Author: michiel
Date: 2010-06-15 11:24:27 +0200 (Tue, 15 Jun 2010)
New Revision: 42563

Added:
   mmbase/trunk/contributions/calendar/src/main/config/functions/
   mmbase/trunk/contributions/calendar/src/main/config/functions/calendar.xml
   
mmbase/trunk/contributions/calendar/src/main/config/functions/functionsets.xml
   
mmbase/trunk/contributions/calendar/src/main/java/org/mmbase/calendar/ItemsController.java
   mmbase/trunk/contributions/calendar/src/test/java/
   mmbase/trunk/contributions/calendar/src/test/java/org/
   mmbase/trunk/contributions/calendar/src/test/java/org/mmbase/
   mmbase/trunk/contributions/calendar/src/test/java/org/mmbase/calendar/
   
mmbase/trunk/contributions/calendar/src/test/java/org/mmbase/calendar/ItemsControllerTest.java
Modified:
   mmbase/trunk/contributions/calendar/pom.xml
   
mmbase/trunk/contributions/calendar/src/main/config/builders/calendar/special_days.xml
Log:
started on a controller to merge and post calendar items

Modified: mmbase/trunk/contributions/calendar/pom.xml
===================================================================
--- mmbase/trunk/contributions/calendar/pom.xml 2010-06-15 09:24:19 UTC (rev 
42562)
+++ mmbase/trunk/contributions/calendar/pom.xml 2010-06-15 09:24:27 UTC (rev 
42563)
@@ -103,6 +103,12 @@
       <version>${project.version}</version>
       <scope>provided</scope>
     </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+
   </dependencies>
 
   <repositories>

Modified: 
mmbase/trunk/contributions/calendar/src/main/config/builders/calendar/special_days.xml
===================================================================
--- 
mmbase/trunk/contributions/calendar/src/main/config/builders/calendar/special_days.xml
      2010-06-15 09:24:19 UTC (rev 42562)
+++ 
mmbase/trunk/contributions/calendar/src/main/config/builders/calendar/special_days.xml
      2010-06-15 09:24:27 UTC (rev 42563)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<builder xmlns="http://www.mmbase.org/xmlns/builder"; 
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
-         extends="calendar_items" maintainer="mmbase.org" 
-         name="special_days" version="0" 
+<builder xmlns="http://www.mmbase.org/xmlns/builder";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         extends="calendar_items" maintainer="mmbase.org"
+         name="special_days" version="0"
          xsi:schemaLocation="http://www.mmbase.org/xmlns/builder 
http://www.mmbase.org/xmlns/builder.xsd";>
   <names>
     <singular xml:lang="en">Special day</singular>
@@ -30,10 +30,10 @@
           <search>-1</search>
         </positions>
       </editor>
-      <datatype xmlns="http://www.mmbase.org/xmlns/datatypes"; >
+      <datatype xmlns="http://www.mmbase.org/xmlns/datatypes";  >
         <commitprocessor>
           <class 
name="org.mmbase.datatypes.processors.CopyFieldCommitProcessorFactory">
-            <param name="field">start</param>            
+            <param name="field">start</param>
           </class>
         </commitprocessor>
       </datatype>

Added: 
mmbase/trunk/contributions/calendar/src/main/config/functions/calendar.xml
===================================================================
--- mmbase/trunk/contributions/calendar/src/main/config/functions/calendar.xml  
                        (rev 0)
+++ mmbase/trunk/contributions/calendar/src/main/config/functions/calendar.xml  
2010-06-15 09:24:27 UTC (rev 42563)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE functionset PUBLIC "//MMBase - functionset //" 
"http://www.mmbase.org/dtd/functionset_1_0.dtd";>
+<functionset>
+
+  <description></description>
+
+  <function name="itemsController">
+    <type>class</type>
+    <class>org.mmbase.security.calendar.ItemsController</class>
+    <method>post</method>
+  </function>
+
+</functionset>

Added: 
mmbase/trunk/contributions/calendar/src/main/config/functions/functionsets.xml
===================================================================
--- 
mmbase/trunk/contributions/calendar/src/main/config/functions/functionsets.xml  
                            (rev 0)
+++ 
mmbase/trunk/contributions/calendar/src/main/config/functions/functionsets.xml  
    2010-06-15 09:24:27 UTC (rev 42563)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE functionsets PUBLIC "-//MMBase//DTD functionsets config 1.0//EN" 
"http://www.mmbase.org/dtd/functionsets_1_0.dtd";>
+<functionsets>
+  <functionset name="calendar"        resource="calendar.xml" />
+</functionsets>

Added: 
mmbase/trunk/contributions/calendar/src/main/java/org/mmbase/calendar/ItemsController.java
===================================================================
--- 
mmbase/trunk/contributions/calendar/src/main/java/org/mmbase/calendar/ItemsController.java
                          (rev 0)
+++ 
mmbase/trunk/contributions/calendar/src/main/java/org/mmbase/calendar/ItemsController.java
  2010-06-15 09:24:27 UTC (rev 42563)
@@ -0,0 +1,208 @@
+/*
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+
+The license (Mozilla version 1.0) can be read at the MMBase site.
+See http://www.MMBase.org/license
+
+*/
+package org.mmbase.calendar;
+
+import java.util.*;
+import org.mmbase.bridge.*;
+import org.mmbase.storage.search.*;
+import org.mmbase.util.functions.Required;
+import org.mmbase.util.logging.Logger;
+import org.mmbase.util.logging.Logging;
+
+/**
+ * The gui function of calendar items and calendar item types.
+ *
+ * @author Michiel Meeuwissen
+ * @version $Id: GuiFunction.java 35892 2009-06-09 20:03:49Z michiel $
+ * @since MMBase-2.0
+ */
+public class ItemsController {
+
+    private static final Logger LOG = 
Logging.getLoggerInstance(ItemsController.class);
+
+    private NodeQuery query;
+    private boolean desiredValue;
+    private Date start;
+    private Date stop;
+    private String title;
+
+
+
+    @Required
+    public void setValue(boolean value) {
+        this.desiredValue = value;
+    }
+
+
+    public void setTitle(String t) {
+        this.title = t;
+    }
+
+
+
+    @Required
+    public void setQuery(NodeQuery query) {
+        this.query = query;
+    }
+
+    public void setStart(Date start) {
+        this.start = start;
+    }
+
+
+    public void setStop(Date stop) {
+        this.stop = stop;
+    }
+
+    protected static FieldValueConstraint getDate(NodeQuery q, Constraint 
constraint, String field) {
+        if (constraint instanceof FieldValueConstraint) {
+            FieldValueConstraint fvc = (FieldValueConstraint) constraint;
+            if (fvc.getField().getStep().equals(q.getNodeStep()) && 
fvc.getField().getFieldName().equals(field)) {
+                return fvc;
+            } else {
+                return null;
+            }
+        } else if (constraint instanceof CompositeConstraint) {
+            CompositeConstraint composite = (CompositeConstraint) constraint;
+            for (Constraint cons : composite.getChilds()) {
+                FieldValueConstraint res = getDate(q, cons, field);
+                if (res != null) {
+                    return res;
+                }
+            }
+            return null;
+        } else {
+            return null;
+        }
+
+    }
+    protected static Date getDate(NodeQuery q, String field) {
+        Constraint constraint = q.getConstraint();
+        if (constraint == null) return null;
+        return (Date) getDate(q, constraint, field).getValue();
+
+
+    }
+
+    protected List<Node> getRelevantPeriods() {
+
+        List<Node> result = new ArrayList<Node>();
+        if (start == null) {
+            start = getDate(query, "start");
+        }
+        if (stop == null) {
+            stop = getDate(query, "stop");
+        }
+        NodeQuery clone = (NodeQuery) query.clone();
+        return result;
+    }
+
+    protected int addAndDelete(List<Node> periods) {
+        Date startDate = getDate(query, "start");
+        Date endDate   = getDate(query, "stop");
+
+        for (int i = 0 ; i < periods.size(); i++) {
+            Node period = periods.get(i);
+            if (desiredValue) {
+                if (period.getDateValue("start").getTime() <= 
startDate.getTime()) {
+                    if (period.getDateValue("stop").getTime() >= 
endDate.getTime()) {
+                        // already covered by a (longer) period
+                        return 0;
+                    } else if (period.getDateValue("stop").getTime() >= 
startDate.getTime()) {
+                        // partially covered by a period that can be extended
+                        period.setDateValue("stop", endDate);
+                        return 1;
+                    } else {
+                        // period does not border or overlap
+                        continue;
+                    }
+                } else {
+                    if (period.getDateValue("start").getTime() <= 
endDate.getTime()) {
+                        if (period.getDateValue("stop").getTime() <= 
endDate.getTime()) {
+                            // period is completely included by desired 
period, extend on both sides.
+                            period.setDateValue("stop", endDate);
+                            period.setDateValue("start", startDate);
+                        } else {
+                            // desired perios is at the beginning of an 
existing item, extend at beginning
+                            period.setDateValue("start", startDate);
+                        }
+                        return 1;
+                    }
+                }
+            } else {
+                if (period.getDateValue("start").getTime() <= 
startDate.getTime()) {
+                    if (period.getDateValue("stop").getTime() > 
startDate.getTime()) {
+                        if (period.getDateValue("stop").getTime() <= 
endDate.getTime()) {
+                            // covered at the end of (longer) period
+                            if (period.getDateValue("start").getTime() == 
startDate.getTime()) {
+                                periods.remove(i);
+                                period.delete(true);
+                                return 1;
+                            } else {
+                                period.setDateValue("stop", startDate);
+                                return 1;
+                            }
+                        } else if (period.getDateValue("start").getTime() == 
startDate.getTime()) {
+                            // convered at the begin of a longer period
+                            period.setDateValue("start", endDate);
+                            return 1;
+                        }
+                    }
+                }
+            }
+
+        }
+
+        if (desiredValue) {
+            // no matching period found, so create one
+            Cloud cloud = query.getCloud();
+            Node newNode = cloud.getNodeManager("calendar_items").createNode();
+            newNode.setStringValue("title", title);
+            newNode.setDateValue("start", startDate);
+            newNode.setDateValue("stop", endDate);
+            newNode.commit();
+            periods.add(newNode);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    protected int merge(List<Node> periods) {
+        int changes = 0;
+        for (int i = 0 ; i < periods.size() - 1; i++) {
+            Node period1 = periods.get(i);
+            Node period2 = periods.get(i + 1);
+            if (period1.getDateValue("stop").getTime() >= 
period2.getDateValue("start").getTime()) {
+                period1.setDateValue("stop", period2.getDateValue("stop"));
+                periods.remove(i + 1);
+                period2.delete(true);
+                changes++;
+                i--; continue;
+            }
+        }
+        return changes;
+    }
+
+    protected int fix(List<Node> periods) {
+        int result = addAndDelete(periods);
+        result += merge(periods);
+        return result;
+    }
+
+    public int post() {
+        int changes = 0;
+        List<Node> periods = getRelevantPeriods();
+        changes += fix(periods);
+        return changes;
+    }
+
+
+}
\ No newline at end of file

Added: 
mmbase/trunk/contributions/calendar/src/test/java/org/mmbase/calendar/ItemsControllerTest.java
===================================================================
--- 
mmbase/trunk/contributions/calendar/src/test/java/org/mmbase/calendar/ItemsControllerTest.java
                              (rev 0)
+++ 
mmbase/trunk/contributions/calendar/src/test/java/org/mmbase/calendar/ItemsControllerTest.java
      2010-06-15 09:24:27 UTC (rev 42563)
@@ -0,0 +1,127 @@
+/*
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+
+The license (Mozilla version 1.0) can be read at the MMBase site.
+See http://www.MMBase.org/license
+
+*/
+
+package org.mmbase.calendar;
+
+import org.mmbase.bridge.mock.*;
+import org.mmbase.bridge.*;
+import org.mmbase.bridge.util.*;
+import org.mmbase.datatypes.*;
+import org.mmbase.util.*;
+import java.util.*;
+import org.junit.*;
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+/**
+ * @version $Id: ContextTagTest.java 39651 2009-11-11 18:17:50Z michiel $
+ */
+
+public  class ItemsControllerTest {
+
+    private static ItemsController controller = new ItemsController();
+    private static NodeManager items;
+    private static List<Node> periods = new ArrayList<Node>();
+
+
+    public CloudContext getCloudContext() {
+        return MockCloudContext.getInstance();
+    }
+    @BeforeClass()
+    public static void setUp() throws Exception {
+        DataTypes.initialize();
+        MockCloudContext.getInstance().clear();
+        MockCloudContext.getInstance().addCore();
+        
MockCloudContext.getInstance().addNodeManagers(MockBuilderReader.getBuilderLoader().getChildResourceLoader("calendar"));
+        Cloud cloud = MockCloudContext.getInstance().getCloud("mmbase");
+        items = cloud.getNodeManager("calendar_items");
+    }
+
+
+    protected NodeQuery getQuery(NodeManager items, String start, String end) {
+        NodeQuery query = items.createQuery();
+        Queries.addConstraint(query,
+                              Queries.createConstraint(query, "start", 
Queries.getOperator("<"), DynamicDate.eval(start)));
+        Queries.addConstraint(query,
+                              Queries.createConstraint(query, "stop", 
Queries.getOperator(">"), DynamicDate.eval(end)));
+        return query;
+    }
+
+
+    @Test
+    public void addToEmpty() throws Exception {
+        assertNotNull(items);
+        controller.setQuery(getQuery(items, "today", "today + 1 day"));
+        controller.setTitle("foo bar");
+        controller.setValue(true);
+
+        assertEquals(1, controller.fix(periods));
+        assertEquals(1, periods.size());
+
+        // another time, not result any changes
+        assertEquals(0, controller.fix(periods));
+        assertEquals(1, periods.size());
+    }
+
+    @Test
+    public void addToPeriod() throws Exception {
+        // Add one day more
+        controller.setQuery(getQuery(items, "today + 1 day", "today + 2 day"));
+        assertEquals(1, controller.fix(periods));
+        assertEquals(1, periods.size());
+        assertEquals(DynamicDate.eval("today"), 
periods.get(0).getDateValue("start"));
+        assertEquals(DynamicDate.eval("today + 2 day"), 
periods.get(0).getDateValue("stop"));
+    }
+
+    @Test
+    public void addWithGap() throws Exception {
+        // Yet another day, but leave a gap
+        controller.setQuery(getQuery(items, "today + 3 day", "today + 4 day"));
+        assertEquals(1, controller.fix(periods));
+        assertEquals(2, periods.size());
+        assertEquals(DynamicDate.eval("today"), 
periods.get(0).getDateValue("start"));
+        assertEquals(DynamicDate.eval("today + 2 day"), 
periods.get(0).getDateValue("stop"));
+        assertEquals(DynamicDate.eval("today + 3 day"), 
periods.get(1).getDateValue("start"));
+        assertEquals(DynamicDate.eval("today + 4 day"), 
periods.get(1).getDateValue("stop"));
+        // second time, nothing should happen
+        assertEquals(0, controller.fix(periods));
+        assertEquals(2, periods.size());
+    }
+
+
+    @Test
+    public void removeAtBeginning() throws Exception {
+        // remove first day again
+        controller.setQuery(getQuery(items, "today", "today + 1 day"));
+        controller.setValue(false);
+        assertEquals(1, controller.fix(periods));
+        assertEquals(2, periods.size());
+        assertEquals(DynamicDate.eval("today + 1 day"), 
periods.get(0).getDateValue("start"));
+        assertEquals(DynamicDate.eval("today + 2 day"), 
periods.get(0).getDateValue("stop"));
+        assertEquals(DynamicDate.eval("today + 3 day"), 
periods.get(1).getDateValue("start"));
+        assertEquals(DynamicDate.eval("today + 4 day"), 
periods.get(1).getDateValue("stop"));
+        assertEquals(0, controller.fix(periods));
+        assertEquals(2, periods.size());
+    }
+
+    @Test
+    public void insertAtGap() throws Exception {
+        controller.setQuery(getQuery(items, "today + 2 day", "today + 3 day"));
+        controller.setValue(true);
+        assertEquals(2, controller.fix(periods));
+        assertEquals(1, periods.size());
+
+        assertEquals(DynamicDate.eval("today + 1 day"), 
periods.get(0).getDateValue("start"));
+        assertEquals(DynamicDate.eval("today + 4 day"), 
periods.get(0).getDateValue("stop"));
+
+        assertEquals(0, controller.fix(periods));
+        assertEquals(1, periods.size());
+    }
+}

_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs

Reply via email to