You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2007/01/24 14:10:49 UTC

svn commit: r499390 - in /cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src: main/java/org/apache/cayenne/map/ test/java/org/apache/cayenne/map/

Author: aadamchik
Date: Wed Jan 24 05:10:47 2007
New Revision: 499390

URL: http://svn.apache.org/viewvc?view=rev&rev=499390
Log:
CAY-735: Embeddable class support in the org.apache.cayenne.map package and the Modeler
(initial embeddable descriptors support)

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/EmbeddableAttribute.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableAttributeTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/DataMap.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/DataMapTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/DataMap.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/DataMap.java?view=diff&rev=499390&r1=499389&r2=499390
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/DataMap.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/DataMap.java Wed Jan 24 05:10:47 2007
@@ -24,12 +24,13 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.cayenne.map.event.AttributeEvent;
 import org.apache.cayenne.map.event.DbAttributeListener;
 import org.apache.cayenne.map.event.DbEntityListener;
@@ -45,6 +46,7 @@
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
+import org.apache.commons.lang.builder.ToStringBuilder;
 
 /**
  * Stores a collection of related mapping objects that describe database and object layers
@@ -113,6 +115,7 @@
     protected boolean clientSupported;
     protected String defaultClientPackage;
 
+    private List embeddables;
     private SortedMap objEntityMap;
     private SortedMap dbEntityMap;
     private SortedMap procedureMap;
@@ -133,6 +136,7 @@
     }
 
     public DataMap(String mapName, Map properties) {
+        embeddables = new ArrayList();
         objEntityMap = new TreeMap();
         dbEntityMap = new TreeMap();
         procedureMap = new TreeMap();
@@ -263,6 +267,31 @@
             encoder.printProperty(DEFAULT_CLIENT_PACKAGE_PROPERTY, defaultClientPackage);
         }
 
+        // embeddables.... must sort explicitly.
+        if (!embeddables.isEmpty()) {
+
+            List sortedEmbeddables;
+
+            if (embeddables.size() > 1) {
+                sortedEmbeddables = new ArrayList(embeddables);
+                Comparator embeddableComparator = new Comparator() {
+
+                    public int compare(Object o1, Object o2) {
+                        Embeddable e1 = (Embeddable) o1;
+                        Embeddable e2 = (Embeddable) o2;
+                        return Util.nullSafeCompare(true, e1.getClassName(), e2
+                                .getClassName());
+                    }
+                };
+                Collections.sort(sortedEmbeddables, embeddableComparator);
+            }
+            else {
+                sortedEmbeddables = embeddables;
+            }
+
+            encoder.print(sortedEmbeddables);
+        }
+
         // procedures
         encoder.print(getProcedureMap());
 
@@ -458,6 +487,15 @@
     }
 
     /**
+     * Removes all stored embeddable objects from the map.
+     * 
+     * @since 3.0
+     */
+    public void clearEmbeddables() {
+        embeddables.clear();
+    }
+
+    /**
      * @since 1.1
      */
     public void clearQueries() {
@@ -502,6 +540,18 @@
     }
 
     /**
+     * Adds an embeddable object to the DataMap.
+     * 
+     * @since 3.0
+     */
+    public void addEmbeddable(Embeddable embeddable) {
+        if (embeddable == null) {
+            throw new NullPointerException("Null embeddable");
+        }
+        embeddables.add(embeddable);
+    }
+
+    /**
      * Adds a new ObjEntity to this DataMap.
      */
     public void addObjEntity(ObjEntity entity) {
@@ -559,6 +609,15 @@
     }
 
     /**
+     * Returns a collection of {@link Embeddable} mappings stored in the DataMap.
+     * 
+     * @since 3.0
+     */
+    public Collection getEmbeddables() {
+        return Collections.unmodifiableCollection(embeddables);
+    }
+
+    /**
      * Returns all DbEntities in this DataMap.
      */
     public Collection getDbEntities() {
@@ -640,6 +699,21 @@
         }
 
         return result;
+    }
+
+    /**
+     * Removes all {@link Embeddable} descriptors with matching class name.
+     * 
+     * @since 3.0
+     */
+    public void removeEmbeddable(String className) {
+        Iterator it = embeddables.iterator();
+        while (it.hasNext()) {
+            Embeddable e = (Embeddable) it.next();
+            if (className.equals(e.getClassName())) {
+                it.remove();
+            }
+        }
     }
 
     /**

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java?view=auto&rev=499390
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java Wed Jan 24 05:10:47 2007
@@ -0,0 +1,130 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.map;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.cayenne.util.XMLEncoder;
+import org.apache.cayenne.util.XMLSerializable;
+
+/**
+ * A mapping descriptor of an embeddable class. Embeddable is a persistent class that
+ * doesn't have its own identity and is embedded in other persistent classes. It can be
+ * viewed as a custom type mapped to one or more database columns. Embeddable mapping can
+ * include optional default column names that can be overriden by the owning entity.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class Embeddable implements XMLSerializable, Serializable {
+
+    protected String className;
+    protected SortedMap attributes;
+
+    public Embeddable() {
+        this(null);
+    }
+
+    public Embeddable(String className) {
+        this.attributes = new TreeMap();
+        this.className = className;
+    }
+
+    /**
+     * Returns an unmodifiable sorted map of embeddable attributes.
+     */
+    public SortedMap getAttributeMap() {
+        // create a new instance ... Caching unmodifiable map causes
+        // serialization issues (esp. with Hessian).
+        return Collections.unmodifiableSortedMap(attributes);
+    }
+
+    /**
+     * Returns an unmodifiable collection of embeddable attributes.
+     */
+    public Collection getAttributes() {
+        // create a new instance. Caching unmodifiable collection causes
+        // serialization issues (esp. with Hessian).
+        return Collections.unmodifiableCollection(attributes.values());
+    }
+
+    /**
+     * Adds new embeddable attribute to the entity, setting its parent embeddable to be
+     * this object. If attribute has no name, IllegalArgumentException is thrown.
+     */
+    public void addAttribute(EmbeddableAttribute attribute) {
+        if (attribute.getName() == null) {
+            throw new IllegalArgumentException("Attempt to insert unnamed attribute.");
+        }
+
+        Object existingAttribute = attributes.get(attribute.getName());
+        if (existingAttribute != null) {
+            if (existingAttribute == attribute) {
+                return;
+            }
+            else {
+                throw new IllegalArgumentException(
+                        "An attempt to override embeddable attribute '"
+                                + attribute.getName()
+                                + "'");
+            }
+        }
+
+        attributes.put(attribute.getName(), attribute);
+        attribute.setEmbeddable(this);
+    }
+    
+    public EmbeddableAttribute getAttribute(String name) {
+        return (EmbeddableAttribute) attributes.get(name);
+    }
+    
+    public void removeAttribute(String name) {
+        attributes.remove(name);
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    /**
+     * {@link XMLSerializable} implementation that generates XML for embeddable.
+     */
+    public void encodeAsXML(XMLEncoder encoder) {
+        encoder.print("<embeddable");
+        if (getClassName() != null) {
+            encoder.print("\" className=\"");
+            encoder.print(getClassName());
+            encoder.print("\"");
+        }
+        encoder.println(">");
+
+        encoder.indent(1);
+        encoder.print(attributes);
+        encoder.indent(-1);
+        encoder.println("</embeddable>");
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/EmbeddableAttribute.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/EmbeddableAttribute.java?view=auto&rev=499390
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/EmbeddableAttribute.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/map/EmbeddableAttribute.java Wed Jan 24 05:10:47 2007
@@ -0,0 +1,99 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.map;
+
+import java.io.Serializable;
+
+import org.apache.cayenne.util.Util;
+import org.apache.cayenne.util.XMLEncoder;
+import org.apache.cayenne.util.XMLSerializable;
+
+/**
+ * A persistent attribute of an embeddable object.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class EmbeddableAttribute implements XMLSerializable, Serializable {
+
+    protected String name;
+    protected String type;
+    protected String dbAttributeName;
+
+    protected Embeddable embeddable;
+
+    public EmbeddableAttribute() {
+
+    }
+
+    public EmbeddableAttribute(String name) {
+        this.name = name;
+    }
+
+    public void encodeAsXML(XMLEncoder encoder) {
+        encoder.print("<embeddable-attribute name=\"" + getName() + '\"');
+
+        if (getType() != null) {
+            encoder.print(" type=\"");
+            encoder.print(getType());
+            encoder.print('\"');
+        }
+
+        // If this obj attribute is mapped to db attribute
+        if (dbAttributeName != null) {
+            encoder.print(" db-attribute-name=\"");
+            encoder.print(Util.encodeXmlAttribute(dbAttributeName));
+            encoder.print('\"');
+        }
+
+        encoder.println("/>");
+    }
+
+    public String getDbAttributeName() {
+        return dbAttributeName;
+    }
+
+    public void setDbAttributeName(String dbAttributeName) {
+        this.dbAttributeName = dbAttributeName;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Embeddable getEmbeddable() {
+        return embeddable;
+    }
+
+    public void setEmbeddable(Embeddable embeddable) {
+        this.embeddable = embeddable;
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/DataMapTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/DataMapTest.java?view=diff&rev=499390&r1=499389&r2=499390
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/DataMapTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/DataMapTest.java Wed Jan 24 05:10:47 2007
@@ -50,7 +50,9 @@
 
     public void testSerializabilityWithHessian() throws Exception {
         DataMap m1 = new DataMap("abc");
-        DataMap d1 = (DataMap) HessianUtil.cloneViaClientServerSerialization(m1, new EntityResolver());
+        DataMap d1 = (DataMap) HessianUtil.cloneViaClientServerSerialization(
+                m1,
+                new EntityResolver());
         assertEquals(m1.getName(), d1.getName());
 
         ObjEntity oe1 = new ObjEntity("oe1");
@@ -239,6 +241,29 @@
 
         map.removeObjEntity(e.getName(), false);
         map.addObjEntity(e);
+    }
+
+    public void testAddEmbeddable() {
+        Embeddable e = new Embeddable("XYZ");
+
+        DataMap map = new DataMap();
+        assertEquals(0, map.getEmbeddables().size());
+        map.addEmbeddable(e);
+        assertEquals(1, map.getEmbeddables().size());
+        assertTrue(map.getEmbeddables().contains(e));
+    }
+
+    public void testRemoveEmbeddable() {
+        Embeddable e = new Embeddable("XYZ");
+
+        DataMap map = new DataMap();
+        map.addEmbeddable(e);
+        assertTrue(map.getEmbeddables().contains(e));
+
+        map.removeEmbeddable("123");
+        assertTrue(map.getEmbeddables().contains(e));
+        map.removeEmbeddable("XYZ");
+        assertFalse(map.getEmbeddables().contains(e));
     }
 
     public void testAddDbEntity() {

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableAttributeTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableAttributeTest.java?view=auto&rev=499390
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableAttributeTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableAttributeTest.java Wed Jan 24 05:10:47 2007
@@ -0,0 +1,34 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.map;
+
+import junit.framework.TestCase;
+
+public class EmbeddableAttributeTest extends TestCase {
+
+    public void testName() {
+        EmbeddableAttribute a1 = new EmbeddableAttribute();
+        assertNull(a1.getName());
+        a1.setName("XYZ");
+        assertEquals("XYZ", a1.getName());
+        
+        EmbeddableAttribute a2 = new EmbeddableAttribute("ABC");
+        assertEquals("ABC", a2.getName());
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableTest.java?view=auto&rev=499390
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/map/EmbeddableTest.java Wed Jan 24 05:10:47 2007
@@ -0,0 +1,70 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.map;
+
+import junit.framework.TestCase;
+
+public class EmbeddableTest extends TestCase {
+
+    public void testClassName() {
+        Embeddable e1 = new Embeddable();
+        assertNull(e1.getClassName());
+
+        e1.setClassName("XYZ");
+        assertEquals("XYZ", e1.getClassName());
+
+        Embeddable e2 = new Embeddable("ABC");
+        assertEquals("ABC", e2.getClassName());
+    }
+
+    public void testAddAttribute() {
+        Embeddable e1 = new Embeddable();
+
+        EmbeddableAttribute a1 = new EmbeddableAttribute("a1");
+        EmbeddableAttribute a2 = new EmbeddableAttribute("a2");
+
+        assertEquals(0, e1.getAttributeMap().size());
+        e1.addAttribute(a1);
+        assertEquals(1, e1.getAttributeMap().size());
+        assertSame(e1, a1.getEmbeddable());
+        e1.addAttribute(a2);
+        assertEquals(2, e1.getAttributeMap().size());
+        assertSame(e1, a2.getEmbeddable());
+
+        assertTrue(e1.getAttributes().contains(a1));
+        assertTrue(e1.getAttributes().contains(a2));
+    }
+
+    public void testRemoveAttribute() {
+        Embeddable e1 = new Embeddable();
+
+        EmbeddableAttribute a1 = new EmbeddableAttribute("a1");
+        EmbeddableAttribute a2 = new EmbeddableAttribute("a2");
+
+        e1.addAttribute(a1);
+        e1.addAttribute(a2);
+
+        e1.removeAttribute("a1");
+        e1.removeAttribute("a2");
+        assertEquals(0, e1.getAttributeMap().size());
+
+        assertFalse(e1.getAttributes().contains(a1));
+        assertFalse(e1.getAttributes().contains(a2));
+    }
+}