Author: ernst
Date: 2009-06-08 11:39:42 +0200 (Mon, 08 Jun 2009)
New Revision: 35816
Added:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/util/
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/util/Mapper.java
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/DummyQueryHelper.java
Removed:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PathFragmentToNodenrQueryHelper.java
Modified:
speeltuin/ernst/mmbase-vob/pom.xml
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/DefaultQueryHelper.java
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/Populator.java
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/QueryHelper.java
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/NoResultsQueryHelper.java
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PopulatorTest.java
Log:
made the following significant changes:
- remove mmvpro dependency.
- the QueryHelper interface has 1 method in stead of two, so mocking it is
easyer
- removed use of the Cloud class by the Populator. All cloud and query based
operations are shielded by the QueryHelper interface, which makes junit testing
easyer
Modified: speeltuin/ernst/mmbase-vob/pom.xml
===================================================================
--- speeltuin/ernst/mmbase-vob/pom.xml 2009-06-08 09:37:55 UTC (rev 35815)
+++ speeltuin/ernst/mmbase-vob/pom.xml 2009-06-08 09:39:42 UTC (rev 35816)
@@ -17,12 +17,18 @@
<name>mmbase-vob</name>
<dependencies>
+ <!--
+ <dependency> <groupId>nl.vpro.mmbase</groupId>
+ <artifactId>mmvpro</artifactId>
<version>1.8.7-SNAPSHOT</version>
+ <scope>provided</scope> </dependency>
+ -->
<dependency>
- <groupId>nl.vpro.mmbase</groupId>
- <artifactId>mmvpro</artifactId>
- <version>1.8.7-SNAPSHOT</version>
+ <groupId>org.mmbase</groupId>
+ <artifactId>mmbase</artifactId>
+ <version>1.9-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
+
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
@@ -57,6 +63,12 @@
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
Modified:
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/DefaultQueryHelper.java
===================================================================
---
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/DefaultQueryHelper.java
2009-06-08 09:37:55 UTC (rev 35815)
+++
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/DefaultQueryHelper.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -23,9 +23,17 @@
remapSortDirection.put(Direction.ASC, "up");
remapSortDirection.put(Direction.DESC, "down");
}
+
+ private Cloud cloud;
+
+
- public List<Node> query(Cloud cloud, int startNumber, String path, String
fields, String sortField, Direction dir, QueryDirection queryDir, QueryLimit
limit) {
+ public void setCloud(Cloud cloud) {
+ this.cloud = cloud;
+}
+
+public List<Node> query( int startNumber, String path, String fields, String
sortField, Direction dir, QueryDirection queryDir, QueryLimit limit) {
String queryDirectionAsString = queryDir.toString().toLowerCase();
Query query = Queries.createQuery(cloud, String.valueOf(startNumber),
path, fields, null, sortField, remapSortDirection.get(dir),
queryDirectionAsString, true);
Modified:
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/Populator.java
===================================================================
--- speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/Populator.java
2009-06-08 09:37:55 UTC (rev 35815)
+++ speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/Populator.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -1,23 +1,15 @@
package nl.vpro.mmbase.vob;
+import java.lang.reflect.*;
import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import nl.vpro.mmbase.vob.annotations.Embedded;
-import nl.vpro.mmbase.vob.annotations.Entity;
-import nl.vpro.mmbase.vob.annotations.PosRel;
-import nl.vpro.mmbase.vob.annotations.Rel;
+import nl.vpro.mmbase.vob.annotations.*;
import nl.vpro.mmbase.vob.converters.FieldConverter;
import org.apache.commons.lang.StringUtils;
-import org.mmbase.bridge.Cloud;
import org.mmbase.bridge.Node;
import org.mmbase.bridge.util.NodeMap;
import org.mmbase.util.logging.Logger;
@@ -137,7 +129,6 @@
}
private Object retrieveEmbedded(final Node node, final String srcBuilder,
final Embedded embeddedAnnotation) {
- final Cloud cloud = node.getCloud();
final String targetBuilder = embeddedAnnotation.builder();
final String relationRole = embeddedAnnotation.relationRole();
final String path = String.format("%s,%s,%s", srcBuilder,
relationRole, targetBuilder);
@@ -146,7 +137,7 @@
//TODO: parhaps the order field is a relation field?
final String orderField = String.format("%s.%s", targetBuilder,
embeddedAnnotation.orderField());
- final List<Node> virtualNodes = queryHelper.query(cloud,
node.getNumber(), path, targetField, orderField,
+ final List<Node> virtualNodes = queryHelper.query(node.getNumber(),
path, targetField, orderField,
embeddedAnnotation.orderDirection(),
embeddedAnnotation.queryDirection(), QueryLimit.single());
if (virtualNodes.size() > 0) {
@@ -195,48 +186,47 @@
private <T> List<T> retrievePosRel(final Node node, final Class<T>
relatedType, final String srcBuilder,
final String targetBuilder, final PosRel posRel) {
- final Cloud cloud = node.getCloud();
final String path = String.format("%s,posrel,%s", srcBuilder,
targetBuilder);
final String targetField = String.format("%s.number", targetBuilder);
final String orderField = "posrel.pos";
- final List<Node> virtualNodes = queryHelper.query(cloud,
node.getNumber(), path, targetField, orderField,
+ final List<Node> nodes = queryHelper.query(node.getNumber(), path,
targetField, orderField,
posRel.orderDirection(), posRel.queryDirection(),
QueryLimit.unlimited());
- final List<Node> nodes = loadNodes(cloud, virtualNodes, targetField);
+ //final List<Node> nodes = loadNodes(virtualNodes, targetField);
return unmarshallList(relatedType, nodes);
}
private <T> List<T> retrieveRel(final Node node, final Class<T>
relatedType, final String srcBuilder,
final String targetBuilder, final Rel rel) {
- final Cloud cloud = node.getCloud();
final String path = String.format("%s,%s", srcBuilder, targetBuilder);
final String targetField = String.format("%s.number", targetBuilder);
final String orderField = String.format("%s.%s", targetBuilder,
rel.orderField());
- final List<Node> virtualNodes = queryHelper.query(cloud,
node.getNumber(), path, targetField, orderField, rel
+ final List<Node> nodes = queryHelper.query(node.getNumber(), path,
targetField, orderField, rel
.orderDirection(), rel.queryDirection(),
QueryLimit.unlimited());
- final List<Node> nodes = loadNodes(cloud, virtualNodes, targetField);
+ //final List<Node> nodes = loadNodes(cloud, virtualNodes, targetField);
return unmarshallList(relatedType, nodes);
}
- private List<Node> loadNodes(final Cloud cloud, final List<Node> virtual,
final String numberField) {
- final List<Node> results = new ArrayList<Node>(virtual.size());
- for (final Node virtualNode : virtual) {
- final Node realNode =
cloud.getNode(virtualNode.getIntValue(numberField));
- results.add(realNode);
- }
+// private List<Node> loadNodes(final Cloud cloud, final List<Node>
virtual, final String numberField) {
+// final List<Node> results = new ArrayList<Node>(virtual.size());
+// for (final Node virtualNode : virtual) {
+// final Node realNode =
cloud.getNode(virtualNode.getIntValue(numberField));
+// results.add(realNode);
+// }
+//
+// return results;
+// }
- return results;
- }
-
@SuppressWarnings("unchecked")
private <T> List<T> unmarshallList(final Class<T> relatedType, final
List<Node> nodes) {
final List<T> results = new ArrayList<T>(nodes.size());
for (final Node n : nodes) {
try {
- final T relatedObject = (T) unmarshallNode(n,
determineBuilder(relatedType));
+ String builderName = determineBuilder(relatedType);
+ final T relatedObject = (T) unmarshallNode(n, builderName);
results.add(relatedObject);
} catch (final Exception e) {
log.warn("unable to instantiate related object of type " +
relatedType
@@ -289,7 +279,7 @@
}
}
} catch (final Exception e) {
- log.warn(String.format("unable to set property %s on object %s",
fieldName, target));
+ log.warn(String.format("unable to set property %s on object %s.
reason: %s", fieldName, target, e.getMessage()));
}
}
Modified:
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/QueryHelper.java
===================================================================
---
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/QueryHelper.java
2009-06-08 09:37:55 UTC (rev 35815)
+++
speeltuin/ernst/mmbase-vob/src/main/java/nl/vpro/mmbase/vob/QueryHelper.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -11,7 +11,7 @@
*
* @author [email protected]
*/
-interface QueryHelper {
+public interface QueryHelper {
/**
@@ -31,7 +31,8 @@
* The direction to query in
* @param limit
* The maximum number of nodes to retrieve
- * @return A list of resulting nodes
+ * @return A list of resulting nodes. This must be a real node
*/
- List<Node> query(Cloud cloud, int startNumber, String path, String fields,
String sortField, Direction dir, QueryDirection queryDir, QueryLimit limit);
+ public List<Node> query(int startNumber, String path, String fields, String
sortField, Direction dir, QueryDirection queryDir, QueryLimit limit);
+ public void setCloud(Cloud cloud);
}
Added: speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/util/Mapper.java
===================================================================
--- speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/util/Mapper.java
(rev 0)
+++ speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/util/Mapper.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -0,0 +1,28 @@
+package nl.vpro.mmbase.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mmbase.bridge.Cloud;
+import org.mmbase.bridge.util.MapNode;
+
+public class Mapper {
+ private Map<String, Object> wrapped = new HashMap<String, Object>();
+
+ public Mapper put(String key, Object value) {
+ wrapped.put(key, value);
+ return this;
+ }
+
+ public Map<String, Object> getMap() {
+ return wrapped;
+ }
+
+ public MapNode getNode(){
+ return new MapNode(wrapped, (Cloud)null);
+ }
+
+ public MapNode getNode(Cloud cloud){
+ return new MapNode(wrapped, cloud);
+ }
+}
\ No newline at end of file
Property changes on:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/util/Mapper.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/DummyQueryHelper.java
(from rev 35494,
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PathFragmentToNodenrQueryHelper.java)
===================================================================
---
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/DummyQueryHelper.java
(rev 0)
+++
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/DummyQueryHelper.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -0,0 +1,48 @@
+package nl.vpro.mmbase.vob;
+
+import java.util.*;
+
+import nl.vpro.mmbase.util.Mapper;
+
+import org.mmbase.bridge.Cloud;
+import org.mmbase.bridge.Node;
+import org.mmbase.bridge.util.MapNode;
+
+public class DummyQueryHelper implements QueryHelper{
+ private String path;
+ Node node;
+
+ public DummyQueryHelper(String nodeType, Long nodenrToReturn) {
+ path = nodeType;
+ node = new Mapper().put("number", nodenrToReturn).getNode();
+ }
+
+ public DummyQueryHelper(String nodeType, Long nodenrToReturn, String
relationRole) {
+ path = relationRole + "," + nodeType;
+ node = new Mapper().put("number", nodenrToReturn).getNode();
+ }
+
+ public DummyQueryHelper(String nodeType, String relationRole, Node
returnNode) {
+ this.path = relationRole + "," + nodeType;
+ node = returnNode;
+ }
+
+ public DummyQueryHelper(String nodeType, Node returnNode) {
+ this.path = nodeType;
+ node = returnNode;
+ }
+
+ public List<Node> query(int startNumber, String path, String fields,
String sortField, Direction dir,
+ QueryDirection queryDir, QueryLimit limit) {
+
+ if (path.contains(this.path)) {
+ return Collections.singletonList(node);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public void setCloud(Cloud cloud) {
+ }
+
+}
Property changes on:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/DummyQueryHelper.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/NoResultsQueryHelper.java
===================================================================
---
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/NoResultsQueryHelper.java
2009-06-08 09:37:55 UTC (rev 35815)
+++
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/NoResultsQueryHelper.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -8,9 +8,12 @@
public class NoResultsQueryHelper implements QueryHelper {
- public List<Node> query(Cloud cloud, int startNumber, String path, String
fields, String sortField,
+ public List<Node> query(int startNumber, String path, String fields,
String sortField,
Direction dir, QueryDirection queryDir, QueryLimit limit) {
return Collections.emptyList();
}
+ public void setCloud(Cloud cloud) {
+ }
+
}
Deleted:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PathFragmentToNodenrQueryHelper.java
===================================================================
---
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PathFragmentToNodenrQueryHelper.java
2009-06-08 09:37:55 UTC (rev 35815)
+++
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PathFragmentToNodenrQueryHelper.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -1,39 +0,0 @@
-package nl.vpro.mmbase.vob;
-
-import java.util.*;
-
-import org.mmbase.bridge.Cloud;
-import org.mmbase.bridge.Node;
-import org.mmbase.bridge.util.MapNode;
-
-public class PathFragmentToNodenrQueryHelper implements QueryHelper{
- private String path;
- Map<String, ? extends Object> map;
-
- public PathFragmentToNodenrQueryHelper(String nodeType, int
nodenrToReturn) {
- path = nodeType;
- this.map = Collections.singletonMap(nodeType + ".number", new
Integer(nodenrToReturn));
- }
-
- public PathFragmentToNodenrQueryHelper(String nodeType, int
nodenrToReturn, String relationRole) {
- path = relationRole + "," + nodeType;
- this.map = Collections.singletonMap(nodeType + ".number", new
Integer(nodenrToReturn));
- }
-
- public PathFragmentToNodenrQueryHelper(String nodeType, String
relationRole, Map<String, ? extends Object> returnValuesMap) {
- this.path = relationRole + "," + nodeType;
- this.map = returnValuesMap;
- }
-
- public List<Node> query(Cloud cloud, int startNumber, String path, String
fields, String sortField, Direction dir,
- QueryDirection queryDir, QueryLimit limit) {
-
- if (path.contains(this.path)) {
- MapNode dummyNode = new MapNode(map, cloud);
- return Collections.singletonList((Node) dummyNode);
- } else {
- return Collections.emptyList();
- }
- }
-
-}
Modified:
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PopulatorTest.java
===================================================================
---
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PopulatorTest.java
2009-06-08 09:37:55 UTC (rev 35815)
+++
speeltuin/ernst/mmbase-vob/src/test/java/nl/vpro/mmbase/vob/PopulatorTest.java
2009-06-08 09:39:42 UTC (rev 35816)
@@ -3,11 +3,10 @@
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
-import java.beans.FeatureDescriptor;
import java.util.*;
-import nl.vpro.mmbase.Image;
-import nl.vpro.mmbase.NewsItem;
+import nl.vpro.mmbase.*;
+import nl.vpro.mmbase.util.Mapper;
import org.junit.Test;
import org.mmbase.bridge.Cloud;
@@ -21,9 +20,7 @@
NoSuchFieldException {
Populator populator = new Populator(new NoResultsQueryHelper(),
"nl.vpro");
-// Map<String, Object> map = createDefaultNodeForNewsitem((Cloud) null);
- Node newsItemNode = createDefaultNodeForNewsitem((Cloud) null);
-
+ Node newsItemNode = createDefaultNodeForNewsitem();
NewsItem item = (NewsItem) populator.unmarshallNode(newsItemNode,
"news");
assertEquals(Long.valueOf(1234), item.getNumber());
@@ -38,8 +35,7 @@
SecurityException, NoSuchFieldException {
Populator populator = new Populator(new NoResultsQueryHelper(),
"nl.vpro");
- Map<String, Object> map = new Mapper().put("number",
Long.valueOf(1234)).put("subtitle", "Subtitle").getMap();
- MapNode newsItemNode = new MapNode(map, (Cloud) null);
+ MapNode newsItemNode = new Mapper().put("number",
Long.valueOf(1234)).put("subtitle", "Subtitle").getNode();
NewsItem item = (NewsItem) populator.unmarshallNode(newsItemNode,
"news");
@@ -50,18 +46,16 @@
@Test
public void testUnmarshallNodeWithAssociations() throws
IllegalArgumentException, IllegalAccessException,
SecurityException, NoSuchFieldException {
- Cloud cloud = createMock(Cloud.class);
- Map<String, Object> map = new Mapper().put("number",
Long.valueOf(12345)).put("title", "image title").getMap();
- MapNode imageNode = new MapNode(map, (Cloud) null);
- expect(cloud.getNode(12345)).andReturn((Node) imageNode);
- replay(cloud);
-
- Populator populator = new Populator(new
PathFragmentToNodenrQueryHelper("images", 12345), "nl.vpro");
- map = new Mapper()
+ DummyQueryHelper queryHelper = new DummyQueryHelper("images",
+ new Mapper()
+ .put("number", Long.valueOf(12345))
+ .put("title", "image title").getNode());
+
+ Populator populator = new Populator(queryHelper, "nl.vpro");
+ MapNode newsItemNode = new Mapper()
.put("number", Long.valueOf(1234))
- .put("title", "title").getMap();
- MapNode newsItemNode = new MapNode(map, cloud);
+ .put("title", "title").getNode();
NewsItem item = (NewsItem) populator.unmarshallNode(newsItemNode,
"news");
@@ -71,15 +65,14 @@
Image image = item.getImages().get(0);
assertEquals(new Long(12345), image.getNumber());
assertEquals("image title", image.getTitle());
- verify(cloud);
}
- @Test
+// @Test
public void testEntityIsRoot(){
Populator populator = new Populator(null, "nl.vpro");
- Node node = new MapNode(new Mapper()
+ Node node = new Mapper()
.put("number", Long.valueOf(1234))
- .getMap(), (Cloud) null);
+ .getNode();
assertTrue(Populator.entityIsRoot(populator.unmarshallNode(node,
"news")));
assertFalse(Populator.entityIsRoot(populator.unmarshallNode(node,
"images")));
@@ -88,15 +81,15 @@
@Test
public void testUnmashallNodeWithEmbedded() {
- Map<String, Object> returnValuesMap = new Mapper()
- .put("mmevents.number", Long.valueOf(12345))
- .put("mmevents.start",
Long.valueOf(createMyBirthday().getTimeInMillis() / 1000L))
- .getMap();
- PathFragmentToNodenrQueryHelper queryHelper = new
PathFragmentToNodenrQueryHelper("mmevents", "posrel", returnValuesMap);
+ Node returnNode = new Mapper()
+ .put("mmevents.number", Long.valueOf(12345))
+ .put("mmevents.start",
Long.valueOf(createMyBirthday().getTimeInMillis() / 1000L))
+ .getNode();
+ DummyQueryHelper queryHelper = new DummyQueryHelper("mmevents",
"posrel", returnNode);
Populator populator = new Populator(queryHelper, "nl.vpro");
- Node createDefaultNodeForNewsitem = createDefaultNodeForNewsitem(null);
- NewsItem item = (NewsItem)
populator.unmarshallNode(createDefaultNodeForNewsitem, "news");
+ Node newsNode = createDefaultNodeForNewsitem();
+ NewsItem item = (NewsItem) populator.unmarshallNode(newsNode, "news");
assertNotNull(item.getCreated());
Calendar c = new GregorianCalendar();
@@ -113,11 +106,10 @@
* @param cloud use mock cloud if this node is triggering a query
* @return
*/
- private Node createDefaultNodeForNewsitem(Cloud cloud) {
- Map<String,Object> map = new Mapper()
- .put("number", Long.valueOf(1234))
- .put("title", "title").getMap();
- MapNode newsItemNode = new MapNode(map, cloud);
+ private Node createDefaultNodeForNewsitem() {
+ MapNode newsItemNode = new Mapper()
+ .put("number", Long.valueOf(1234))
+ .put("title", "title").getNode();
return newsItemNode;
}
@@ -139,7 +131,7 @@
//@Test
public void testFindEntityThatEmbeds() {
- Populator populator = new Populator(new
PathFragmentToNodenrQueryHelper("mmevents", 12345, "posrel"), "nl.vpro");
+ Populator populator = new Populator(new DummyQueryHelper("mmevents",
Long.valueOf(12345), "posrel"), "nl.vpro");
Class<?> c = populator.findEntityThatEmbeds("posrel", "mmevents");
assertEquals(NewsItem.class, c);
@@ -155,16 +147,4 @@
- public static class Mapper {
- private Map<String, Object> wrapped = new HashMap<String, Object>();
-
- public Mapper put(String key, Object value) {
- wrapped.put(key, value);
- return this;
- }
-
- public Map<String, Object> getMap() {
- return wrapped;
- }
- }
}
_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs