cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r479075 - in /incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src: main/java/org/apache/cayenne/map/ main/java/org/apache/cayenne/map/compiled/ main/java/org/apache/cayenne/property/ test/java/org/apache/cayenne/map/ test/java/org/apache/c...
Date Sat, 25 Nov 2006 02:44:20 GMT
Author: aadamchik
Date: Fri Nov 24 18:44:18 2006
New Revision: 479075

URL: http://svn.apache.org/viewvc?view=rev&rev=479075
Log:
CAY-701: property" package refactoring
(new ClassDescriptor factory API that supports factory chains for multiple types of persistent objects)

Added:
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ClassDescriptorMap.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptorFactory.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoCollectionProperty.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoDescriptorFactory.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoSingleObjectArcProperty.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptorFactory.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ProxyClassDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/compiled/
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/compiled/PersistentDescriptorTst.java
Removed:
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/ClientPersistentDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/DataObjectDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EnhancedPojoCollectionProperty.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EnhancedPojoDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EnhancedPojoSingleObjectArcProperty.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityDescriptorFactory.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/property/BaseClassDescriptor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/EntityDescriptorTst.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/property/BaseClassDescriptorTst.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/property/MockBaseClassDescriptor.java
Modified:
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/ClientEntityResolver.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityResolver.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/EntityResolverClassDescriptorTst.java

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/ClientEntityResolver.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/ClientEntityResolver.java?view=diff&rev=479075&r1=479074&r2=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/ClientEntityResolver.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/ClientEntityResolver.java Fri Nov 24 18:44:18 2006
@@ -18,7 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.map;
 
-import org.apache.cayenne.property.ClassDescriptor;
 import org.apache.cayenne.property.ClassDescriptorFactory;
 
 /**
@@ -35,19 +34,5 @@
 
     public EntityResolver getClientEntityResolver() {
         return this;
-    }
-
-    public ClassDescriptorFactory getClassDescriptorFactory() {
-        if (classDescriptorFactory == null) {
-            this.classDescriptorFactory = new EntityDescriptorFactory(this) {
-
-                protected EntityDescriptor createDescriptor(
-                        ObjEntity entity,
-                        ClassDescriptor superclassDescriptor) {
-                    return new ClientPersistentDescriptor(entity, superclassDescriptor);
-                }
-            };
-        }
-        return classDescriptorFactory;
     }
 }

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityResolver.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityResolver.java?view=diff&rev=479075&r1=479074&r2=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityResolver.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/EntityResolver.java Fri Nov 24 18:44:18 2006
@@ -31,8 +31,11 @@
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
+import org.apache.cayenne.map.compiled.ClassDescriptorMap;
+import org.apache.cayenne.map.compiled.DataObjectDescriptorFactory;
+import org.apache.cayenne.map.compiled.EnhancedPojoDescriptorFactory;
+import org.apache.cayenne.map.compiled.PersistentDescriptorFactory;
 import org.apache.cayenne.property.ClassDescriptor;
-import org.apache.cayenne.property.ClassDescriptorFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.commons.collections.collection.CompositeCollection;
 
@@ -63,7 +66,7 @@
 
     // must be transient, as resolver may get deserialized in another VM, and descriptor
     // recompilation will be desired.
-    protected transient ClassDescriptorFactory classDescriptorFactory;
+    protected transient ClassDescriptorMap classDescriptorMap;
 
     // callbacks are not serializable
     protected transient LifecycleEventCallbackMap[] lifecycleEventCallbacks;
@@ -251,7 +254,7 @@
             throw new IllegalArgumentException("Null entityName");
         }
 
-        return getClassDescriptorFactory().getDescriptor(entityName);
+        return getClassDescriptorMap().getDescriptor(entityName);
     }
 
     public synchronized void addDataMap(DataMap map) {
@@ -643,25 +646,26 @@
     }
 
     /**
-     * Returns a factory for ClassDescriptors used by Cayenne stack. This method is
-     * guaranteed to return non null value. If the factory hasn't been set explicitly, it
-     * initializes default {@link EntityDescriptorFactory}.
+     * Returns an object that compiles and stores {@link ClassDescriptor} instances for
+     * all entities.
      * 
-     * @since 1.2
+     * @since 3.0
      */
-    public ClassDescriptorFactory getClassDescriptorFactory() {
-        if (classDescriptorFactory == null) {
-            this.classDescriptorFactory = new EntityDescriptorFactory(this);
+    public ClassDescriptorMap getClassDescriptorMap() {
+        if (classDescriptorMap == null) {
+            ClassDescriptorMap classDescriptorMap = new ClassDescriptorMap(this);
+
+            // add factories in reverse of the desired chain order
+            classDescriptorMap.addFactory(new PersistentDescriptorFactory(
+                    classDescriptorMap));
+            classDescriptorMap.addFactory(new EnhancedPojoDescriptorFactory(
+                    classDescriptorMap));
+            classDescriptorMap.addFactory(new DataObjectDescriptorFactory(
+                    classDescriptorMap));
+
+            this.classDescriptorMap = classDescriptorMap;
         }
-        return classDescriptorFactory;
-    }
 
-    /**
-     * Sets a factory for ClassDescriptors used by Cayenne stack.
-     * 
-     * @since 1.2
-     */
-    public void setClassDescriptorFactory(ClassDescriptorFactory descriptorFactory) {
-        this.classDescriptorFactory = descriptorFactory;
+        return classDescriptorMap;
     }
 }

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ClassDescriptorMap.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ClassDescriptorMap.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ClassDescriptorMap.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ClassDescriptorMap.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,134 @@
+/*****************************************************************
+ *   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.compiled;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.ClassDescriptorFactory;
+
+/**
+ * An object that holds class descriptors for mapped entities, compiling new descriptors
+ * on demand using an internal chain of descriptor factories.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class ClassDescriptorMap {
+
+    protected EntityResolver resolver;
+    protected Map descriptors;
+    protected List factories;
+
+    public ClassDescriptorMap(EntityResolver resolver) {
+        this.descriptors = new HashMap();
+        this.resolver = resolver;
+        this.factories = new ArrayList();
+    }
+
+    public EntityResolver getResolver() {
+        return resolver;
+    }
+
+    /**
+     * Adds a factory to the descriptor factory chain.
+     */
+    public void addFactory(ClassDescriptorFactory factory) {
+        factories.add(factory);
+    }
+
+    public void removeFactory(ClassDescriptorFactory factory) {
+        factories.remove(factory);
+    }
+
+    public void clearFactories() {
+        factories.clear();
+    }
+
+    public void clearDescriptors() {
+        descriptors.clear();
+    }
+
+    /**
+     * Removes cached descriptor if any for the given entity.
+     */
+    public void removeDescriptor(String entityName) {
+        descriptors.remove(entityName);
+    }
+
+    /**
+     * Caches descriptor definition.
+     */
+    public void addDescriptor(String entityName, ClassDescriptor descriptor) {
+        if (descriptor == null) {
+            removeDescriptor(entityName);
+        }
+        else {
+            descriptors.put(entityName, descriptor);
+        }
+    }
+
+    public ClassDescriptor getDescriptor(String entityName) {
+        ClassDescriptor cached = (ClassDescriptor) descriptors.get(entityName);
+        if (cached != null) {
+            return cached;
+        }
+
+        return createProxyDescriptor(entityName);
+    }
+
+    /**
+     * Creates a descriptor wrapper that will compile the underlying descriptor on demand.
+     * Using proxy indirection is needed to compile relationships of descriptors to other
+     * descriptors that are not compiled yet.
+     */
+    protected ClassDescriptor createProxyDescriptor(String entityName) {
+        ClassDescriptor descriptor = new ProxyClassDescriptor(this, entityName);
+        addDescriptor(entityName, descriptor);
+        return descriptor;
+    }
+
+    /**
+     * Creates a new descriptor.
+     */
+    protected ClassDescriptor createDescriptor(String entityName) {
+
+        // scan the factory chain until some factory returns a non-null descriptor;
+        // scanning is done in reverse order so that the factories added last take higher
+        // precedence...
+        ListIterator it = factories.listIterator(factories.size());
+        while (it.hasPrevious()) {
+            ClassDescriptorFactory factory = (ClassDescriptorFactory) it.previous();
+            ClassDescriptor descriptor = factory.getDescriptor(entityName);
+
+            if (descriptor != null) {
+                return descriptor;
+            }
+        }
+
+        throw new CayenneRuntimeException("Failed to create descriptor for entity: "
+                + entityName);
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptor.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptor.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptor.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,44 @@
+/*****************************************************************
+ *   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.compiled;
+
+import org.apache.cayenne.DataObject;
+import org.apache.cayenne.property.PropertyAccessException;
+
+/**
+ * A ClassDescriptor for "generic" persistent classes implementing {@link DataObject}
+ * interface.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+// non-public as the only difference with the superclass is version handling on merge -
+// this is something we need to solved in a more generic fashion (e.g. as via enhancer)
+// for other object types.
+class DataObjectDescriptor extends PersistentDescriptor {
+
+    public void shallowMerge(Object from, Object to) throws PropertyAccessException {
+        super.shallowMerge(from, to);
+
+        if (from instanceof DataObject && to instanceof DataObject) {
+            ((DataObject) to)
+                    .setSnapshotVersion(((DataObject) from).getSnapshotVersion());
+        }
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptorFactory.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptorFactory.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptorFactory.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/DataObjectDescriptorFactory.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,101 @@
+/*****************************************************************
+ *   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.compiled;
+
+import java.util.List;
+
+import org.apache.cayenne.DataObject;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.property.Accessor;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.ClassDescriptorFactory;
+import org.apache.cayenne.property.DataObjectAccessor;
+import org.apache.cayenne.property.PersistentObjectProperty;
+import org.apache.cayenne.property.PropertyAccessException;
+import org.apache.cayenne.property.ToManyListProperty;
+
+/**
+ * A {@link ClassDescriptorFactory} that creates descriptors for classes implementing
+ * {@link DataObject}.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class DataObjectDescriptorFactory extends PersistentDescriptorFactory {
+
+    public DataObjectDescriptorFactory(ClassDescriptorMap descriptorMap) {
+        super(descriptorMap);
+    }
+
+    protected ClassDescriptor getDescriptor(ObjEntity entity, Class entityClass) {
+        if (!DataObject.class.isAssignableFrom(entityClass)) {
+            return null;
+        }
+
+        return super.getDescriptor(entity, entityClass);
+    }
+
+    protected PersistentDescriptor createDescriptor() {
+        return new DataObjectDescriptor();
+    }
+
+    protected void createToManyProperty(
+            PersistentDescriptor descriptor,
+            ObjRelationship relationship) {
+
+        ClassDescriptor targetDescriptor = descriptorMap.getDescriptor(relationship
+                .getTargetEntityName());
+        String reverseName = relationship.getReverseRelationshipName();
+        Accessor accessor = createAccessor(descriptor, relationship.getName(), List.class);
+
+        descriptor.addDeclaredProperty(new ToManyListProperty(
+                descriptor,
+                targetDescriptor,
+                accessor,
+                reverseName));
+    }
+
+    protected void createToOneProperty(
+            PersistentDescriptor descriptor,
+            ObjRelationship relationship) {
+
+        ClassDescriptor targetDescriptor = descriptorMap.getDescriptor(relationship
+                .getTargetEntityName());
+        String reverseName = relationship.getReverseRelationshipName();
+        ObjEntity targetEntity = (ObjEntity) relationship.getTargetEntity();
+        Accessor accessor = createAccessor(
+                descriptor,
+                relationship.getName(),
+                targetEntity.getJavaClass());
+        descriptor.addDeclaredProperty(new PersistentObjectProperty(
+                descriptor,
+                targetDescriptor,
+                accessor,
+                reverseName));
+
+    }
+
+    protected Accessor createAccessor(
+            PersistentDescriptor descriptor,
+            String propertyName,
+            Class propertyType) throws PropertyAccessException {
+        return new DataObjectAccessor(propertyName);
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoCollectionProperty.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoCollectionProperty.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoCollectionProperty.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoCollectionProperty.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,44 @@
+/*****************************************************************
+ *   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.compiled;
+
+import org.apache.cayenne.property.Accessor;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.ListProperty;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class EnhancedPojoCollectionProperty extends ListProperty {
+
+    private Accessor faultResolvedFlagAccessor;
+
+    public EnhancedPojoCollectionProperty(ClassDescriptor owner,
+            ClassDescriptor targetDescriptor, Accessor accessor, String reverseName,
+            Accessor faultResolvedFlagAccessor) {
+        super(owner, targetDescriptor, accessor, reverseName);
+        this.faultResolvedFlagAccessor = faultResolvedFlagAccessor;
+    }
+
+    public void invalidate(Object object) {
+        faultResolvedFlagAccessor.setValue(object, Boolean.FALSE);
+    }
+
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoDescriptorFactory.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoDescriptorFactory.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoDescriptorFactory.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoDescriptorFactory.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,106 @@
+/*****************************************************************
+ *   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.compiled;
+
+import java.util.List;
+
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.property.Accessor;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.ClassDescriptorFactory;
+import org.apache.cayenne.property.FieldAccessor;
+
+/**
+ * A {@link ClassDescriptorFactory} used to create descriptors for the enhanced POJO's.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class EnhancedPojoDescriptorFactory extends PersistentDescriptorFactory {
+
+    static final String FAULT_FIELD_PREFIX = "$cay_faultResolved_";
+    static final String PERSISTENCE_STATE_FIELD = "$cay_persistenceState";
+
+    public EnhancedPojoDescriptorFactory(ClassDescriptorMap descriptorMap) {
+        super(descriptorMap);
+    }
+
+    protected ClassDescriptor getDescriptor(ObjEntity entity, Class entityClass) {
+        // check whether we are dealing with enhaced pojo
+        try {
+            Integer.TYPE.equals(entityClass
+                    .getDeclaredField(PERSISTENCE_STATE_FIELD)
+                    .getType());
+        }
+        catch (Throwable th) {
+            return null;
+        }
+
+        return super.getDescriptor(entity, entityClass);
+    }
+
+    protected void createToManyProperty(
+            PersistentDescriptor descriptor,
+            ObjRelationship relationship) {
+
+        ClassDescriptor targetDescriptor = descriptorMap.getDescriptor(relationship
+                .getTargetEntityName());
+        String reverseName = relationship.getReverseRelationshipName();
+
+        Accessor faultFlagAccessor = createFaultFlagAccessor(descriptor, relationship
+                .getName());
+
+        Accessor accessor = createAccessor(descriptor, relationship.getName(), List.class);
+        descriptor.addDeclaredProperty(new EnhancedPojoCollectionProperty(
+                descriptor,
+                targetDescriptor,
+                accessor,
+                reverseName,
+                faultFlagAccessor));
+    }
+
+    protected void createToOneProperty(
+            PersistentDescriptor descriptor,
+            ObjRelationship relationship) {
+
+        ClassDescriptor targetDescriptor = descriptorMap.getDescriptor(relationship
+                .getTargetEntityName());
+        String reverseName = relationship.getReverseRelationshipName();
+
+        Accessor faultFlagAccessor = createFaultFlagAccessor(descriptor, relationship
+                .getName());
+
+        Accessor accessor = createAccessor(
+                descriptor,
+                relationship.getName(),
+                targetDescriptor.getObjectClass());
+        descriptor.addDeclaredProperty(new EnhancedPojoSingleObjectArcProperty(
+                descriptor,
+                targetDescriptor,
+                accessor,
+                reverseName,
+                faultFlagAccessor));
+    }
+
+    Accessor createFaultFlagAccessor(PersistentDescriptor descriptor, String propertyName) {
+        return new FieldAccessor(descriptor.getObjectClass(), FAULT_FIELD_PREFIX
+                + propertyName, Boolean.TYPE);
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoSingleObjectArcProperty.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoSingleObjectArcProperty.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoSingleObjectArcProperty.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/EnhancedPojoSingleObjectArcProperty.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,69 @@
+/*****************************************************************
+ *   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.compiled;
+
+import org.apache.cayenne.Fault;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.property.AbstractSingleObjectArcProperty;
+import org.apache.cayenne.property.Accessor;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.PropertyAccessException;
+
+/**
+ * A property descriptor for the to-one relationship property of an enhanced pojo. Assumes
+ * a class in question has a field called "$cay_faultResolved_propertyName" that stores a
+ * boolean flag indicating whether the property in question is not yet resolved.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class EnhancedPojoSingleObjectArcProperty extends AbstractSingleObjectArcProperty {
+
+    protected Accessor faultResolvedFlagAccessor;
+
+    EnhancedPojoSingleObjectArcProperty(ClassDescriptor owner,
+            ClassDescriptor targetDescriptor, Accessor accessor, String reverseName,
+            Accessor faultResolvedFlagAccessor) {
+        super(owner, targetDescriptor, accessor, reverseName);
+        this.faultResolvedFlagAccessor = faultResolvedFlagAccessor;
+    }
+
+    public boolean isFault(Object source) {
+        return !((Boolean) faultResolvedFlagAccessor.getValue(source)).booleanValue();
+    }
+
+    public void invalidate(Object object) {
+        faultResolvedFlagAccessor.setValue(object, Boolean.FALSE);
+    }
+
+    protected void resolveFault(Object object) {
+        if (isFault(object)) {
+            Object target = Fault.getToOneFault().resolveFault(
+                    (Persistent) object,
+                    getName());
+            writePropertyDirectly(object, null, target);
+            faultResolvedFlagAccessor.setValue(object, Boolean.TRUE);
+        }
+    }
+
+    public Object readProperty(Object object) throws PropertyAccessException {
+        resolveFault(object);
+        return super.readProperty(object);
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptor.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptor.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptor.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,273 @@
+/*****************************************************************
+ *   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.compiled;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.property.Accessor;
+import org.apache.cayenne.property.AttributeProperty;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.CollectionProperty;
+import org.apache.cayenne.property.Property;
+import org.apache.cayenne.property.PropertyAccessException;
+import org.apache.cayenne.property.PropertyVisitor;
+import org.apache.cayenne.property.SingleObjectArcProperty;
+import org.apache.commons.collections.IteratorUtils;
+
+/**
+ * A default ClassDescriptor implementation for persistent objects.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class PersistentDescriptor implements ClassDescriptor {
+
+    static final Integer TRANSIENT_STATE = new Integer(PersistenceState.TRANSIENT);
+    static final Integer HOLLOW_STATE = new Integer(PersistenceState.HOLLOW);
+    static final Integer COMMITTED_STATE = new Integer(PersistenceState.COMMITTED);
+
+    protected ClassDescriptor superclassDescriptor;
+
+    // compiled properties ...
+    protected Class objectClass;
+    protected Map declaredProperties;
+    protected Map subclassDescriptors;
+    protected Accessor persistenceStateAccessor;
+
+    protected ObjEntity entity;
+
+    /**
+     * Creates a PersistentDescriptor.
+     */
+    public PersistentDescriptor() {
+        this.declaredProperties = new HashMap();
+        this.subclassDescriptors = new HashMap();
+    }
+
+    /**
+     * Registers a property. This method is useful to customize default ClassDescriptor
+     * generated from ObjEntity by adding new properties or overriding the standard ones.
+     */
+    public void addDeclaredProperty(Property property) {
+        declaredProperties.put(property.getName(), property);
+    }
+
+    /**
+     * Removes declared property. This method can be used to customize default
+     * ClassDescriptor generated from ObjEntity.
+     */
+    public void removeDeclaredProperty(String propertyName) {
+        declaredProperties.remove(propertyName);
+    }
+
+    public void addSubclassDescriptor(ClassDescriptor subclassDescriptor) {
+        subclassDescriptors.put(
+                subclassDescriptor.getEntity().getClassName(),
+                subclassDescriptor);
+    }
+
+    public ObjEntity getEntity() {
+        return entity;
+    }
+
+    public boolean isFault(Object object) {
+        if (superclassDescriptor != null) {
+            return superclassDescriptor.isFault(object);
+        }
+
+        if (object == null) {
+            return false;
+        }
+
+        return HOLLOW_STATE.equals(persistenceStateAccessor.getValue(object));
+    }
+
+    public Class getObjectClass() {
+        return objectClass;
+    }
+
+    void setObjectClass(Class objectClass) {
+        this.objectClass = objectClass;
+    }
+
+    public ClassDescriptor getSubclassDescriptor(Class objectClass) {
+        if (objectClass == null) {
+            throw new IllegalArgumentException("Null objectClass");
+        }
+
+        if (subclassDescriptors.isEmpty()) {
+            return this;
+        }
+
+        ClassDescriptor subclassDescriptor = (ClassDescriptor) subclassDescriptors
+                .get(objectClass.getName());
+
+        // ascend via the class hierarchy (only doing it if there are multiple choices)
+        if (subclassDescriptor == null) {
+            Class currentClass = objectClass;
+            while (subclassDescriptor == null
+                    && (currentClass = currentClass.getSuperclass()) != null) {
+                subclassDescriptor = (ClassDescriptor) subclassDescriptors
+                        .get(currentClass.getName());
+            }
+        }
+
+        return subclassDescriptor != null ? subclassDescriptor : this;
+    }
+
+    public Iterator getProperties() {
+        Iterator declaredIt = IteratorUtils.unmodifiableIterator(declaredProperties
+                .values()
+                .iterator());
+
+        if (getSuperclassDescriptor() == null) {
+            return declaredIt;
+        }
+        else {
+            return IteratorUtils.chainedIterator(
+                    superclassDescriptor.getProperties(),
+                    declaredIt);
+        }
+    }
+
+    /**
+     * Recursively looks up property descriptor in this class descriptor and all
+     * superclass descriptors.
+     */
+    public Property getProperty(String propertyName) {
+        Property property = getDeclaredProperty(propertyName);
+
+        if (property == null && superclassDescriptor != null) {
+            property = superclassDescriptor.getProperty(propertyName);
+        }
+
+        return property;
+    }
+
+    public Property getDeclaredProperty(String propertyName) {
+        return (Property) declaredProperties.get(propertyName);
+    }
+
+    /**
+     * Returns a descriptor of the mapped superclass or null if the descriptor's entity
+     * sits at the top of inheritance hierarchy.
+     */
+    public ClassDescriptor getSuperclassDescriptor() {
+        return superclassDescriptor;
+    }
+
+    /**
+     * Creates a new instance of a class described by this object.
+     */
+    public Object createObject() {
+        if (objectClass == null) {
+            throw new NullPointerException(
+                    "Null objectClass. Descriptor wasn't initialized properly.");
+        }
+
+        try {
+            return objectClass.newInstance();
+        }
+        catch (Throwable e) {
+            throw new CayenneRuntimeException("Error creating object of class '"
+                    + objectClass.getName()
+                    + "'", e);
+        }
+    }
+
+    /**
+     * Invokes 'prepareForAccess' of a super descriptor and then invokes
+     * 'prepareForAccess' of each declared property.
+     */
+    public void injectValueHolders(Object object) throws PropertyAccessException {
+
+        // do super first
+        if (getSuperclassDescriptor() != null) {
+            getSuperclassDescriptor().injectValueHolders(object);
+        }
+
+        Iterator it = declaredProperties.values().iterator();
+        while (it.hasNext()) {
+            Property property = (Property) it.next();
+            property.injectValueHolder(object);
+        }
+    }
+
+    /**
+     * Copies object properties from one object to another. Invokes 'shallowCopy' of a
+     * super descriptor and then invokes 'shallowCopy' of each declared property.
+     */
+    public void shallowMerge(final Object from, final Object to)
+            throws PropertyAccessException {
+
+        visitProperties(new PropertyVisitor() {
+
+            public boolean visitAttributeProperty(AttributeProperty property) {
+                property.writePropertyDirectly(
+                        to,
+                        property.readPropertyDirectly(to),
+                        property.readPropertyDirectly(from));
+                return true;
+            }
+
+            public boolean visitSingleObjectArc(SingleObjectArcProperty property) {
+                property.invalidate(to);
+                return true;
+            }
+
+            public boolean visitCollectionArc(CollectionProperty property) {
+                return true;
+            }
+        });
+    }
+
+    public boolean visitProperties(PropertyVisitor visitor) {
+        if (superclassDescriptor != null
+                && !superclassDescriptor.visitProperties(visitor)) {
+            return false;
+        }
+
+        Iterator it = declaredProperties.values().iterator();
+        while (it.hasNext()) {
+            Property next = (Property) it.next();
+            if (!next.visit(visitor)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public void setPersistenceStateAccessor(Accessor persistenceStateAccessor) {
+        this.persistenceStateAccessor = persistenceStateAccessor;
+    }
+
+    public void setEntity(ObjEntity entity) {
+        this.entity = entity;
+    }
+
+    public void setSuperclassDescriptor(ClassDescriptor superclassDescriptor) {
+        this.superclassDescriptor = superclassDescriptor;
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptorFactory.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptorFactory.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptorFactory.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/PersistentDescriptorFactory.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,188 @@
+/*****************************************************************
+ *   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.compiled;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.map.EntityInheritanceTree;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.property.Accessor;
+import org.apache.cayenne.property.BeanAccessor;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.ClassDescriptorFactory;
+import org.apache.cayenne.property.FieldAccessor;
+import org.apache.cayenne.property.ListProperty;
+import org.apache.cayenne.property.Property;
+import org.apache.cayenne.property.PropertyAccessException;
+import org.apache.cayenne.property.SimpleAttributeProperty;
+import org.apache.cayenne.property.ValueHolderProperty;
+
+/**
+ * A ClassDescriptorFactory that handles creation of ClassDescriptors for Persistent
+ * objects.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+// corresponds to the client variety of objects with ValueHolders...
+public class PersistentDescriptorFactory implements ClassDescriptorFactory {
+
+    protected ClassDescriptorMap descriptorMap;
+
+    public PersistentDescriptorFactory(ClassDescriptorMap descriptorMap) {
+        this.descriptorMap = descriptorMap;
+    }
+
+    public ClassDescriptor getDescriptor(String entityName) {
+        ObjEntity entity = descriptorMap.getResolver().lookupObjEntity(entityName);
+        if (entity == null) {
+            throw new CayenneRuntimeException("Unmapped entity: " + entityName);
+        }
+
+        Class entityClass = entity.getJavaClass();
+        return getDescriptor(entity, entityClass);
+    }
+
+    protected ClassDescriptor getDescriptor(ObjEntity entity, Class entityClass) {
+        String superEntityName = entity.getSuperEntityName();
+
+        ClassDescriptor superDescriptor = (superEntityName != null) ? descriptorMap
+                .getDescriptor(superEntityName) : null;
+
+        PersistentDescriptor descriptor = createDescriptor();
+
+        descriptor.setEntity(entity);
+        descriptor.setSuperclassDescriptor(superDescriptor);
+        descriptor.setObjectClass(entityClass);
+        descriptor.setPersistenceStateAccessor(new BeanAccessor(
+                entityClass,
+                "persistenceState",
+                Integer.TYPE));
+
+        // only include this entity attributes and skip superclasses...
+        Iterator attributes = descriptor.getEntity().getDeclaredAttributes().iterator();
+        while (attributes.hasNext()) {
+            createAttributeProperty(descriptor, (ObjAttribute) attributes.next());
+        }
+
+        // only include this entity relationships and skip superclasses...
+        Iterator it = descriptor.getEntity().getDeclaredRelationships().iterator();
+        while (it.hasNext()) {
+
+            ObjRelationship relationship = (ObjRelationship) it.next();
+            if (relationship.isToMany()) {
+                createToManyProperty(descriptor, relationship);
+            }
+            else {
+                createToOneProperty(descriptor, relationship);
+            }
+        }
+
+        EntityInheritanceTree inheritanceTree = descriptorMap
+                .getResolver()
+                .lookupInheritanceTree(descriptor.getEntity());
+        indexSubclassDescriptors(descriptor, inheritanceTree);
+
+        return descriptor;
+    }
+
+    protected PersistentDescriptor createDescriptor() {
+        return new PersistentDescriptor();
+    }
+
+    protected void createAttributeProperty(
+            PersistentDescriptor descriptor,
+            ObjAttribute attribute) {
+        Class propertyType = attribute.getJavaClass();
+        Accessor accessor = createAccessor(descriptor, attribute.getName(), propertyType);
+        descriptor.addDeclaredProperty(new SimpleAttributeProperty(
+                descriptor,
+                accessor,
+                attribute));
+    }
+
+    protected void createToOneProperty(
+            PersistentDescriptor descriptor,
+            ObjRelationship relationship) {
+        ClassDescriptor targetDescriptor = descriptorMap.getDescriptor(relationship
+                .getTargetEntityName());
+        String reverseName = relationship.getReverseRelationshipName();
+
+        Accessor accessor = createAccessor(
+                descriptor,
+                relationship.getName(),
+                ValueHolder.class);
+        Property property = new ValueHolderProperty(
+                descriptor,
+                targetDescriptor,
+                accessor,
+                reverseName);
+
+        descriptor.addDeclaredProperty(property);
+    }
+
+    protected void createToManyProperty(
+            PersistentDescriptor descriptor,
+            ObjRelationship relationship) {
+
+        ClassDescriptor targetDescriptor = descriptorMap.getDescriptor(relationship
+                .getTargetEntityName());
+        String reverseName = relationship.getReverseRelationshipName();
+
+        Accessor accessor = createAccessor(descriptor, relationship.getName(), List.class);
+        descriptor.addDeclaredProperty(new ListProperty(
+                descriptor,
+                targetDescriptor,
+                accessor,
+                reverseName));
+    }
+
+    protected void indexSubclassDescriptors(
+            PersistentDescriptor descriptor,
+            EntityInheritanceTree inheritanceTree) {
+
+        if (inheritanceTree != null) {
+
+            Iterator it = inheritanceTree.getChildren().iterator();
+            while (it.hasNext()) {
+                EntityInheritanceTree child = (EntityInheritanceTree) it.next();
+                descriptor.addSubclassDescriptor(descriptorMap.getDescriptor(child
+                        .getEntity()
+                        .getName()));
+
+                indexSubclassDescriptors(descriptor, child);
+            }
+        }
+    }
+
+    /**
+     * Creates an accessor for the property.
+     */
+    protected Accessor createAccessor(
+            PersistentDescriptor descriptor,
+            String propertyName,
+            Class propertyType) throws PropertyAccessException {
+        return new FieldAccessor(descriptor.getObjectClass(), propertyName, propertyType);
+    }
+}

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ProxyClassDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ProxyClassDescriptor.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ProxyClassDescriptor.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/map/compiled/ProxyClassDescriptor.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,120 @@
+/*****************************************************************
+ *   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.compiled;
+
+import java.util.Iterator;
+
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.property.ClassDescriptor;
+import org.apache.cayenne.property.Property;
+import org.apache.cayenne.property.PropertyAccessException;
+import org.apache.cayenne.property.PropertyVisitor;
+
+/**
+ * A ClassDescriptor wrapper that compiles itself lazily on first access.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class ProxyClassDescriptor implements ClassDescriptor {
+
+    protected ClassDescriptor descriptor;
+    protected ClassDescriptorMap descriptorMap;
+    protected String entityName;
+
+    public ProxyClassDescriptor(ClassDescriptorMap descriptorMap, String entityName) {
+        this.descriptorMap = descriptorMap;
+        this.entityName = entityName;
+    }
+
+    protected void checkCompiled() {
+        if (descriptor == null) {
+            descriptor = descriptorMap.createDescriptor(entityName);
+        }
+    }
+
+    /**
+     * Returns underlying descriptor used to delegate all processing, resolving it if
+     * needed.
+     */
+    public ClassDescriptor getDescriptor() {
+        checkCompiled();
+        return descriptor;
+    }
+
+    public Object createObject() {
+        checkCompiled();
+        return descriptor.createObject();
+    }
+
+    public Property getDeclaredProperty(String propertyName) {
+        checkCompiled();
+        return descriptor.getDeclaredProperty(propertyName);
+    }
+
+    public ObjEntity getEntity() {
+        checkCompiled();
+        return descriptor.getEntity();
+    }
+
+    public Class getObjectClass() {
+        checkCompiled();
+        return descriptor.getObjectClass();
+    }
+
+    public Iterator getProperties() {
+        checkCompiled();
+        return descriptor.getProperties();
+    }
+
+    public Property getProperty(String propertyName) {
+        checkCompiled();
+        return descriptor.getProperty(propertyName);
+    }
+
+    public ClassDescriptor getSubclassDescriptor(Class objectClass) {
+        checkCompiled();
+        return descriptor.getSubclassDescriptor(objectClass);
+    }
+
+    public ClassDescriptor getSuperclassDescriptor() {
+        checkCompiled();
+        return descriptor.getSuperclassDescriptor();
+    }
+
+    public void injectValueHolders(Object object) throws PropertyAccessException {
+        checkCompiled();
+        descriptor.injectValueHolders(object);
+    }
+
+    public boolean isFault(Object object) {
+        checkCompiled();
+        return descriptor.isFault(object);
+    }
+
+    public void shallowMerge(Object from, Object to) throws PropertyAccessException {
+        checkCompiled();
+        descriptor.shallowMerge(from, to);
+    }
+
+    public boolean visitProperties(PropertyVisitor visitor) {
+        checkCompiled();
+        return descriptor.visitProperties(visitor);
+    }
+}

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/EntityResolverClassDescriptorTst.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/EntityResolverClassDescriptorTst.java?view=diff&rev=479075&r1=479074&r2=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/EntityResolverClassDescriptorTst.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/EntityResolverClassDescriptorTst.java Fri Nov 24 18:44:18 2006
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.map;
 
+import org.apache.cayenne.map.compiled.ProxyClassDescriptor;
 import org.apache.cayenne.property.ArcProperty;
 import org.apache.cayenne.property.ClassDescriptor;
 import org.apache.cayenne.property.MockClassDescriptor;
@@ -43,12 +44,12 @@
 
     public void testServerDescriptorCaching() {
         EntityResolver resolver = getDomain().getEntityResolver();
-        resolver.setClassDescriptorFactory(null);
+        resolver.getClassDescriptorMap().clearDescriptors();
 
         ClassDescriptor descriptor = resolver.getClassDescriptor("MtTable1");
         assertNotNull(descriptor);
         assertSame(descriptor, resolver.getClassDescriptor("MtTable1"));
-        resolver.setClassDescriptorFactory(null);
+        resolver.getClassDescriptorMap().clearDescriptors();
 
         ClassDescriptor descriptor1 = resolver.getClassDescriptor("MtTable1");
         assertNotNull(descriptor1);
@@ -57,24 +58,26 @@
 
     public void testServerDescriptorFactory() {
         EntityResolver resolver = getDomain().getEntityResolver();
-        resolver.setClassDescriptorFactory(null);
+        resolver.getClassDescriptorMap().clearDescriptors();
 
         MockClassDescriptor mockDescriptor = new MockClassDescriptor();
-        resolver
-                .setClassDescriptorFactory(new MockClassDescriptorFactory(mockDescriptor));
+        MockClassDescriptorFactory factory = new MockClassDescriptorFactory(
+                mockDescriptor);
+        resolver.getClassDescriptorMap().addFactory(factory);
         try {
             ClassDescriptor descriptor = resolver.getClassDescriptor("MtTable1");
             assertNotNull(descriptor);
+            descriptor = ((ProxyClassDescriptor) descriptor).getDescriptor();
             assertSame(mockDescriptor, descriptor);
         }
         finally {
-            resolver.setClassDescriptorFactory(null);
+            resolver.getClassDescriptorMap().removeFactory(factory);
         }
     }
 
     public void testArcProperties() {
         EntityResolver resolver = getDomain().getEntityResolver();
-        resolver.setClassDescriptorFactory(null);
+        resolver.getClassDescriptorMap().clearDescriptors();
 
         ClassDescriptor descriptor = resolver.getClassDescriptor("MtTable1");
         assertNotNull(descriptor);

Added: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/compiled/PersistentDescriptorTst.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/compiled/PersistentDescriptorTst.java?view=auto&rev=479075
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/compiled/PersistentDescriptorTst.java (added)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/map/compiled/PersistentDescriptorTst.java Fri Nov 24 18:44:18 2006
@@ -0,0 +1,57 @@
+/*****************************************************************
+ *   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.compiled;
+
+import junit.framework.TestCase;
+
+import org.apache.cayenne.property.FieldAccessor;
+import org.apache.cayenne.property.Property;
+import org.apache.cayenne.property.SimpleAttributeProperty;
+import org.apache.cayenne.unit.util.TestBean;
+
+public class PersistentDescriptorTst extends TestCase {
+
+    public void testConstructor() {
+        PersistentDescriptor d1 = new PersistentDescriptor();
+        assertNull(d1.getSuperclassDescriptor());
+
+        PersistentDescriptor d2 = new PersistentDescriptor();
+        d2.setSuperclassDescriptor(d1);
+        assertNull(d1.getSuperclassDescriptor());
+        assertSame(d1, d2.getSuperclassDescriptor());
+    }
+
+    public void testCopyObjectProperties() {
+        PersistentDescriptor d1 = new PersistentDescriptor();
+
+        FieldAccessor accessor = new FieldAccessor(TestBean.class, "string", String.class);
+        Property property = new SimpleAttributeProperty(d1, accessor, null);
+
+        d1.declaredProperties.put(property.getName(), property);
+
+        TestBean from = new TestBean();
+        from.setString("123");
+
+        TestBean to = new TestBean();
+
+        d1.shallowMerge(from, to);
+        assertEquals("123", to.getString());
+    }
+}



Mime
View raw message