db-jdo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m..@apache.org
Subject svn commit: r158176 [38/79] - in incubator/jdo/trunk/ri11: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ src/java/org/apache/jdo/ejb/ src/java/org/apache/jdo/enhancer/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/enhancer/ src/java/org/apache/jdo/impl/enhancer/classfile/ src/java/org/apache/jdo/impl/enhancer/core/ src/java/org/apache/jdo/impl/enhancer/generator/ src/java/org/apache/jdo/impl/enhancer/meta/ src/java/org/apache/jdo/impl/enhancer/meta/model/ src/java/org/apache/jdo/impl/enhancer/meta/prop/ src/java/org/apache/jdo/impl/enhancer/meta/util/ src/java/org/apache/jdo/impl/enhancer/util/ src/java/org/apache/jdo/impl/fostore/ src/java/org/apache/jdo/impl/jdoql/ src/java/org/apache/jdo/impl/jdoql/jdoqlc/ src/java/org/apache/jdo/impl/jdoql/scope/ src/java/org/apache/jdo/impl/jdoql/tree/ src/java/org/apache/jdo/impl/model/ src/java/org/apache/jdo/impl/model/java/ src/java/org/apache/jdo/impl/model/java/runtime/ src/java/org/apache/jdo/impl/model/jdo/ src/java/org/apache/jdo/impl/model/jdo/caching/ src/java/org/apache/jdo/impl/model/jdo/util/ src/java/org/apache/jdo/impl/model/jdo/xml/ src/java/org/apache/jdo/impl/pm/ src/java/org/apache/jdo/impl/sco/ src/java/org/apache/jdo/impl/state/ src/java/org/apache/jdo/jdoql/ src/java/org/apache/jdo/jdoql/tree/ src/java/org/apache/jdo/model/ src/java/org/apache/jdo/model/java/ src/java/org/apache/jdo/model/jdo/ src/java/org/apache/jdo/pm/ src/java/org/apache/jdo/sco/ src/java/org/apache/jdo/state/ src/java/org/apache/jdo/store/ src/java/org/apache/jdo/util/ test/ test/conf/ test/enhancer/ test/enhancer/sempdept/ test/enhancer/sempdept/src/ test/enhancer/sempdept/src/empdept/ test/fsuid2/ test/fsuid2/org/ test/fsuid2/org/apache/ test/fsuid2/org/apache/jdo/ test/fsuid2/org/apache/jdo/pc/ test/java/ test/java/org/ test/java/org/apache/ test/java/org/apache/jdo/ test/java/org/apache/jdo/impl/ test/java/org/apache/jdo/impl/fostore/ test/java/org/apache/jdo/pc/ test/java/org/apache/jdo/pc/appid/ test/java/org/apache/jdo/pc/empdept/ test/java/org/apache/jdo/pc/serializable/ test/java/org/apache/jdo/pc/xempdept/ test/java/org/apache/jdo/test/ test/java/org/apache/jdo/test/query/ test/java/org/apache/jdo/test/util/ test/jdo/ test/jdo/org/ test/jdo/org/apache/ test/jdo/org/apache/jdo/ test/jdo/org/apache/jdo/pc/ test/jdo/org/apache/jdo/pc/appid/ test/jdo/org/apache/jdo/pc/empdept/ test/jdo/org/apache/jdo/pc/serializable/ test/jdo/org/apache/jdo/pc/xempdept/ xdocs/
Date Sat, 19 Mar 2005 01:06:07 GMT
Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOFieldImplDynamic.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOFieldImplDynamic.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOFieldImplDynamic.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOFieldImplDynamic.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.jdo.impl.model.jdo.util.TypeSupport;
+import org.apache.jdo.model.ModelException;
+import org.apache.jdo.model.java.JavaField;
+import org.apache.jdo.model.java.JavaType;
+import org.apache.jdo.model.jdo.JDOArray;
+import org.apache.jdo.model.jdo.JDOCollection;
+import org.apache.jdo.model.jdo.JDOField;
+import org.apache.jdo.model.jdo.JDOMap;
+import org.apache.jdo.model.jdo.JDOReference;
+import org.apache.jdo.model.jdo.JDORelationship;
+import org.apache.jdo.model.jdo.NullValueTreatment;
+import org.apache.jdo.model.jdo.PersistenceModifier;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+ * An instance of this class represents the JDO metadata of a managed field 
+ * of a persistence capable class. This dynamic implementation only
+ * stores property values explicitly set by setter method. 
+ * <p>
+ * Please note, you cannot rely on the Java identity of the
+ * JDORelationship instance returned by {@link #getRelationship}.  
+ * The getter will always return a new Java Instance, unless the
+ * relationship is explicitly set by the setter 
+ * {@link #setRelationship(JDORelationship relationship)}.
+ * <p>
+ * TBD:
+ * <ul>
+ * <li> Change usage of POSSIBLY_PERSISTENT persistence-modifier as soon as 
+ * the enhancer fully supports it.
+ * <li> Property change support
+ * </ul> 
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class JDOFieldImplDynamic
+    extends JDOMemberImpl 
+    implements JDOField
+{
+    /** 
+     * Property persistenceModifier. 
+     * Default see {@link #getPersistenceModifier}. 
+     */
+    protected int persistenceModifier = PersistenceModifier.UNSPECIFIED;
+    
+    /** Property primaryKey. Defaults to <code>false</code>. */
+    private boolean primaryKey = false;
+    
+    /** Property nullValueTreatment. Defaults to none. */
+    private int nullValueTreatment = NullValueTreatment.NONE;
+
+    /** Property defaultFetchGroup. Default see {@link #isDefaultFetchGroup}. */
+    protected Boolean defaultFetchGroup;
+
+    /** Property embedded. Default see {@link #isEmbedded}. */
+    protected Boolean embedded;
+
+    /** Property javaField. No default. */
+    private transient JavaField javaField;
+
+    /** Property serializable. Defaults to <code>false</code>. */
+    private boolean serializable = false;
+
+    /** Relationship JDOField<->JDORelationship. */
+    protected JDORelationship relationship;
+    
+    /** I18N support */
+    protected final static I18NHelper msg =  
+        I18NHelper.getInstance(JDOFieldImplDynamic.class);
+
+    /**
+     * Get the persistence modifier of this JDOField.
+     * @return the persistence modifier, one of 
+     * {@link PersistenceModifier#NONE}, 
+     * {@link PersistenceModifier#PERSISTENT},
+     * {@link PersistenceModifier#TRANSACTIONAL}, or
+     * {@link PersistenceModifier#POSSIBLY_PERSISTENT}.
+     */
+    public int getPersistenceModifier() {
+        if (persistenceModifier != PersistenceModifier.UNSPECIFIED) {
+            // return persistenceModifier, if explicitly set by the setter
+            return persistenceModifier;
+        }
+        
+        // not set => calculate
+        int result = PersistenceModifier.UNSPECIFIED;
+        JavaType type = getType();
+        if (nameHasJDOPrefix()) {
+            result = PersistenceModifier.NONE;
+        }
+        else if (type != null) {
+            result = TypeSupport.isPersistenceFieldType(type) ?
+                PersistenceModifier.POSSIBLY_PERSISTENT : 
+                PersistenceModifier.NONE;
+        }
+
+        return result;
+    }
+
+    /** 
+     * Set the persistence modifier for this JDOField.
+     * @param persistenceModifier an integer indicating the persistence 
+     * modifier, one of: {@link PersistenceModifier#UNSPECIFIED}, 
+     * {@link PersistenceModifier#NONE}, 
+     * {@link PersistenceModifier#PERSISTENT},
+     * {@link PersistenceModifier#TRANSACTIONAL}, or
+     * {@link PersistenceModifier#POSSIBLY_PERSISTENT}.
+     */
+    public void setPersistenceModifier (int persistenceModifier)
+        throws ModelException {
+        if (nameHasJDOPrefix() && 
+            (persistenceModifier == PersistenceModifier.PERSISTENT ||
+             persistenceModifier == PersistenceModifier.TRANSACTIONAL)) {
+            throw new ModelException(
+                msg.msg("EXC_IllegalJDOPrefix", getName())); //NOI18N
+        }
+        this.persistenceModifier = persistenceModifier;
+    }
+    
+    /** 
+     * Determines whether this JDOField is a key field or not.  
+     * @return <code>true</code> if the field is a key field, 
+     * <code>false</code> otherwise
+     */
+    public boolean isPrimaryKey() {
+        return primaryKey;
+    }
+
+    /** 
+     * Set whether this JDOField is a key field or not.
+     * @param primaryKey if <code>true</code>, the JDOField is marked 
+     * as a key field; otherwise, it is not
+     */
+    public void setPrimaryKey(boolean primaryKey) {
+        this.primaryKey = primaryKey;
+    }
+
+    /**
+     * Gets the null value treatment indicator of this JDOField.
+     * @return the null value treatment of this JDOField, one of 
+     * {@link NullValueTreatment#NONE}, {@link NullValueTreatment#EXCEPTION} or
+     * {@link NullValueTreatment#DEFAULT}
+     */
+    public int getNullValueTreatment() {
+        return nullValueTreatment;
+    }
+
+    /**
+     * Sets the null value treatment indicator for this JDOField.
+     * @param nullValueTreatment an integer indicating the null 
+     * value treatment, one of: {@link NullValueTreatment#NONE}, 
+     * {@link NullValueTreatment#EXCEPTION} or 
+     * {@link NullValueTreatment#DEFAULT}
+     */
+    public void setNullValueTreatment(int nullValueTreatment) {
+        this.nullValueTreatment = nullValueTreatment;
+    }
+
+    /**
+     * Determines whether this JDOField is part of the default fetch group or 
+     * not.
+     * @return <code>true</code> if the field is part of the default fetch 
+     * group, <code>false</code> otherwise
+     */
+    public boolean isDefaultFetchGroup() {
+        if (defaultFetchGroup != null) {
+            // return dfg, if explicitly set by the setter
+            return defaultFetchGroup.booleanValue();
+        }
+        
+        // not set => calculate
+        boolean dfg = false;
+        if (isPrimaryKey()) {
+            dfg = false;
+        }
+        else {
+            JavaType type = getType();
+            if ((type != null) && type.isValue()) {
+                dfg = true;
+            }
+        }
+        
+        return dfg;
+    }
+
+    /**
+     * Set whether this JDOField is part of the default fetch group or not.
+     * @param defaultFetchGroup if <code>true</code>, the JDOField is marked  
+     * as beeing part of the default fetch group; otherwise, it is not
+     */
+    public void setDefaultFetchGroup(boolean defaultFetchGroup) {
+        this.defaultFetchGroup = 
+            defaultFetchGroup ? Boolean.TRUE : Boolean.FALSE;
+    }
+
+    /**
+     * Determines whether the field should be stored if possible as part of
+     * the instance instead of as its own instance in the datastore.
+     * @return <code>true</code> if the field is stored as part of the instance;
+     * <code>false</code> otherwise
+     */
+    public boolean isEmbedded() {
+        if (embedded != null) {
+            // return embedded, if explicitly set by the setter
+            return embedded.booleanValue();
+        }
+        
+        // not set => calculate
+        boolean result = false;
+        JavaType type = getType();
+        if (type != null) {
+            result = TypeSupport.isEmbeddedFieldType(type);
+        }
+        return result;
+    }
+
+    /**
+     * Set whether the field should be stored if possible as part of
+     * the instance instead of as its own instance in the datastore.
+     * @param embedded <code>true</code> if the field is stored as part of the 
+     * instance; <code>false</code> otherwise
+     */
+    public void setEmbedded(boolean embedded) {
+        this.embedded = (embedded ? Boolean.TRUE : Boolean.FALSE);
+    }
+    
+    /**
+     * Get the corresponding Java field representation for this JDOField.
+     * @return the corresponding Java field representation
+     */
+    public JavaField getJavaField() {
+        return javaField;
+    }
+
+    /**
+     * Sets the corresponding Java field representation for this JDOField.
+     * @param javaField the corresponding Java field representation
+     */
+    public void setJavaField (JavaField javaField) {
+        this.javaField = javaField;
+    }
+    
+    /**
+     * Determines whether this JDOField is serializable or not.  
+     * @return <code>true</code> if the field is serializable,
+     * <code>false</code> otherwise
+     */
+    public boolean isSerializable() {
+        return serializable;
+    }
+
+    /** 
+     * Set whether this JDOField is serializable or not.
+     * @param serializable if <code>true</code>, the JDOField is serializable;
+     * otherwise, it is not
+     * @exception ModelException if impossible
+     */
+    public void setSerializable(boolean serializable) throws ModelException {
+        this.serializable = serializable;
+    }
+
+    /**
+     * Get the relationship information for this JDOField. The method 
+     * returns null if the field is not part of a relationship 
+     * (e.g. it is a primitive type field).
+     * @return relationship info of this JDOField or <code>null</code> if 
+     * this JDOField is not a relationship
+     */
+    public JDORelationship getRelationship() {
+        if (relationship != null) {
+            // return relationship, if explicitly set by the setter
+            return relationship;
+        }
+        
+        // not set => calculate
+
+        if (getPersistenceModifier() == PersistenceModifier.NONE)
+            // field has persistence modifier none => cannot be a relationship
+            return null;
+                            
+        // check the type if available
+        JDORelationship rel = null;
+        JavaType type = getType();
+        if (type != null) {
+            if (type.isValue() || TypeSupport.isValueArrayType(type)) {
+                // no relationship
+                rel = null;
+            }
+            else if (type.isJDOSupportedCollection()) {
+                rel = createJDOCollectionInternal();
+            }
+            else if (type.isJDOSupportedMap()) {
+                rel = createJDOMapInternal();
+            }
+            else if (type.isArray()) {
+                rel = createJDOArrayInternal();
+            }
+            else {
+                rel = createJDOReferenceInternal();
+            }
+        }
+        return rel;
+    }
+
+    /**
+     * Set the relationship information for this JDOField.
+     * @param relationship the JDORelationship instance
+     */
+    public void setRelationship(JDORelationship relationship) {
+        this.relationship = relationship;
+    }
+
+    /**
+     * Creates and returns a new JDOReference instance. 
+     * This method automatically binds the new JDOReference to this JDOField. 
+     * The following holds true:
+     * <ul>
+     * <li> Method {@link #getRelationship} returns the new created instance
+     * <li> <code>this.getRelationship().getDeclaringField() == this</code>
+     * </ul> 
+     * @return a new JDOReference instance bound to this JDOField
+     * @exception ModelException if impossible
+     */
+    public JDOReference createJDOReference() throws ModelException {
+        JDOReference ref = createJDOReferenceInternal();
+        setRelationship(ref);
+        return ref;
+    }
+
+    /**
+     * Creates and returns a new JDOCollection instance. 
+     * This method automatically binds the new JDOCollection to this JDOField. 
+     * The following holds true:
+     * <ul>
+     * <li> Method {@link #getRelationship} returns the new created instance
+     * <li> <code>this.getRelationship().getDeclaringField() == this</code>
+     * </ul> 
+     * @return a new JDOCollection instance bound to this JDOField
+     * @exception ModelException if impossible
+     */
+    public JDOCollection createJDOCollection() throws ModelException {
+        JDOCollection col = createJDOCollectionInternal();
+        setRelationship(col);
+        return col;
+    }
+
+    /**
+     * Creates and returns a new JDOArray instance. 
+     * This method automatically binds the new JDOArray to this JDOField. 
+     * The following holds true:
+     * <ul>
+     * <li> Method {@link #getRelationship} returns the new created instance
+     * <li> <code>this.getRelationship().getDeclaringField() == this</code>
+     * </ul> 
+     * @return a new JDOArray instance bound to this JDOField
+     * @exception ModelException if impossible
+     */
+    public JDOArray createJDOArray() throws ModelException {
+        JDOArray array = createJDOArrayInternal();
+        setRelationship(array);
+        return array;
+    }
+
+    /**
+     * Creates and returns a new JDOMap instance. 
+     * This method automatically binds the new JDOMap to this JDOField. 
+     * The following holds true:
+     * <ul>
+     * <li> Method {@link #getRelationship} returns the new created instance
+     * <li> <code>this.getRelationship().getDeclaringField() == this</code>
+     * </ul> 
+     * @return a new JDOMap instance bound to this JDOField
+     * @exception ModelException if impossible
+     */
+    public JDOMap createJDOMap() throws ModelException {
+        JDOMap map = createJDOMapInternal();
+        setRelationship(map);
+        return map;
+    }
+
+    /**
+     * Convenience method to check the persistence modifier from this JDOField.
+     * @return <code>true</code> if this field has the  
+     * {@link PersistenceModifier#PERSISTENT} modifier; <code>false</code> 
+     * otherwise
+     */
+    public boolean isPersistent() {
+        switch (getPersistenceModifier()) {
+        case PersistenceModifier.PERSISTENT:
+            return true;
+        case PersistenceModifier.POSSIBLY_PERSISTENT:
+            // Enable assertion as soon as the enhancer sets the java modifier.
+            //Assertion.affirm(javaModifier, 
+            //                 msg.msg("ERR_MissingJavaModifier", 
+            //                 getDeclaringClass().getName() + "." + getName()));
+            int mod = getJavaField().getModifiers();
+            return !(Modifier.isStatic(mod) || Modifier.isFinal(mod) || 
+                     Modifier.isTransient(mod));
+        }
+        return false;
+    }
+
+    /**
+     * Convenience method to check the persistence modifier from this JDOField.
+     * @return <code>true</code> if this field has the  
+     * {@link PersistenceModifier#TRANSACTIONAL} modifier; <code>false</code> 
+     * otherwise
+     */
+    public boolean isTransactional() {
+        return (getPersistenceModifier() == PersistenceModifier.TRANSACTIONAL);
+    }
+    
+    /**
+     * Convenience method to check the persistence modifier from this JDOField.
+     * A field is a managed field, if it has the persistence-modifier 
+     * {@link PersistenceModifier#PERSISTENT} or 
+     * {@link PersistenceModifier#TRANSACTIONAL}.
+     * @return <code>true</code> if this field is a managed field; 
+     * <code>false</code> otherwise     
+     */
+    public boolean isManaged() {
+        // For now treat POSSIBLY_PERSISTENT as PERSISTENT. This will be removed 
+        // as soon as the enhancer fully supports POSSIBLY_PERSISTENT
+        int persistenceModifier = getPersistenceModifier();
+        return (persistenceModifier == PersistenceModifier.PERSISTENT) ||
+               (persistenceModifier == PersistenceModifier.POSSIBLY_PERSISTENT) || 
+               (persistenceModifier == PersistenceModifier.TRANSACTIONAL);
+    }
+
+    /**
+     * Convenience method to check whether this field is a relationship field.
+     * @return <code>true</code> if this field is a relationship;
+     * <code>false</code> otherwise
+     */
+    public boolean isRelationship() {
+        return getRelationship() != null;
+    }
+
+    /**
+     * Get the JavaType representation of the type of the field.
+     * @return JavaType representation of the type of this field.
+     */
+    public JavaType getType() {
+        return (javaField == null) ? null : javaField.getType();
+    }
+    
+    /**
+     * Returns the absolute field number of this JDOField.
+     * @return the absolute field number
+     */
+    public int getFieldNumber() {
+        int fieldNumber = getRelativeFieldNumber();
+        if (fieldNumber > -1) {
+            // >-1 denotes a managed field
+            fieldNumber += getDeclaringClass().getInheritedManagedFieldCount();
+        }
+        return fieldNumber;
+    }
+
+    /**
+     * Returns the relative field number of this JDOField.
+     * @return the relative field number
+     */
+    public int getRelativeFieldNumber() {
+        JDOField[] fields = getDeclaringClass().getDeclaredManagedFields();
+        List fieldList = Arrays.asList(fields);
+        return fieldList.indexOf(this);
+    }
+
+    //========= Internal helper methods ==========
+
+    /**
+     * Creates and returns a new JDOReference instance. 
+     * This method automatically sets this JDOField as the declarinmg field of 
+     * the returned instance.
+     * @return a new JDOReference instance bound to this JDOField
+     */
+    protected JDOReference createJDOReferenceInternal() {
+        JDOReferenceImpl ref = new JDOReferenceImpl();
+        // update relationship JDORelationship->JDOField
+        ref.setDeclaringField(this);
+        return ref;
+    }
+
+    /**
+     * Creates and returns a new JDOCollection instance. 
+     * This method automatically this JDOField as the declarinmg field of 
+     * the returned instance.
+     * @return a new JDOCollection instance bound to this JDOField
+     */
+    protected JDOCollection createJDOCollectionInternal() {
+        JDOCollectionImplDynamic collection = new JDOCollectionImplDynamic();
+        // update relationship JDORelationship->JDOField
+        collection.setDeclaringField(this);
+        return collection;
+    }
+
+    /**
+     * Creates and returns a new JDOArray instance. 
+     * This method automatically this JDOField as the declarinmg field of 
+     * the returned instance.
+     * @return a new JDOArray instance bound to this JDOField
+     */
+    protected JDOArray createJDOArrayInternal() {
+        JDOArrayImplDynamic array = new JDOArrayImplDynamic();
+        // update relationship JDORelationship->JDOField
+        array.setDeclaringField(this);
+        return array;
+    }
+
+    /**
+     * Creates and returns a new JDOMap instance. 
+     * This method automatically this JDOField as the declarinmg field of 
+     * the returned instance.
+     * @return a new JDOMap instance bound to this JDOField
+     */
+    protected JDOMap createJDOMapInternal() {
+        JDOMapImplDynamic map = new JDOMapImplDynamic();
+        // update relationship JDORelationship->JDOField
+        map.setDeclaringField(this);
+        return map;
+    }
+
+    /**
+     * Returns <code>true</code> if the name of this JDOField has the
+     * prefix jdo. 
+     * @return <code>true</code> if the name of this JDOField has the
+     * prefix jdo; <code>false</code> otherwise.
+     */
+    private boolean nameHasJDOPrefix() {
+        String name = getName();
+        return (name != null) && name.startsWith("jdo"); //NOI18N
+    }
+    
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMapImplDynamic.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMapImplDynamic.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMapImplDynamic.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMapImplDynamic.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import org.apache.jdo.impl.model.jdo.util.TypeSupport;
+import org.apache.jdo.model.ModelFatalException;
+import org.apache.jdo.model.java.JavaType;
+import org.apache.jdo.model.jdo.JDOClass;
+import org.apache.jdo.model.jdo.JDOField;
+import org.apache.jdo.model.jdo.JDOMap;
+import org.apache.jdo.model.jdo.JDOModel;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+ * An instance of this class represents the JDO relationship metadata 
+ * (the treatment of keys and values) of a map relationship field. 
+ * This dynamic implementation only stores property values explicitly
+ * set by setter method.
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class JDOMapImplDynamic extends JDORelationshipImpl implements JDOMap {
+    
+    /** Property embeddedKey. */
+    protected Boolean embeddedKey;
+
+    /** Property keyType. No default. */
+    protected transient JavaType keyType;
+
+    /** Property keyTypeName. Defaults to java.lang.Object. */
+    private String keyTypeName = "java.lang.Object"; //NOI18N
+
+    /** Property embeddedValue. */
+    protected Boolean embeddedValue;
+
+    /** Property valueType. No default. */
+    protected transient JavaType valueType;
+
+    /** Property valueTypeName. Defaults to java.lang.Object. */
+    private String valueTypeName = "java.lang.Object"; //NOI18N
+
+    /** I18N support */
+    private final static I18NHelper msg =  
+        I18NHelper.getInstance(JDOMapImplDynamic.class);
+
+    /**
+     * Determines whether the keys of the map should be stored if possible as 
+     * part of the instance instead of as their own instances in the datastore.
+     * @return <code>true</code> if the keys are stored as part of this instance;
+     * <code>false</code> otherwise
+     */
+    public boolean isEmbeddedKey() {
+        if (embeddedKey != null) {
+            // return embeddedKey, if explicitly set by the setter
+            return embeddedKey.booleanValue();
+        }
+        
+        // not set => calculate
+        JavaType type = getKeyType();
+        return (type != null) ? 
+            TypeSupport.isEmbeddedElementType(type) : false;
+    }
+    
+    /**
+     * Set whether the keys of the map should be stored if possible as part 
+     * of the instance instead of as their own instances in the datastore.
+     * @param embeddedKey <code>true</code> if the keys are stored as part of
+     * this instance; <code>false</code> otherwise
+     */
+    public void setEmbeddedKey(boolean embeddedKey) {
+        this.embeddedKey = (embeddedKey ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /**
+     * Get the type representation of the keys for this JDOMap.
+     * @return the type of the keys of this JDOMap  
+     */
+    public JavaType getKeyType() {
+        if (keyType != null) {
+            // return keyType, if explicitly set by the setter
+            return keyType;
+        }
+    
+        // not set => calculate
+        JavaType type = null;
+        if (keyTypeName != null) {
+            JDOField jdoField = getDeclaringField();
+            JDOClass jdoClass = jdoField.getDeclaringClass();
+            JDOModel jdoModel = jdoClass.getDeclaringModel();
+            type = TypeSupport.resolveType(jdoModel, keyTypeName,
+                                           jdoClass.getPackagePrefix());
+            if (type == null) {
+                throw new ModelFatalException(
+                    msg.msg("EXC_CannotResolveKeyType", keyTypeName,
+                            jdoField.getName(), jdoClass.getName())); //NOI18N
+            }
+        }
+        
+        return type;
+    }
+
+    /**
+     * Set the type representation of the keys for this JDOMap.
+     * @param keyType the type representation of the keys
+     */
+    public void setKeyType(JavaType keyType) {
+        this.keyType = keyType;
+        if (keyType != null) {
+            setKeyTypeName(keyType.getName());
+        }
+    }
+
+    /**
+     * Get the string representation of the type of the keys for this JDOMap.
+     * @return the key type as string
+     */
+    public String getKeyTypeName() {
+        return keyTypeName;
+    }
+
+    /**
+     * Set string representation of the type of the keys for this JDOMap.
+     * @param keyTypeName the name of the key type
+     */
+    public void setKeyTypeName(String keyTypeName) {
+        this.keyTypeName = keyTypeName;
+    }
+
+    /**
+     * Determines whether the values of the map should be stored if possible as 
+     * part of the instance instead of as their own instances in the datastore.
+     * @return <code>true</code> if the values are stored as part of this 
+     * instance; <code>false</code> otherwise
+     */
+    public boolean isEmbeddedValue() {
+        if (embeddedValue != null) {
+            // return embeddedKey, if explicitly set by the setter
+            return embeddedValue.booleanValue();
+        }
+        
+        // not set => calculate
+        JavaType type = getValueType();
+        return (type != null) ? 
+            TypeSupport.isEmbeddedElementType(type) : false;
+    }
+    
+    /**
+     * Set whether the values of the map should be stored if possible as part 
+     * of the instance instead of as their own instances in the datastore.
+     * @param embeddedValue <code>true</code> if the values are stored as part 
+     * of this instance; <code>false</code> otherwise
+     */
+    public void setEmbeddedValue(boolean embeddedValue) {
+        this.embeddedValue = (embeddedValue ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /**
+     * Get the type representation of the values for this JDOMap.
+     * @return the type of the values of this JDOMap  
+     */
+    public JavaType getValueType() {
+        if (valueType != null) {
+            // return valueType, if explicitly set by the setter
+            return valueType;
+        }
+    
+        // not set => calculate
+        JavaType type = null;
+        if (valueTypeName != null) {
+            JDOField jdoField = getDeclaringField();
+            JDOClass jdoClass = jdoField.getDeclaringClass();
+            JDOModel jdoModel = jdoClass.getDeclaringModel();
+            type = TypeSupport.resolveType(jdoModel, valueTypeName,
+                                           jdoClass.getPackagePrefix());
+            if (type == null) {
+                throw new ModelFatalException(
+                    msg.msg("EXC_CannotResolveValueType", valueTypeName,
+                            jdoField.getName(), jdoClass.getName())); //NOI18N
+            }
+        }
+        
+        return type;
+    }
+
+    /**
+     * Set the type representation of the values for this JDOMap.
+     * @param valueType the type representation of the values
+     */
+    public void setValueType(JavaType valueType) {
+        this.valueType = valueType;
+        if (valueType != null) {
+            setKeyTypeName(valueType.getName());
+        }
+    }
+
+    /**
+     * Get the string representation of the type of the values for this JDOMap.
+     * @return the key value as string
+     */
+    public String getValueTypeName() {
+        return valueTypeName;
+    }
+
+    /**
+     * Set string representation of the type of the values for this JDOMap.
+     * @param valueTypeName the name of the value type
+     */
+    public void setValueTypeName(String valueTypeName) {
+        this.valueTypeName = valueTypeName;
+    }
+
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMemberImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMemberImpl.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMemberImpl.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOMemberImpl.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import java.text.Collator;
+
+import org.apache.jdo.model.jdo.JDOClass;
+import org.apache.jdo.model.jdo.JDOMember;
+
+/**
+ * This is the super interface for named JDO metadata elements, 
+ * such as JDOClass and JDOField.
+ *
+ * @author Michael Bouschen
+ */
+public class JDOMemberImpl
+    extends JDOElementImpl
+    implements JDOMember
+{
+    /** Property name.*/
+    private String name;
+
+    /** Relationship JDOClass<->JDOMember. */
+    private JDOClass declaringClass;
+
+    /**
+     * Returns the name of this JDOMember.
+     * @return the name
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Sets the name of this JDOMember.
+     * @param name the name
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /** 
+     * Get the declaring class of this JDOMember.
+     * @return the class that owns this JDOMember, or <code>null</code>
+     * if the element is not attached to any class
+     */
+    public JDOClass getDeclaringClass()
+    {
+        return declaringClass;
+    }
+
+    /** 
+     * Set the declaring class of this JDOMember.
+     * @param declaringClass the declaring class of this member element
+     */
+    public void setDeclaringClass(JDOClass declaringClass)
+    {
+        this.declaringClass = declaringClass;
+    }
+
+    //================= redefinition of java.lang.Object methods ================
+    
+    /** 
+     * Overrides Object's <code>toString</code> method to return the name
+     * of this persistence element.
+     * @return a string representation of the object
+     */
+    public String toString () 
+    { 
+        return getName(); 
+    }
+    
+    /** 
+     * Overrides Object's <code>equals</code> method by comparing the name 
+     * of this member with the name of the argument obj. The method returns 
+     * <code>false</code> if obj does not have the same dynamic type as this 
+     * member.
+     * @return <code>true</code> if this object is the same as the obj argument;
+     * <code>false</code> otherwise.
+     * @param obj the reference object with which to compare.
+     */
+    public boolean equals(Object obj)
+    {
+        if (obj == null)
+            return false;
+        if (obj == this)
+            return true;
+        
+        // check for the right class and then do the name check by 
+        // calling compareTo.
+        return (getClass() == obj.getClass()) && (compareTo(obj) == 0);
+    }
+    
+    /** Overrides Object's <code>hashCode</code> method to return the hashCode 
+     * of this name.
+     * @return a hash code value for this object.
+     */
+    public int hashCode()
+    {
+        return (getName()==null) ? 0 : getName().hashCode();
+    }
+    
+    //================= implementation of Comparable ================
+    
+    /** 
+     * Compares this object with the specified object for order. Returns a 
+     * negative integer, zero, or a positive integer as this object is less than, 
+     * equal to, or greater than the specified object. The specified object must 
+     * be a an instance of JDOMember, if not a ClassCastException is thrown.
+     * The order of JDOMember instances is defined by the order of their names.
+     * JDOMember instances without name are considered to be less than any named 
+     * member.
+     * @param o the Object to be compared.
+     * @return a negative integer, zero, or a positive integer as this object is
+     * less than, equal to, or greater than the specified object.
+     * @exception ClassCastException - if the specified object is null or is not 
+     * an instance of JDOMember
+     */
+    public int compareTo(Object o)
+    {
+        // null is not allowed
+        if (o == null)
+            throw new ClassCastException();
+        if (o == this)
+            return 0;
+        
+        String thisName = getName();
+        // the following throws a ClassCastException if o is not a JDOMember
+        String otherName = ((JDOMember)o).getName();
+        // if this does not have a name it should compare less than any named
+        if (thisName == null) {
+            return (otherName == null) ? 0 : -1;
+        }
+        
+        // if this is named and o does not have a name it should compare greater
+        if (otherName == null) {
+            return 1;
+        }
+        
+        // now we know that this and o are named JDOMembers => compare the names
+        int ret = thisName.compareTo(otherName);
+        // If both names are equal, both objects might have different types.
+        // If so order both objects by their type names 
+        // (necessary to be consistent with equals)
+        if ((ret == 0) && (getClass() != o.getClass()))
+            ret = getClass().getName().compareTo(o.getClass().getName());
+        return ret;
+    }
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelFactoryImplDynamic.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelFactoryImplDynamic.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelFactoryImplDynamic.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelFactoryImplDynamic.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.jdo.model.java.JavaModel;
+import org.apache.jdo.model.jdo.JDOModel;
+import org.apache.jdo.model.jdo.JDOModelFactory;
+
+/**
+ * Factory for dynamic JDOModel instances. The factory provides a
+ * mechanism to cache JDOModel instances per JavaModel instances. 
+ * <p>
+ * TBD:
+ * <ul>
+ * <li> Check synchronization.
+ * </ul>
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class JDOModelFactoryImplDynamic implements JDOModelFactory {
+
+    /**
+     * Map of JDOModel instances, key is the JavaModel
+     * {@link #getJDOModel(JavaModel javaModel)} 
+     */
+    private Map modelCache = new HashMap();
+
+    /** The singleton JDOModelFactory instance. */    
+    private static JDOModelFactory jdoModelFactory = 
+        new JDOModelFactoryImplDynamic();
+
+    /**
+     * Creates new JDOModelFactory. This constructor should not be
+     * called directly; instead, the singleton access method  
+     * {@link #getInstance} should be used.
+     */
+    protected JDOModelFactoryImplDynamic() {}
+
+    /** 
+     * Get an instance of JDOModelFactory.
+     * @return an instance of JDOModelFactory
+     */    
+    public static JDOModelFactory getInstance() {
+        return jdoModelFactory;
+    }
+    
+    /**
+     * Creates a new empty JDOModel instance.
+     */
+    public JDOModel createJDOModel(JavaModel javaModel) {
+        return new JDOModelImplDynamic(javaModel);
+    }
+    
+    /**
+     * Returns the JDOModel instance for the specified key.
+     * @param javaModel the javaModel used to cache the returned JDOModel instance
+     */
+    public JDOModel getJDOModel(JavaModel javaModel) {
+        synchronized (this.modelCache) {
+            JDOModel jdoModel = (JDOModel)modelCache.get(javaModel);
+            if (jdoModel == null) {
+                // create new model and store it using the specified javaModel
+                jdoModel = createJDOModel(javaModel);
+                modelCache.put(javaModel, jdoModel);
+            }
+            return jdoModel;
+        }
+    }
+    
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelImplDynamic.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelImplDynamic.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelImplDynamic.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOModelImplDynamic.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,718 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.impl.model.jdo.xml.JDOHandler;
+import org.apache.jdo.impl.model.jdo.xml.JDOHandlerImpl;
+import org.apache.jdo.impl.model.jdo.xml.JDOParser;
+import org.apache.jdo.model.ModelException;
+import org.apache.jdo.model.ModelFatalException;
+import org.apache.jdo.model.java.JavaModel;
+import org.apache.jdo.model.java.JavaType;
+import org.apache.jdo.model.jdo.JDOClass;
+import org.apache.jdo.model.jdo.JDOModel;
+import org.apache.jdo.model.jdo.JDOPackage;
+import org.apache.jdo.util.I18NHelper;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+
+/**
+ * A JDOModel instance bundles a number of JDOClass instances used by an 
+ * application. It provides factory methods to create and retrieve JDOClass 
+ * instances. A fully qualified class name must be unique within a JDOModel 
+ * instance. The model supports multiple classes having the same fully qualified 
+ * name by different JDOModel instances.
+ * <p>
+ * The dynamic JDOModel implementation does not store any internally
+ * calculated values. It is intended to be used in an environment
+ * where JDO metatdata are likely to be changed (e.g. at development
+ * time).
+ * <br> 
+ * There are two exceptions:
+ * <ul>
+ * <li>JDOModelImplDynamic caches JDOClass instances. This means a
+ * second lookup of the same class will return the same JDOClass
+ * instance.
+ * <li>JDOModelImplDynamic manages a list of xml resources (.jdo
+ * files) that are processed already, to avoid reading the same
+ * resource again.
+ * <p>
+ * TBD:
+ * <ul>
+ * <li> Other implementations of JavaModel interface: Development
+ * <li> Check synchronization.
+ * <li> Check non validating XML parsing
+ * <li> Open issue: a .jdo file might contain XML for multiple classes. 
+ * Today all the metadata is stored in the same jdoModel instance, but at runtime
+ * class loading determines the correct jdoModel instance. 
+ * Either we need to be able to change the declaringModel of a JDOClass instance. 
+ * Or reading a .jdo only load metadata for the requested class, so all the other 
+ * metadata is ignored.
+ * </ul>
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class JDOModelImplDynamic extends JDOElementImpl implements JDOModel {
+
+    /** 
+     * Map of JDOPackage managed by this JDOModel instance,
+     * key is the package name.
+     */
+    private Map jdoPackages = new HashMap();
+
+    /** 
+     * Map of JDOClass objects managed by this JDOModel instance, 
+     * key is the fully qualified class name. 
+     */
+    private Map jdoClasses = new HashMap();
+
+    /**
+     * Set of names of XML resources that are processed already 
+     * (see {link #lookupXMLMetadata(String className)}.
+     */
+    private Set processedResources = new HashSet();
+
+    /** The JavaModel used to get type info. */
+    private JavaModel javaModel;
+    
+    /** I18N support */
+    protected final static I18NHelper msg =
+        I18NHelper.getInstance(JDOModelImplDynamic.class);
+
+    /** XML Logger */
+    protected static Log xmlLogger = 
+        LogFactory.getFactory().getInstance("org.apache.jdo.impl.model.jdo.xml"); // NOI18N
+
+    /** Logger */
+    protected static Log logger =
+        LogFactory.getFactory().getInstance("org.apache.jdo.impl.model.jdo"); // NOI18N
+
+    /** 
+     * Constructor. 
+     * JDOModel instances are created using the JDOModelFactory only.
+     */
+    protected JDOModelImplDynamic(JavaModel javaModel) {
+        super();
+        setJavaModel(javaModel);
+    }
+
+    /** 
+     * The method returns a JDOClass instance for the specified package name.
+     * If this JDOModel contains the corresponding JDOPackage instance,
+     * the existing instance is returned. Otherwise, it creates a new JDOPackage
+     * instance and returns the new instance.
+     * @param packageName the name of the JDOPackage instance 
+     * to be returned
+     * @return a JDOPackage instance for the specified package name
+     * @exception ModelException if impossible
+     */
+    public JDOPackage createJDOPackage(String packageName) 
+        throws ModelException {
+        JDOPackage jdoPackage = getJDOPackage(packageName);
+        if (jdoPackage == null) {
+            jdoPackage = new JDOPackageImpl();
+            jdoPackage.setName(packageName);
+            jdoPackage.setDeclaringModel(this);
+            jdoPackages.put(packageName, jdoPackage);
+        }
+        return jdoPackage;
+    }
+    
+    /** 
+     * The method returns the JDOPackage instance for the specified package 
+     * name, if present. The method returns <code>null</code> if it cannot 
+     * find a JDOPackage instance for the specified name. 
+     * @param packageName the name of the JDOPackage instance 
+     * to be returned
+     * @return a JDOPackage instance for the specified package name 
+     * or <code>null</code> if not present
+     */
+    public JDOPackage getJDOPackage(String packageName) {
+        return (JDOPackage)jdoPackages.get(packageName);
+    }
+
+    /**
+     * Returns the collection of JDOPackage instances declared by this JDOModel 
+     * in the format of an array.
+     * @return the packages declared by this JDOModel
+     */
+    public JDOPackage[] getDeclaredPackages() {
+        return (JDOPackage[])jdoPackages.values().toArray(
+            new JDOPackage[jdoPackages.size()]);
+    }
+
+    /**
+     * The method returns a JDOClass instance for the specified fully qualified
+     * class name. If this JDOModel contains the corresponding JDOClass instance,
+     * the existing instance is returned. Otherwise, it creates a new JDOClass 
+     * instance, sets its declaringModel and returns the new instance.
+     * <p>
+     * Invoking this method is method is equivalent to 
+     * <code>createJDOClass(className, true)</code>.
+     * @param className the fully qualified class name of the JDOClass instance 
+     * to be returned
+     * @return a JDOClass instance for the specified class name
+     * @exception ModelException if impossible
+     */
+    public JDOClass createJDOClass(String className) throws ModelException {
+        return createJDOClass(className, true);
+    }
+
+    /**
+     * The method returns a JDOClass instance for the specified fully qualified
+     * class name. If this JDOModel contains the corresponding JDOClass instance,
+     * the existing instance is returned. Otherwise, if the flag loadXMLMetadata
+     * is set to <code>true</code> the method tries to find the JDOClass 
+     * instance by reading the XML metadata. If it could not be found the method
+     * creates a new JDOClass instance, sets its declaringModel and returns the 
+     * instance.
+     * @param className the fully qualified class name of the JDOClass instance 
+     * to be returned
+     * @param loadXMLMetadata indicated whether to read XML metadata or not
+     * @return a JDOClass instance for the specified class name
+     * @exception ModelException if impossible
+     */
+    public synchronized JDOClass createJDOClass(String className, 
+                                                boolean loadXMLMetadata)
+        throws ModelException {
+        JDOClass jdoClass = getJDOClass(className, loadXMLMetadata);
+        if (jdoClass == null) {
+            if (logger.isDebugEnabled())
+                logger.debug("JDOModel.createJDOClass: " + //NOI18N
+                             "create new JDOClass instance " + className); //NOI18N
+            jdoClass = newJDOClassInstance();
+            jdoClass.setName(className);
+            jdoClass.setDeclaringModel(this);
+            jdoClasses.put(className, jdoClass);
+            // create the corresponding JDOPackage
+            jdoClass.setJDOPackage(createJDOPackage(getPackageName(className)));
+        }
+        return jdoClass;
+    }
+
+    /**
+     * The method returns the JDOClass instance for the specified fully 
+     * qualified class name if present. The method returns <code>null</code> 
+     * if it cannot find a JDOClass instance for the specified name. 
+     * <p>
+     * Invoking this method is equivalent to 
+     * <code>getJDOClass(className, true)</code>.
+     * @param className the fully qualified class name of the JDOClass instance 
+     * to be returned
+     * @return a JDOClass instance for the specified class name 
+     * or <code>null</code> if not present
+     */
+    public JDOClass getJDOClass(String className) {
+        return getJDOClass(className, true);
+    }
+    
+    /**
+     * The method returns the JDOClass instance for the specified fully 
+     * qualified class name if present. If the flag loadXMLMetadata is set 
+     * to <code>true</code> the method tries to find the JDOClass instance by 
+     * reading the XML metadata. The method returns null if it cannot find a 
+     * JDOClass instance for the specified name.
+     * @param className the fully qualified class name of the JDOClass instance 
+     * to be returned
+     * @param loadXMLMetadata indicate whether to read XML metatdata or not
+     * @return a JDOClass instance for the specified class name
+     * or <code>null</code> if not present
+     * @exception ModelException if impossible
+     */
+    public synchronized JDOClass getJDOClass(String className, 
+                                             boolean loadXMLMetadata) {
+
+        boolean trace = logger.isTraceEnabled();
+
+        // check whether the class is known to be non PC
+        if (isKnownNonPC(className)) {
+            if (trace)
+                logger.trace("JDOModel.getJDOClass: " + className + //NOI18N
+                             " known to be non-persistence-capable"); //NOI18N
+            return null;
+        }
+
+        JDOClass jdoClass = (JDOClass)jdoClasses.get(className);
+        if (trace)
+            logger.trace("JDOModel.getJDOClass: " + className + //NOI18N
+                         ((jdoClass != null) ? " cached" : " not cached")); //NOI18N
+
+        // check for XML metatdata
+        if (loadXMLMetadata) {
+            if (jdoClass == null)
+                jdoClass = lookupXMLMetadata(className);
+            else if (!isXMLProcessed(jdoClass))
+                jdoClass = lookupXMLMetadata(jdoClass);
+
+            if (jdoClass == null) {
+                // we loaded XML metadata, but there is no metadata
+                // for this class => known to be non persistence-capable
+                knownNonPC(className);
+            }
+        }
+
+        return jdoClass;
+    }
+
+    /**
+     * Returns the collection of JDOClass instances declared by this JDOModel 
+     * in the format of an array.
+     * @return the classes declared by this JDOModel
+     */
+    public synchronized JDOClass[] getDeclaredClasses()  {
+        return (JDOClass[])jdoClasses.values().toArray(
+            new JDOClass[jdoClasses.size()]);
+    }
+
+    /**
+     * Returns the JavaModel bound to this JDOModel instance.
+     * @return the JavaModel
+     */
+    public JavaModel getJavaModel() {
+        return javaModel;
+    }
+    
+    /**
+     * Sets the JavaModel for this JDOModel instance.
+     * @param javaModel the JavaModel
+     */
+    public void setJavaModel(JavaModel javaModel) {
+        this.javaModel = javaModel;
+    }
+    
+    /**
+     * Returns the parent JDOModel instance of this JDOModel.
+     * @return the parent JDOModel
+     */
+    public JDOModel getParent() {
+        if (javaModel != null) {
+            JavaModel parentJavaModel = javaModel.getParent();
+            if (parentJavaModel != null)
+                return parentJavaModel.getJDOModel();
+        }
+        return null; 
+    }
+
+    /**
+     * This method returns the JDOClass instance that defines the specified type
+     * as its objectId class. In the case of an inheritance hierarchy it returns 
+     * the top most persistence-capable class of the hierarchy (see 
+     * {@link JDOClass#getPersistenceCapableSuperclass}).
+     * @param objectIdClass the type representation of the ObjectId class
+     * @return the JDOClass defining the specified class as ObjectId class
+     */
+    public JDOClass getJDOClassForObjectIdClass(JavaType objectIdClass) {
+        // Note, method getJDOClassForObjectIdClass is not synchronized to
+        // avoid a deadlock with PC class registration.
+        if (logger.isTraceEnabled())
+            logger.trace("JDOModel.getJDOClassForObjectIdClass: " + //NOI18N
+                         "check objectIdClass " +objectIdClass); //NOI18N
+                        
+        if (objectIdClass == null)
+            return null;
+
+        JDOClass jdoClass = null;
+        String objectIdClassName = objectIdClass.getName();
+        // check all JDOClasses for this JDOModel instance
+        List classesToActivate = new ArrayList();
+        while (true) {
+            try {
+                for (Iterator i = jdoClasses.values().iterator(); i.hasNext();) {
+                    JDOClass next = (JDOClass)i.next();
+                    if (isXMLProcessed(next)) {
+                        // XML metadata is loaded => check the objectIdClass
+                        if (objectIdClassName.equals(
+                                next.getDeclaredObjectIdClassName())) {
+                            // found => return
+                            return next;
+                        }
+                    }
+                    else {
+                        // XML metadata is NOT loaded => 
+                        // store the class for later processing.
+                        // Do not load the XML metadata here. This might create
+                        // new JDOClass instances in this model for other pc
+                        // classes listed in the same .jdo file. This would
+                        // change the jdoClasses map while its values are
+                        // iterated => ConcurrentModificationException
+                        classesToActivate.add(next);
+                    }
+                }
+                // No ConcurrentModificationException => break the loop 
+                break;
+            }
+            catch (ConcurrentModificationException ex) {
+                // ConcurrentModificationException means a JDOClass was
+                // added to the JDOModel in parallel => 
+                // start the loop again.
+            }
+        }
+                
+        // None of the activated JDOClasses knows the objectIdClass =>
+        // activate the classes that were registered but not activated 
+        // and check these classes
+        for (Iterator i = classesToActivate.iterator(); i.hasNext();) {
+            JDOClass next = (JDOClass)i.next();
+            lookupXMLMetadata(next);
+
+            if (objectIdClass.equals(next.getDeclaredObjectIdClassName())) {
+                // found => return
+                return next;
+            }
+        }
+
+        // objectIdClass not found in this model => return null
+        return null;
+    }
+
+    //========= Internal helper methods ==========
+    
+    /** Returns a new instance of the JDOClass implementation class. */
+    protected JDOClass newJDOClassInstance() {
+        return new JDOClassImplDynamic();
+    }
+
+    /**
+     * Checks whether the type with the specified name does NOT denote a
+     * persistence-capable class.
+     * @param typeName name of the type to be checked
+     * @return <code>true</code> if types is a name of a primitive type; 
+     * <code>false</code> otherwise
+     */
+    protected boolean isKnownNonPC(String typeName) {
+        // Any class from packages java and javax are supposed to be non-pc.
+        return typeName.startsWith("java.") || //NOI18N
+               typeName.startsWith("javax."); //NOI18N
+    }
+
+    /** 
+     * Hook called when a class is known to be non persistence
+     * capable. Subclasses might want to keep track of classes marked
+     * as non pc classes and use this in the implementation of
+     * {link #isKnownNonPC(String typeName)}.
+     * @param className the name of the non-pc class
+     */
+    protected void knownNonPC(String className) {
+    }
+
+    /** 
+     * Return true if the specified JDOClass is activated. 
+     * A class is activated, if the class XML metadata is processed
+     * for this JDOClass. 
+     * @return <code>true</code> if XML metadata is processed;
+     * <code>false</code> otherwise
+     */
+    private boolean isXMLProcessed(JDOClass jdoClass) {
+        if (jdoClass instanceof JDOClassImplDynamic)
+            return ((JDOClassImplDynamic)jdoClass).isXMLProcessed();
+        return false;
+    }
+
+    /**
+     * The method seaches JDO metadata for the class with the specified
+     * class name. Chapter 18 of the JDO specification defines the search
+     * order. The method skips resources that have been tried to load
+     * before, no matter whether the resource currently exist. 
+     * The method returns the populated JDOClass instance, if there is XML
+     * metadata available for the specified class name. Otherwise it
+     * returns <code>null</code>. 
+     * <p>
+     * The purpose of this method is to populate an existing JDOClass
+     * instance with the JDO metadata. It throws an exception if there is
+     * no jdo file for this class. The specified jdoClass must not be
+     * <code>null</code>; otherwise a NullPointerException is thrown.
+     * @param jdoClass the non-activated JDOClass instance.
+     * @return the JDOClass instance for the specified class name or
+     * <code>null</code> if there is no XML metadata.
+     * @exception ModelFatalException indicates a problem while parsing the
+     * XML file or a missing XML file.
+     * @exception NullPointerException the specified jdoClass is
+     * <code>null</code>.
+     */
+    private JDOClass lookupXMLMetadata(JDOClass jdoClass)
+        throws ModelFatalException, NullPointerException {
+        String className = jdoClass.getName();
+        JDOClass activated = lookupXMLMetadata(className);
+        if (activated == null) {
+            throw new ModelFatalException(msg.msg(
+                "EXC_MissingJDOMetadata", className)); //NOI18N
+        }
+        else if (activated != jdoClass) {
+            throw new ModelFatalException(msg.msg(
+                "ERR_MultipleJDOClassInstances", className)); //NOI18N
+        }
+        return jdoClass;
+    }
+
+    /**
+     * The method seaches JDO metadata for the class with the specified
+     * class name. Chapter 18 of the JDO specification defines the search
+     * order. The method skips resources that have been tried to load
+     * before, no matter whether the resource currently exist. 
+     * The method returns the populated JDOClass instance, if there is XML
+     * metadata available for the specified class name. Otherwise it
+     * returns <code>null</code>. 
+     * @param className the name of the class to check for XML metadata.
+     * @return the JDOClass instance for the specified class name or
+     * <code>null</code> if there is no XML metadata.
+     */
+    private JDOClass lookupXMLMetadata(String className) {
+        boolean debug = xmlLogger.isDebugEnabled();
+        JDOClass jdoClass = null;
+        
+        if (debug)
+            xmlLogger.debug("JDOModel.lookupXMLMetadata:" + // NOI18N
+                            " lookup XML for class " + className); // NOI18N
+        // Iterate possible resources to find JDO metadata for className
+        Iterator i = new MetadataResourceNameIterator(className);
+        while((jdoClass == null) && i.hasNext()) {
+            String resource = (String)i.next();
+            if (processedResources.contains(resource)) {
+                if (debug)
+                    xmlLogger.debug("  XML " + resource + //NOI18N
+                                    " processed already"); //NOI18N
+                // processed already => skip
+                continue;
+            }
+            else {
+                // add resource to the list of processed resources
+                // Note, this adds the resource no matter whether the
+                // resource existst or not. This implies this JDOModel 
+                // instance will not check this resource again, 
+                // even if it exists, again.
+                processedResources.add(resource);
+                // load resource
+                jdoClass = loadXMLResource(resource, className);
+            }
+        }
+        if (debug)
+            xmlLogger.debug("JDOModel.lookupXMLMetadata: " +  //NOI18N
+                            ((jdoClass!=null)?"found":"no") + //NOI18N
+                            " JDO metadata for class " + className); //NOI18N
+        return jdoClass;
+    }
+
+    /**
+     * Load the specified resource assuming it contains JDO metadata for
+     * one or more persistence capable classes. 
+     * The method returns the populated JDOClass instance, if the specified
+     * resource has XML metadata for the specified class name. Otherwise it
+     * returns <code>null</code>. 
+     * @param resource resource to load
+     * @param className the name of the class to check for XML metadata.
+     * @return the JDOClass instance for the specified class name or
+     * <code>null</code> if the specified resource has no XML metadata.
+     */
+    private JDOClass loadXMLResource(String resource, String className) {
+        boolean debug = xmlLogger.isDebugEnabled();
+        JDOClass jdoClass = null;
+        InputStream stream = javaModel.getInputStreamForResource(resource);
+        if (stream == null) {
+            if (debug)
+                xmlLogger.debug("  XML " + resource + " not available"); //NOI18N
+        }
+        else {
+            // resource exists => parse it
+            // Store all pc classes specified in this resource in this
+            // JDOModel instance => pass this to the handler
+            JDOHandler handler = new JDOHandlerImpl(this);
+            JDOParser parser = new JDOParser(handler);
+            try {
+                if (debug)
+                    xmlLogger.debug("  XML " + resource +  //NOI18N
+                                    " found, start parsing ..."); //NOI18N
+                parser.parse(new InputSource(new InputStreamReader(stream)));
+            }
+            catch (SAXException ex) {
+                throw new ModelFatalException(
+                    msg.msg("EXC_XMLError", resource), ex); //NOI18N
+            }
+            catch (ParserConfigurationException ex) {
+                throw new ModelFatalException(
+                    msg.msg("EXC_XMLError", resource), ex); //NOI18N
+            }
+            catch (IOException ex) {
+                throw new ModelFatalException(
+                    msg.msg("EXC_XMLError", resource), ex); //NOI18N
+            }
+            finally {
+                try { stream.close(); }
+                catch (IOException ex) { 
+                    // ignore close exception, stream will be nullified anyway 
+                }
+            }
+            stream = null;
+            
+            // post process loaded JDOClasses
+            Collection newJDOClasses = handler.handledJDOClasses();
+            if (debug)
+                xmlLogger.debug("  XML " + resource + //NOI18N
+                                " has JDO metadata for class(es) " + //NOI18N
+                                newJDOClasses);
+            for (Iterator i = newJDOClasses.iterator(); i.hasNext();) {
+                JDOClass next = (JDOClass)i.next();
+                if (className.equals(next.getName())) {
+                    jdoClass = next;
+                }
+                checkSuperclass(next);
+            }
+            if (jdoClass == null)
+                if (debug)
+                    xmlLogger.debug("  XML " + resource + //NOI18N
+                                    " does not have JDO metadata for class " + //NOI18N
+                                    className); 
+        }
+        return jdoClass;
+    }
+
+    /**
+     * Updates the pcSuperclass property of the specified JDOClass and all its 
+     * superclasses. 
+     * @param jdoClass the class to be checked
+     */
+    private void checkSuperclass(JDOClass jdoClass) {
+        if (jdoClass != null) {
+            JDOClass superclass = jdoClass.getPersistenceCapableSuperclass();
+            checkSuperclass(superclass);
+        }
+    }
+
+    /** Returns the package name of a class name */
+    private String getPackageName(String className) {
+        int index = className.lastIndexOf('.');
+        return (index == -1) ? "" : className.substring(0, index); //NOI18N
+    }
+    
+    /**
+     * This Iterator implementation iterates resource names of possible JDO
+     * metadata files for the specified class name. Chapter 18 of the JDO
+     * specification defines the search order as follows: 
+     * META-INF/package.jdo, WEB-INF/package.jdo, package.jdo, 
+     * <package>/.../<package>/package.jdo, and <package>/<class>.jdo.
+     */
+    private static class MetadataResourceNameIterator 
+        implements Iterator {
+        /** Suffix of a JDO metadata file. */
+        private static final String JDO_SUFFIX = ".jdo"; //NOI18N
+
+        /** The name of a package JDO metadata file. */
+        private static final String PACKAGE_JDO = "package" + JDO_SUFFIX; //NOI18N
+
+        /** List of constant package JDO metadata file names. */
+        private static final String[] constantResources = { 
+            "META-INF/" + PACKAGE_JDO, //NOI18N
+            "WEB-INF/" + PACKAGE_JDO,  //NOI18N
+            PACKAGE_JDO 
+        };
+
+        /** Indicates whether this iterator has more elements. */
+        private boolean hasNext = true;
+
+        /** The class name as resource name. */
+        private final String prefix;
+
+        /** Current index in the list of constant package JDO metadata file names. */
+        private int constantResourcesIndex = 0;
+
+        /** Current index in the prefix. */
+        private int fromIndex = 0;
+
+        /** Constructor. */
+        public MetadataResourceNameIterator(String className) {
+            this.prefix = className.replace('.', '/');
+        }
+        
+        /**
+         * Returns <code>true</code> if the iteration has more elements.
+         * @return <code>true</code> if the iterator has more elements.
+         */
+        public boolean hasNext() {
+            return hasNext;
+        }
+        
+        /**
+         * Returns the next resource name.
+         * @return the next resource name.
+         * @exception NoSuchElementException iteration has no more elements. 
+         */
+        public Object next() {
+            String resource = null;
+            if (!hasNext) {
+                throw new NoSuchElementException();
+            }
+            else if (constantResourcesIndex < constantResources.length) {
+                // Use a constant resource name, if there is one left in
+                // the iteration.
+                resource = constantResources[constantResourcesIndex];
+                constantResourcesIndex++;
+            }
+            else {
+                // No constant resource name left
+                // build resource names from the package of the class name
+                // Check for the next package, fromIndex is the index of
+                // the '/' used in the previous iteration.
+                int index = prefix.indexOf('/', fromIndex);
+                if (index != -1) {
+                    // string needs to include '/' => use index+1
+                    resource = prefix.substring(0, index + 1) + PACKAGE_JDO;
+                    fromIndex = index + 1;
+                }
+                else {
+                    // no more package jdo files left => use class .jdo file 
+                    resource = prefix + JDO_SUFFIX;
+                    // the class jdo file is the last resource to be checked 
+                    hasNext = false;
+                }
+            }
+            return resource;
+        }
+
+        /**
+         * This Iterator does not implement this method.
+         * @exception UnsupportedOperationException if the
+         * <code>remove</code> operation is not supported by this
+         * Iterator. 
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+        
+    }
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOPackageImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOPackageImpl.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOPackageImpl.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOPackageImpl.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import java.util.*;
+
+import org.apache.jdo.model.jdo.JDOModel;
+import org.apache.jdo.model.jdo.JDOPackage;
+
+/**
+ * A JDOPackage instance represents the JDO package metadata.
+ *
+ * @author Michael Bouschen
+ */
+public class JDOPackageImpl 
+    extends JDOElementImpl
+    implements JDOPackage
+{
+    /** The package name. */
+    private String name;
+
+    /** Relationship JDOModel<->JDOPackage. Initialized during creation.*/
+    private JDOModel declaringModel;
+
+    /**
+     * Returns the name of this JDOPackage.
+     * @return the name
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Sets the name of this JDOPackage.
+     * @param name the name
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Returns the declaring JDOModel of this JDOPackage.
+     * @return the JDOModel that owns this JDOPackage.
+     */
+    public JDOModel getDeclaringModel()
+    {
+        return declaringModel;
+    }
+
+    /**
+     * Set the declaring JDOModel for this JDOPackage.
+     * @param model the declaring JDOModel of this JDOPackage.
+     */
+    public void setDeclaringModel(JDOModel model)
+    {
+        this.declaringModel = model;
+    }
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOReferenceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOReferenceImpl.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOReferenceImpl.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDOReferenceImpl.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import org.apache.jdo.model.jdo.JDOReference;
+
+/**
+ * An instance of this class represents the JDO relationship metadata 
+ * of a reference relationship field.
+ *
+ * @author Michael Bouschen
+ */
+public class JDOReferenceImpl extends JDORelationshipImpl 
+    implements JDOReference
+{
+    // empty implementation
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDORelationshipImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDORelationshipImpl.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDORelationshipImpl.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/JDORelationshipImpl.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo;
+
+import org.apache.jdo.model.jdo.JDOField;
+import org.apache.jdo.model.jdo.JDORelationship;
+
+/**
+ * JDORelationship is the super interface for all interfaces representing 
+ * JDO relationship metadata of a managed field of a persistence capable class.
+ * 
+ * @author Michael Bouschen
+ */
+public abstract class JDORelationshipImpl extends JDOElementImpl
+    implements JDORelationship {
+    
+    /** Property lowerBound. No default. */
+    private int lowerBound;
+
+    /** Property upperBound. No default. */
+    private int upperBound;
+
+    /** Relationship JDOField<->JDORelationship. */
+    private JDOField declaringField;
+
+    /** Relationship JDORelationship<->JDORelationship. */
+    private JDORelationship inverse;
+
+    /** 
+     * Get the lower cardinality bound for this relationship element.
+     * @return the lower cardinality bound
+     */
+    public int getLowerBound() {
+        return lowerBound;
+    }
+
+    /** 
+     * Set the lower cardinality bound for this relationship element.
+     * @param lowerBound an integer indicating the lower cardinality bound
+     */
+    public void setLowerBound(int lowerBound) {
+        this.lowerBound = lowerBound;
+    }
+    
+    /** 
+     * Get the upper cardinality bound for this relationship element.
+     * @return the upper cardinality bound
+     */
+    public int getUpperBound() {
+        return upperBound;
+    }
+
+    /** 
+     * Set the upper cardinality bound for this relationship element.
+     * @param upperBound an integer indicating the upper cardinality bound
+     */
+    public void setUpperBound(int upperBound)
+    {
+        this.upperBound = upperBound;
+    }
+
+    /** 
+     * Get the declaring field of this JDORelationship.
+     * @return the field that owns this JDORelationship, or <code>null</code>
+     * if the element is not attached to any field
+     */
+    public JDOField getDeclaringField() {
+        return declaringField;
+    }
+
+    /** 
+     * Set the declaring field of this JDORelationship.
+     * @param declaringField the declaring field of this relationship element
+     */
+    public void setDeclaringField(JDOField declaringField) {
+        this.declaringField = declaringField;
+    }
+    
+    /**
+     * Get the inverse JDORelationship in the case of a managed relationship.
+     * @return the inverse relationship
+     */
+    public JDORelationship getInverseRelationship() {
+        return inverse;
+    }
+
+    /**
+     * Set the inverse JDORelationship in the case of a managed relationship.
+     * @param inverseRelationship the inverse relationship
+     */
+    public void setInverseRelationship(JDORelationship inverseRelationship) {
+        this.inverse = inverseRelationship;
+    }
+
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/caching/JDOArrayImplCaching.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/caching/JDOArrayImplCaching.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/caching/JDOArrayImplCaching.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/jdo/caching/JDOArrayImplCaching.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.model.jdo.caching;
+
+import org.apache.jdo.model.java.JavaType;
+import org.apache.jdo.impl.model.jdo.JDOArrayImplDynamic;
+
+/**
+ * An instance of this class represents the JDO relationship metadata 
+ * of a array relationship field. This caching implementation
+ * caches any calulated value to avoid re-calculating it if it is
+ * requested again. 
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class JDOArrayImplCaching extends JDOArrayImplDynamic {
+    
+    /** Type of the array element. */
+    private transient JavaType elementType;
+    
+    /**
+     * Determines whether the values of the elements should be stored 
+     * if possible as part of the instance instead of as their own instances 
+     * in the datastore.
+     * @return <code>true</code> if the elements should be stored as part of 
+     * the instance; <code>false</code> otherwise
+     */
+    public boolean isEmbeddedElement() {
+        if (embeddedElement == null) {
+            embeddedElement = 
+                super.isEmbeddedElement() ? Boolean.TRUE : Boolean.FALSE;
+        }
+        return embeddedElement.booleanValue();
+    }
+    
+    /** 
+     * Get the type representation of the array component type. 
+     * @return the array component type
+     */
+    public JavaType getElementType() {
+        if (elementType == null) {
+            elementType = super.getElementType();
+        }
+        return elementType;
+    }
+
+}
+



Mime
View raw message