You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by mb...@apache.org on 2005/05/22 19:44:23 UTC

svn commit: r171348 [7/7] - in /incubator/jdo/trunk/core20: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/model/ src/java/org/apache/jdo/impl/model/java/ src/java/org/apache/jdo/impl/model/java/reflection/ 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/model/ src/java/org/apache/jdo/model/java/ src/java/org/apache/jdo/model/jdo/ src/java/org/apache/jdo/util/

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOMember.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOMember.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOMember.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOMember.java Sun May 22 10:44:19 2005
@@ -0,0 +1,59 @@
+/*
+ * 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.model.jdo;
+
+import org.apache.jdo.model.ModelException;
+
+/**
+ * This is the super interface for named JDO metadata elements, 
+ * such as JDOClass and JDOField.
+ *
+ * @author Michael Bouschen
+ */
+public interface JDOMember
+    extends JDOElement, Comparable 
+{
+    /**
+     * Returns the name of this JDOMember.
+     * @return the name
+     */
+    public String getName();
+
+    /**
+     * Sets the name of this JDOMember.
+     * @param name the name
+     * @exception ModelException if impossible
+     */
+    public void setName(String name)
+        throws ModelException;
+
+    /** 
+     * 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();
+
+    /** 
+     * Set the declaring class of this JDOMember.
+     * @param declaringClass the declaring class of this member element
+     * @exception ModelException if impossible
+     */
+    public void setDeclaringClass(JDOClass declaringClass)
+        throws ModelException;
+
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.java Sun May 22 10:44:19 2005
@@ -0,0 +1,168 @@
+/*
+ * 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.model.jdo;
+
+import org.apache.jdo.model.ModelException;
+import org.apache.jdo.model.java.JavaModel;
+import org.apache.jdo.model.java.JavaType;
+
+
+/**
+ * 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.
+ *
+ * @author Michael Bouschen
+ */
+public interface JDOModel
+    extends JDOElement
+{
+    /** 
+     * 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;
+
+    /** 
+     * 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);
+
+    /**
+     * 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();
+
+    /**
+     * 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>
+     * Whether this method reads XML metatdata or not is deteremined at
+     * JDOModel creation time (see flag <code>loadXMLMetadataDefault</code> 
+     * in {@link JDOModelFactory#getJDOModel(JavaModel javaModel, boolean
+     * loadXMLMetadataDefault)}). Invoking this method is method is equivalent
+     * to <code>createJDOClass(className, loadXMLMetadataDefault)</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;
+
+    /**
+     * 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 indicates whether to read XML metatdata or not
+     * @return a JDOClass instance for the specified class name
+     * @exception ModelException if impossible
+     */
+    public JDOClass createJDOClass(String className, boolean loadXMLMetadata)
+        throws ModelException;
+
+    /**
+     * 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>
+     * Whether this method reads XML metatdata or not is deteremined at
+     * JDOModel creation time (see flag <code>loadXMLMetadataDefault</code> 
+     * in {@link JDOModelFactory#getJDOModel(JavaModel javaModel, boolean
+     * loadXMLMetadataDefault)}). Invoking this method is method is equivalent
+     * to <code>createJDOClass(className, loadXMLMetadataDefault)</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);
+
+    /**
+     * 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 indicates whether to read XML metatdata or not
+     * @return a JDOClass instance for the specified class name
+     * or <code>null</code> if not present
+     */
+    public JDOClass getJDOClass(String className, boolean loadXMLMetadata);
+
+    /**
+     * Returns the collection of JDOClass instances declared by this JDOModel 
+     * in the format of an array.
+     * @return the classes declared by this JDOModel
+     */
+    public JDOClass[] getDeclaredClasses();
+
+    /**
+     * Returns the JavaModel bound to this JDOModel instance.
+     * @return the JavaModel
+     */
+    public JavaModel getJavaModel();
+    
+    /**
+     * Sets the JavaModel for this JDOModel instance.
+     * @param javaModel the JavaModel
+     */
+    public void setJavaModel(JavaModel javaModel);
+
+    /**
+     * Returns the parent JDOModel instance of this JDOModel.
+     * @return the parent JDOModel
+     */
+    public JDOModel getParent();
+
+    /**
+     * 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);
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.jpg
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.jpg?rev=171348&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.mdl
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.mdl?rev=171348&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModel.mdl
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelFactory.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelFactory.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelFactory.java Sun May 22 10:44:19 2005
@@ -0,0 +1,68 @@
+/*
+ * 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.model.jdo;
+
+import org.apache.jdo.model.ModelException;
+import org.apache.jdo.model.java.JavaModel;
+
+
+/**
+ * Factory for JDOModel instances. The factory provides a mechanism to cache 
+ * JDOModel instances per user defined keys.
+ * 
+ * @author Michael Bouschen
+ */
+public interface JDOModelFactory 
+{
+    /**
+     * Creates a new empty JDOModel instance. 
+     * The returned JDOModel instance uses the specified flag
+     * <code>loadXMLMetadataDefault</code> to set the default behavior 
+     * for the creation of new JDOClass instances  using methods 
+     * {@link JDOModel#createJDOClass(String)} and 
+     * {@link JDOModel#getJDOClass(String)} for which the caller doesn't 
+     * explicitly specify whether to read XML metatdata or not.
+     * @param loadXMLMetadataDefault the default setting for whether to 
+     * read XML metatdata in JDOModel's methods for JDOClass creation.
+     * @exception ModelException if impossible
+     */
+    public JDOModel createJDOModel(JavaModel javaModel,
+                                   boolean loadXMLMetadataDefault)
+        throws ModelException;
+    
+    /**
+     * Returns the JDOModel instance for the specified JavaModel.
+     * @param javaModel the javaModel used to cache the returned JDOModel
+     * instance.
+     */
+    public JDOModel getJDOModel(JavaModel javaModel);
+    
+    /**
+     * Returns the JDOModel instance for the specified JavaModel.  
+     * The returned JDOModel instance uses the specified flag
+     * <code>loadXMLMetadataDefault</code> to set the default behavior 
+     * for the creation of new JDOClass instances  using methods 
+     * {@link JDOModel#createJDOClass(String)} and 
+     * {@link JDOModel#getJDOClass(String)} for which the caller doesn't 
+     * explicitly specify whether to read XML metatdata or not.
+     * @param loadXMLMetadataDefault the default setting for whether to 
+     * read XML metatdata in JDOModel's methods for JDOClass creation.
+     */
+    public JDOModel getJDOModel(JavaModel javaModel, 
+                                boolean loadXMLMetadataDefault);
+
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelHelper.jpg
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelHelper.jpg?rev=171348&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOModelHelper.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOPackage.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOPackage.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOPackage.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOPackage.java Sun May 22 10:44:19 2005
@@ -0,0 +1,54 @@
+/*
+ * 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.model.jdo;
+
+import org.apache.jdo.model.ModelException;
+
+/**
+ * A JDOPackage instance represents the JDO package metadata.
+ *
+ * @author Michael Bouschen
+ */
+public interface JDOPackage 
+    extends JDOElement
+{
+    /**
+     * Returns the name of this JDOPackage.
+     * @return the name
+     */
+    public String getName();
+
+    /**
+     * Sets the name of this JDOPackage.
+     * @param name the name
+     * @exception ModelException if impossible
+     */
+    public void setName(String name)
+        throws ModelException;
+
+    /**
+     * Returns the declaring JDOModel of this JDOPackage.
+     * @return the JDOModel that owns this JDOPackage.
+     */
+    public JDOModel getDeclaringModel();
+
+    /**
+     * Set the declaring JDOModel for this JDOPackage.
+     * @param model the declaring JDOModel of this JDOPackage.
+     */
+    public void setDeclaringModel(JDOModel model);
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOReference.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOReference.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOReference.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDOReference.java Sun May 22 10:44:19 2005
@@ -0,0 +1,28 @@
+/*
+ * 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.model.jdo;
+
+/**
+ * A JDOReference instance represents the JDO relationship metadata 
+ * of a reference relationship field.
+ *
+ * @author Michael Bouschen
+ */
+public interface JDOReference
+    extends JDORelationship 
+{
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDORelationship.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDORelationship.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDORelationship.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/JDORelationship.java Sun May 22 10:44:19 2005
@@ -0,0 +1,103 @@
+/*
+ * 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.model.jdo;
+
+import org.apache.jdo.model.ModelException;
+
+/**
+ * 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 interface JDORelationship 
+    extends JDOElement 
+{
+    /**
+     * Constant representing the cardinality zero used for lower and upper 
+     * bounds.
+     */
+    public static final int CARDINALITY_ZERO = 0;
+
+    /**
+     * Constant representing the cardinality one used for lower and upper bounds.
+     */
+    public static final int CARDINALITY_ONE = 1;
+
+    /**
+     * Constant representing the cardinality n used for lower and upper bounds.
+     */
+    public static final int CARDINALITY_N = java.lang.Integer.MAX_VALUE;
+
+    /** 
+     * Get the lower cardinality bound for this relationship element.
+     * @return the lower cardinality bound
+     */
+    public int getLowerBound();
+
+    /** 
+     * Set the lower cardinality bound for this relationship element.
+     * @param lowerBound an integer indicating the lower cardinality bound
+     * @exception ModelException if impossible
+     */
+    public void setLowerBound(int lowerBound)
+        throws ModelException;
+    
+    /** 
+     * Get the upper cardinality bound for this relationship element.
+     * @return the upper cardinality bound
+     */
+    public int getUpperBound();
+
+    /** 
+     * Set the upper cardinality bound for this relationship element.
+     * @param upperBound an integer indicating the upper cardinality bound
+     * @exception ModelException if impossible
+     */
+    public void setUpperBound(int upperBound)
+        throws ModelException;
+
+    /** 
+     * 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();
+
+    /** 
+     * Set the declaring field of this JDORelationship.
+     * @param declaringField the declaring field of this relationship element
+     * @exception ModelException if impossible
+     */
+    public void setDeclaringField(JDOField declaringField)
+        throws ModelException;
+
+    /**
+     * Get the inverse JDORelationship in the case of a managed relationship.
+     * @return the inverse relationship
+     */
+    public JDORelationship getInverseRelationship();
+
+    /**
+     * Set the inverse JDORelationship in the case of a managed relationship.
+     * @param inverseRelationship the inverse relationship
+     * @exception ModelException if impossible
+     */
+    public void setInverseRelationship(JDORelationship inverseRelationship)
+        throws ModelException;
+
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/NullValueTreatment.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/NullValueTreatment.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/NullValueTreatment.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/NullValueTreatment.java Sun May 22 10:44:19 2005
@@ -0,0 +1,88 @@
+/*
+ * 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.model.jdo;
+
+/**
+ * This interface provides constants denoting the treatment of null values 
+ * for persistent fields during storage in the data store.
+ *
+ * @author Michael Bouschen
+ */
+public class NullValueTreatment 
+{
+    /**
+     * Constant representing converting a null value of a field of nullable type 
+     * to the default value for the type in the datastore.
+     */
+    public static final int NONE = 0;
+
+    /** 
+     * Constant representing throwing an exception when storing a null value of 
+     * field of a nullable type that is mapped to non-nullable type in the 
+     * datastore.
+     */
+    public static final int EXCEPTION = 1;
+
+    /**
+     * Constant representing converting a null value of a field of nullable type 
+     * to the default value for the type in the datastore.
+     */
+    public static final int DEFAULT = 2;
+
+    /**
+     * Returns a string representation of the specified NullValueTreatment 
+     * constant.  
+     * @param nullValueTreatment the null value treatment, one of 
+     * {@link #NONE}, {@link #EXCEPTION} or {@link #DEFAULT}
+     * @return the string representation of the NullValueTreatment constant
+     */
+    public static String toString(int nullValueTreatment) 
+    {
+        switch (nullValueTreatment) {
+        case NONE :
+            return "none"; //NOI18N
+        case EXCEPTION :
+            return "exception"; //NOI18N
+        case DEFAULT :
+            return "default"; //NOI18N
+        default:
+            return "UNSPECIFIED"; //NOI18N
+        }
+    }
+
+    /**
+     * Returns the NullValueTreatment constant for the string representation.
+     * @param nullValueTreatment the string representation of the null value
+     * treatment
+     * @return the null value treatment, one of {@link #NONE}, 
+     * {@link #EXCEPTION} or {@link #DEFAULT}
+     **/
+    public static int toNullValueTreatment(String nullValueTreatment)
+    {
+        if ((nullValueTreatment == null) || (nullValueTreatment.length() == 0))
+            return NONE;
+ 
+        if ("none".equals(nullValueTreatment)) //NOI18N
+            return NONE;
+        else if ("exception".equals(nullValueTreatment)) //NOI18N
+            return EXCEPTION;
+        else if ("default".equals(nullValueTreatment)) //NOI18N
+            return DEFAULT;
+        else
+            return NONE;
+    }
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/PersistenceModifier.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/PersistenceModifier.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/PersistenceModifier.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/PersistenceModifier.java Sun May 22 10:44:19 2005
@@ -0,0 +1,88 @@
+/*
+ * 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.model.jdo;
+
+/**
+ * This interface provides constants denoting JDO specific 
+ * modifiers for fields of a persistence-capable class.
+ *
+ * @author Michael Bouschen
+ */
+public class PersistenceModifier 
+{
+    /** Constant representing an unspecified field modifier */
+    public static final int UNSPECIFIED = 0;
+
+    /** Constant representing a none field modifier.  */
+    public static final int NONE = 1;
+
+    /** Constant representing a transactional field modifier. */
+    public static final int TRANSACTIONAL = 2;
+
+    /** Constant representing a persistence field modifier. */
+    public static final int PERSISTENT  = 4;
+
+    /** Constant representing a possibly persistence field modifier. */
+    public static final int POSSIBLY_PERSISTENT  = 8;
+
+    /**
+     * Returns a string representation of the specified persistence modifer. 
+     * @param persistenceModifier the persistence modifer, one of  
+     * {@link #UNSPECIFIED}, {@link #NONE}, {@link #PERSISTENT},
+     * {@link #TRANSACTIONAL}, or {@link #POSSIBLY_PERSISTENT}.
+     * @return the string representation of the PersistenceModifer constant
+     */
+    public static String toString(int persistenceModifier) 
+    {
+        switch (persistenceModifier) {
+        case NONE :
+            return "none"; //NOI18N
+        case TRANSACTIONAL :
+            return "transactional"; //NOI18N
+        case PERSISTENT:
+            return "persistent"; //NOI18N
+        case POSSIBLY_PERSISTENT:
+            return "possibly-persistent"; //NOI18N
+        default:
+            return "UNSPECIFIED"; //NOI18N
+        }
+    }
+    
+    /**
+     * Returns the PersistenceModifier constant for the specified string.
+     * @param persistenceModifier the string representation of the persistence 
+     * modifer
+     * @return the persistence modifer, one of {@link #UNSPECIFIED}, 
+     * {@link #NONE}, {@link #PERSISTENT} or {@link #TRANSACTIONAL}
+     **/
+    public static int toPersistenceModifier(String persistenceModifier)
+    {
+        if ((persistenceModifier == null) || (persistenceModifier.length() == 0))
+            return UNSPECIFIED;
+ 
+        if ("none".equals(persistenceModifier)) //NOI18N
+            return NONE;
+        else if ("transactional".equals(persistenceModifier)) //NOI18N
+            return TRANSACTIONAL;
+        else if ("persistent".equals(persistenceModifier)) //NOI18N
+            return PERSISTENT;
+        else if ("possibly-persistent".equals(persistenceModifier)) //NOI18N
+            return POSSIBLY_PERSISTENT;
+        else
+            return UNSPECIFIED;
+    }
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/package.html
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/package.html?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/package.html (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/jdo/package.html Sun May 22 10:44:19 2005
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+
+<html>
+<head>
+<title>JDOModel API package.</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="#FFFFFF">
+<p>This package defines the JDOModel API. 
+  It provides interfaces to access JDO metadata.
+</body>
+</html>

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/package.html
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/package.html?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/package.html (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/model/package.html Sun May 22 10:44:19 2005
@@ -0,0 +1,26 @@
+<!--
+ 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.
+-->
+
+<html>
+<head>
+<title>Package org.apache.jdo.model</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="#FFFFFF">
+<p>This package defines the Model Exception classes.</p>
+</body>
+</html>

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Bundle.properties
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Bundle.properties?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Bundle.properties (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Bundle.properties Sun May 22 10:44:19 2005
@@ -0,0 +1,51 @@
+#
+# 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.
+
+# This file should conform to netbeans standards
+# (http://www.netbeans.org/i18n)
+
+# resource bundle for the messages
+# key consists of: <PREFIX_><description>
+# <PREFIX_> - any valid prefix like MSG_, EXC_, etc.
+# <description> - short description started with the upper case letter and used
+# upper case to represent each next word.
+
+#
+# JDORIVersion
+#
+
+# Vendor Name
+MSG_VendorName=Sun Microsystems
+# Version Number
+MSG_VersionNumber=1.0.1
+# Displayed Version 
+MSG_DisplayVersion=Version: {0}
+
+#
+# Pool
+#
+EXC_CountOutOfRange=Invalid state: {0} is out of range 0 - {1}
+EXC_DuplicateObject=Illegal attempt to add an object to a Pool that is already there: {0}
+EXC_PoolGetTimeout=Timed out getting an entry from the pool.
+
+#
+# JDOJdk14Logger
+#
+EXC_LoggerSetupSecurityException=A SecurityException was thrown when trying \
+to read the logging configuration file ''{0}''. In order to configure JDK 1.4 \
+logging, you must grant java.util.logging.LoggingPermission("control") to the \
+codeBase containing the JDO Reference Implementation (jdo-ri.jar).
+EXC_LoggerSetupIOException=A IOException was thrown when trying to read the \
+logging configuration file ''{0}''.

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/I18NHelper.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/I18NHelper.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/I18NHelper.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/I18NHelper.java Sun May 22 10:44:19 2005
@@ -0,0 +1,376 @@
+/*
+ * 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.util;
+
+import java.util.*;
+import java.text.MessageFormat;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/** Helper class for constructing messages from bundles.  The intended usage
+ * of this class is to construct a new instance bound to a bundle, as in
+ * <P>
+ * <code>I18NHelper msg = I18NHelper.getInstance("org.apache.jdo.util.jdo.Bundle");</code>
+ * <P>
+ * This call uses the class loader that loaded the I18NHelper class to find
+ * the specified Bundle. The class provides two overloaded getInstance
+ * methods allowing to specify a different class loader: 
+ * {@link #getInstance(Class cls)} looks for a bundle
+ * called "Bundle.properties" located in the package of the specified class 
+ * object and {@link #getInstance(String bundleName,ClassLoader loader)} 
+ * uses the specified class loader to find the bundle.
+ * <P>
+ * Subsequently, instance methods can be used to format message strings 
+ * using the text from the bundle, as in 
+ * <P>
+ * <code>throw new JDOFatalInternalException (msg.msg("ERR_NoMetadata", cls.getName()));</code>
+ * @since 1.0.1
+ * @version 1.1
+ */        
+public class I18NHelper {
+
+    /** Bundles that have already been loaded 
+     */
+    private static Hashtable    bundles = new Hashtable();
+    
+    /** Helper instances that have already been created 
+     */
+    private static Hashtable    helpers = new Hashtable();
+    
+    /** The default locale for this VM.
+     */
+    private static Locale       locale = Locale.getDefault();
+
+    /** The name of the bundle used by this instance of the helper.
+     */
+    private final String        bundleName;
+
+    /** The bundle used by this instance of the helper.
+     */
+    private ResourceBundle      bundle = null;
+
+    /** Throwable if ResourceBundle couldn't be loaded
+     */
+    private Throwable           failure = null;
+
+    /** The unqualified standard name of a bundle. */
+    private static final String bundleSuffix = ".Bundle";    // NOI18N
+
+    /** Constructor */
+    private I18NHelper() {
+        this.bundleName = null;
+    }
+
+    /** Constructor for an instance bound to a bundle.
+     * @param bundleName the name of the resource bundle
+     * @param loader the class loader from which to load the resource
+     * bundle
+     */
+    private I18NHelper (String bundleName, ClassLoader loader) {
+        this.bundleName = bundleName;
+        try {
+            bundle = loadBundle (bundleName, loader);
+        }
+        catch (Throwable e) {
+            failure = e;
+        }
+    }
+    
+    /** An instance bound to a bundle. This method uses the current class 
+     * loader to find the bundle.
+     * @param bundleName the name of the bundle
+     * @return the helper instance bound to the bundle
+     */
+    public static I18NHelper getInstance (String bundleName) {
+        return getInstance (bundleName, I18NHelper.class.getClassLoader());
+    }
+
+    /** An instance bound to a bundle. This method figures out the bundle name
+     * for the class object's package and uses the class' class loader to
+     * find the bundle. Note, the specified class object must not be
+     * <code>null</code>.
+     * @param cls the class object from which to load the resource bundle
+     * @return the helper instance bound to the bundle
+     */
+    public static I18NHelper getInstance (final Class cls) {
+        ClassLoader classLoader = (ClassLoader) AccessController.doPrivileged (
+            new PrivilegedAction () {
+                public Object run () {
+                    return cls.getClassLoader();
+                }
+            }
+            );
+        String bundle = getPackageName (cls.getName()) + bundleSuffix;
+        return getInstance (bundle, classLoader);
+    }
+
+    /** An instance bound to a bundle. This method uses the specified class
+     * loader to find the bundle. Note, the specified class loader must not
+     * be <code>null</code>.
+     * @param bundleName the name of the bundle
+     * @param loader the class loader from which to load the resource
+     * bundle
+     * @return the helper instance bound to the bundle
+     */
+    public static I18NHelper getInstance (String bundleName, 
+                                          ClassLoader loader) {
+        I18NHelper helper = (I18NHelper) helpers.get (bundleName);
+        if (helper != null) {
+            return helper;
+        }
+        helper = new I18NHelper(bundleName, loader);
+        helpers.put (bundleName, helper);
+        // if two threads simultaneously create the same helper, return the first
+        // one to be put into the Hashtable.  The other will be garbage collected.
+        return (I18NHelper) helpers.get (bundleName);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @return the resolved message text
+     */
+    public String msg (String messageKey) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object arg1) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, arg1);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object arg1, Object arg2) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, arg1, arg2);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @param arg3 the third argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object arg1, Object arg2, Object arg3) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, arg1, arg2, arg3);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param args the array of arguments
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object[] args) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, args);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, int arg) {
+        assertBundle (messageKey);
+        return getMessage(bundle, messageKey, arg);
+    }
+    
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, boolean arg) {
+        assertBundle (messageKey);
+        return getMessage(bundle, messageKey, arg);
+    }
+    
+    /** Returns the resource bundle used by this I18NHelper.
+     * @return the associated resource bundle
+     * @since 1.1
+     */
+    public ResourceBundle getResourceBundle () {
+        assertBundle ();
+        return bundle;
+    }
+    
+    //========= Internal helper methods ==========
+
+    /**
+     * Load ResourceBundle by bundle name
+     * @param bundleName the name of the bundle
+     * @param loader the class loader from which to load the resource bundle
+     * @return  the ResourceBundle
+     */
+    final private static ResourceBundle loadBundle(
+        String bundleName, ClassLoader loader) {
+        ResourceBundle messages = (ResourceBundle)bundles.get(bundleName);
+
+        if (messages == null) //not found as loaded - add
+        {
+            messages = ResourceBundle.getBundle(bundleName, locale, loader);
+            bundles.put(bundleName, messages);
+        }
+        return messages;
+    }
+
+    /** Assert resources available
+     * @since 1.1
+     * @throws RuntimeException if the resource bundle could not
+     * be loaded during construction.
+     */
+    private void assertBundle () {
+        if (failure != null)
+            throw new RuntimeException (
+                "No resources could be found for bundle:\"" + 
+                bundle + "\" " + failure);
+    }
+    
+    /** Assert resources available
+     * @param key the message key 
+     * @since 1.0.2
+     * @throws RuntimeException if the resource bundle could not
+     * be loaded during construction.
+     */
+    private void assertBundle (String key) {
+        if (failure != null)
+            throw new RuntimeException (
+                "No resources could be found to annotate error message key:\"" + 
+                key + "\" " + failure);
+    }
+
+    /**
+     * Returns message as <code>String</code>
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey) 
+    {
+        return messages.getString(messageKey);
+    }
+
+    /**
+     * Formats message by adding array of arguments
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param msgArgs an array of arguments to substitute into the message
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey, Object msgArgs[]) 
+    {
+        for (int i=0; i<msgArgs.length; i++) {
+            if (msgArgs[i] == null) msgArgs[i] = ""; // NOI18N
+        }
+        MessageFormat formatter = new MessageFormat(messages.getString(messageKey));
+        return formatter.format(msgArgs);
+    }
+    
+    /**
+     * Formats message by adding an <code>Object</code> argument.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey, Object arg) 
+    {
+        Object []args = {arg};
+        return getMessage(messages, messageKey, args);
+    }
+    
+    /**
+     * Formats message by adding two <code>Object</code> arguments.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey, Object arg1,
+                                   Object arg2) 
+    {
+        Object []args = {arg1, arg2};
+        return getMessage(messages, messageKey, args);
+    }
+    
+    /**
+     * Formats message by adding three <code>Object</code> arguments.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @param arg3 the third argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey, Object arg1,
+                                   Object arg2, Object arg3) 
+    {
+        Object []args = {arg1, arg2, arg3};
+        return getMessage(messages, messageKey, args);
+    }
+
+    /**
+     * Formats message by adding an <code>int</code> as an argument.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey, int arg) 
+    {
+        Object []args = {new Integer(arg)};
+        return getMessage(messages, messageKey, args);
+    }
+    
+    /**
+     * Formats message by adding a <code>boolean</code> as an argument.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String messageKey, boolean arg) 
+    {
+        Object []args = {String.valueOf(arg)};
+        return getMessage(messages, messageKey, args);
+    }
+
+    /**  
+     * Returns the package portion of the specified class.
+     * @param className the name of the class from which to extract the 
+     * package 
+     * @return package portion of the specified class
+     */   
+    final private static String getPackageName(final String className)
+    { 
+        final int index = className.lastIndexOf('.');
+        return ((index != -1) ? className.substring(0, index) : ""); // NOI18N
+    }
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDOJdk14Logger.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDOJdk14Logger.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDOJdk14Logger.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDOJdk14Logger.java Sun May 22 10:44:19 2005
@@ -0,0 +1,91 @@
+/*
+ * 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.util;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.logging.LogManager;
+
+import org.apache.commons.logging.impl.Jdk14Logger;
+
+/**
+ * JDO-specific subclass of the apache commons logging Log
+ * implementation that wraps the standard JDK 1.4 logging.
+ * This class configures the JDK LogManager using a properties file
+ * called logging.properties found via the CLASSPATH.
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class JDOJdk14Logger
+    extends Jdk14Logger
+{
+    /** Logging properties file name. */
+    public static final String PROPERIES_FILE = "logging.properties";
+    
+    /** Indicates whether JDK 1.4 logging has been configured by this class. */
+    private static boolean configured = false;
+    
+    /** I18N support. */
+    private final static I18NHelper msg = 
+        I18NHelper.getInstance("org.apache.jdo.util.Bundle"); // NOI18N
+
+    /** 
+     * Constructor checking whether JDK 1.4 logging should be
+     * configuared after calling super constructor. 
+     */
+    public JDOJdk14Logger(String name) {
+        super(name);
+        if (!configured) {
+            configured = true;
+            configureJDK14Logger();
+        }
+    }
+
+    /** 
+     * Configures JDK 1.4 LogManager.
+     */
+    private void configureJDK14Logger() {
+        final LogManager logManager = LogManager.getLogManager();
+        final ClassLoader cl = getClass().getClassLoader();
+        AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run () {
+                try {
+                    InputStream config = cl.getResourceAsStream(PROPERIES_FILE);
+                    logManager.readConfiguration(config);
+                    return null;
+                }
+                catch (IOException ex) {
+                    throw new RuntimeException(
+                        msg.msg("EXC_LoggerSetupIOException", //NOI18N
+                                PROPERIES_FILE) + ex); 
+                }
+                catch (SecurityException ex) {
+                    throw new RuntimeException(
+                        msg.msg("EXC_LoggerSetupSecurityException", // NOI18N
+                                PROPERIES_FILE) + ex);
+                }
+            }
+            });
+    }
+    
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDORIVersion.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDORIVersion.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDORIVersion.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/JDORIVersion.java Sun May 22 10:44:19 2005
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+/*
+ * JDORIVersion.java
+ *
+ * Created on December 1, 2000
+ */
+
+package org.apache.jdo.util;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.io.InputStream;
+import java.io.FileNotFoundException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+/**
+ * Helper class to handle properties object with version number and vendor name.
+ *
+ * @author Marina Vatkina
+ */ 
+public class JDORIVersion {
+    private static Properties _properties	= null;
+    private final static String default_bundle  = "org.apache.jdo.util.Bundle"; // NOI18N
+    
+    private final static String  vendor_name_msg     	= "MSG_VendorName"; // NOI18N
+    private final static String  version_number_msg  	= "MSG_VersionNumber"; // NOI18N
+    
+    private final static String  vendor_name     	= "VendorName"; // NOI18N
+    private final static String  version_number  	= "VersionNumber"; // NOI18N
+    
+    private final static I18NHelper msg = I18NHelper.getInstance(default_bundle);
+    
+    private final static String vendor = msg.msg(vendor_name_msg);
+    private final static String version = msg.msg(version_number_msg);
+    
+    public static void main(String[] args) {
+    	if (args == null || args.length == 0 ||
+            (args.length == 1 && args[0].equals("-version")) ) { // NOI18N
+            System.out.println( msg.msg("MSG_DisplayVersion", version)); // NOI18N
+        }
+        System.exit(0);
+    }
+    
+    /**
+     * Constructor without parameters
+     */
+    public JDORIVersion() { 
+        loadProperties();
+    }
+    
+    /**
+     * Constructor without parameters
+     */
+    public JDORIVersion(String fileName) {
+        loadProperties(fileName);
+    }
+    
+    /**
+     * Load default properties 
+     */
+    private static void loadProperties() {
+        _properties = new Properties();
+        _properties.setProperty(vendor_name, vendor);
+        _properties.setProperty(version_number, version);
+    }
+    
+    /**
+     * Load specific properties file
+     */
+    private static void loadProperties(String fileName) {
+        Properties temp_properties = new Properties();
+        try {
+            InputStream in = JDORIVersion.class.getResourceAsStream(fileName);
+            if (in == null)
+                throw new java.io.FileNotFoundException(fileName);
+    
+            temp_properties.load(in);
+            in.close();
+        } catch (java.io.IOException e) {
+            throw new RuntimeException(e.toString());
+        }
+    
+        _properties = new Properties();
+        _properties.setProperty(vendor_name, temp_properties.getProperty(vendor_name));
+        _properties.setProperty(version_number, temp_properties.getProperty(version_number));
+    }
+    
+    /** 
+     * Return Vendor properties for a given file name
+     */
+    public static Properties getVendorProperties(String fileName) {
+        loadProperties(fileName);
+        return getVendorProperties();
+    }
+    
+    /** 
+     * Return Vendor properties
+     */
+    public synchronized static Properties getVendorProperties() {
+        if (_properties == null) {
+            loadProperties();
+        }
+        return _properties;
+    }
+    
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Pool.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Pool.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Pool.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/Pool.java Sun May 22 10:44:19 2005
@@ -0,0 +1,155 @@
+/*
+ * 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.util;
+
+import java.util.Stack;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+* A general purpose pooling class.
+*
+* @author Dave Bristor
+*/
+public class Pool {
+    // Objects in the pool
+    private final Stack stack = new Stack();
+
+    // Size of the pool
+    private final int size;
+
+    // Number of elements release by Pool for client use
+    private int count = 0;
+    
+    /** Number of millis to wait for a free entry
+     * Currently fixed; might be made configurable in future.
+     */
+    private int waitMillis = 1000;
+    
+    /** Number of times to wait for a free entry
+     * Currently fixed; might be made configurable in future.
+     */
+    private int waitNumber = 5;
+
+    /** I18N */
+    private final static I18NHelper msg = I18NHelper.getInstance("org.apache.jdo.util.Bundle"); // NOI18N
+
+    // For debugging TBD!!!
+    static final Log test = LogFactory.getFactory().getInstance(
+        "org.apache.jdo.util"); // NOI18N
+
+    /**
+     * Constructs a pool that will limit the number of objects which it can
+     * contain.
+     * @param size The maximum number of items that can be put into the pool.
+     */
+    public Pool(int size) {
+        this.size = size;
+    }
+
+    /**
+     * Puts the given object into the pool, if there the pool has fewer than
+     * the number of elements specifed when created.  If the pool is full,
+     * blocks until an element is removed. 
+     * @param o Object to be put in the pool.
+     * @throws InterruptedException
+     */
+    public synchronized void put(Object o) throws InterruptedException {
+       boolean debug = test.isDebugEnabled();
+        
+       if (debug) {
+           test.debug("Pool.put: " + o); // NOI18N
+       }
+       
+       if (count > size || count < 0) {
+           if (debug) {
+               test.debug("Pool: count " + count + // NOI18N
+                            " out of range 0-" + size); // NOI18N
+           }
+           throw new RuntimeException(
+               msg.msg(
+                   "EXC_CountOutOfRange", // NOI18N
+                   new Integer(count).toString(),
+                   new Integer(size).toString()));
+       }
+       
+       if (stack.contains(o)) {
+           if (debug) {
+               test.debug("Pool: duplicate object"); // NOI18N
+           }
+           throw new RuntimeException(
+               msg.msg(
+                   "EXC_DuplicateObject", o)); // NOI18N
+       }
+
+       while (count == size) {
+           if (debug) {
+               test.debug("Pool.put: block"); // NOI18N
+           }
+           wait();
+       }
+       stack.push(o);
+       ++count;
+       notify();
+    }
+
+    /**
+     * Gets an object from the pool, if one is available.  If an object is not
+     * available, waits until one is.  The waiting is governed by two
+     * variables, which are currently fixed: waitMillis and waitNumber.
+     * If no object is available from the pool within (waitNumber) times
+     * (waitMillis) milliseconds, then a RuntimeException is thrown.
+     * In future, the waitMillis and waitNumber should be configurable.
+     * @return An object from the pool.
+     */
+    public synchronized Object get() throws InterruptedException {
+        boolean debug = test.isDebugEnabled();
+        Object rc = null;
+
+        if (count > size || count < 0) {
+            if (debug) {
+                test.debug("Pool: count " + count + // NOI18N
+                           " out of range 0-" + size); // NOI18N
+            }
+            throw new RuntimeException(
+                msg.msg(
+                    "EXC_CountOutOfRange", // NOI18N
+                    new Integer(count).toString(),
+                    new Integer(size).toString()));
+        }
+
+        int timeouts = 0;
+        while (count == 0 && timeouts++ < waitNumber) {
+            if (debug) {
+                test.debug("Pool.get: block " + timeouts); // NOI18N
+            }
+            wait(waitMillis);
+        }
+        if (timeouts >= waitNumber) {
+            throw new RuntimeException(
+                msg.msg("EXC_PoolGetTimeout")); // NOI18N
+        }
+        rc = stack.pop();
+        --count;
+        notify();
+        if (debug) {
+            test.debug("Pool.get: " + rc); // NOI18N
+        }
+        return rc;
+    }
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakHashSet.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakHashSet.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakHashSet.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakHashSet.java Sun May 22 10:44:19 2005
@@ -0,0 +1,173 @@
+/*
+ * 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.util;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Iterator;
+
+/**
+ * A weak HashSet. An element stored in the WeakHashSet might be
+ * garbage collected, if there is no strong reference to this element.
+ */
+
+public class WeakHashSet extends HashSet {
+    /**
+     * Helps to detect garbage collected values.
+     */
+    ReferenceQueue queue = new ReferenceQueue();
+
+    /**
+     * Returns an iterator over the elements in this set.  The elements
+     * are returned in no particular order.
+     *
+     * @return an Iterator over the elements in this set.
+     */
+    public Iterator iterator() {
+        // remove garbage collected elements
+        processQueue();
+
+        // get an iterator of the superclass WeakHashSet
+        final Iterator i = super.iterator();
+
+        return new Iterator() {
+            public boolean hasNext() {
+                return i.hasNext();
+            }
+
+            public Object next() {
+                // unwrap the element
+                return getReferenceObject((WeakReference) i.next());
+            }
+
+            public void remove() {
+                // remove the element from the HashSet
+                i.remove();
+            }
+        };
+    }
+
+    /**
+     * Returns <code>true</code> if this set contains the specified element.
+     *
+     * @param o element whose presence in this set is to be tested.
+     * @return <code>true</code> if this set contains the specified element.
+     */
+    public boolean contains(Object o) {
+        return super.contains(WeakElement.create(o));
+    }
+
+    /**
+     * Adds the specified element to this set if it is not already
+     * present.
+     *
+     * @param o element to be added to this set.
+     * @return <code>true</code> if the set did not already contain the specified
+     * element.
+     */
+    public boolean add(Object o) {
+        processQueue();
+        return super.add(WeakElement.create(o, this.queue));
+    }
+
+    /**
+     * Removes the given element from this set if it is present.
+     *
+     * @param o object to be removed from this set, if present.
+     * @return <code>true</code> if the set contained the specified element.
+     */
+    public boolean remove(Object o) {
+        boolean ret = super.remove(WeakElement.create(o));
+        processQueue();
+        return ret;
+    }
+
+    /**
+     * A convenience method to return the object held by the
+     * weak reference or <code>null</code> if it does not exist.
+     */
+    private final Object getReferenceObject(WeakReference ref) {
+        return (ref == null) ? null : ref.get();
+    }
+
+    /**
+     * Removes all garbage collected values with their keys from the map.
+     * Since we don't know how much the ReferenceQueue.poll() operation
+     * costs, we should call it only in the add() method.
+     */
+    private final void processQueue() {
+        WeakElement wv = null;
+
+        while ((wv = (WeakElement) this.queue.poll()) != null) {
+            super.remove(wv);
+        }
+    }
+
+    /**
+     * A WeakHashSet stores objects of class WeakElement.
+     * A WeakElement wraps the element that should be stored in the WeakHashSet.
+     * WeakElement inherits from java.lang.ref.WeakReference.
+     * It redefines equals and hashCode which delegate to the corresponding methods
+     * of the wrapped element.
+     */
+    static private class WeakElement extends WeakReference {
+        private int hash;	/* Hashcode of key, stored here since the key
+                               may be tossed by the GC */
+
+        private WeakElement(Object o) {
+            super(o);
+            hash = o.hashCode();
+        }
+
+        private WeakElement(Object o, ReferenceQueue q) {
+            super(o, q);
+            hash = o.hashCode();
+        }
+
+        private static WeakElement create(Object o) {
+            return (o == null) ? null : new WeakElement(o);
+        }
+
+        private static WeakElement create(Object o, ReferenceQueue q) {
+            return (o == null) ? null : new WeakElement(o, q);
+        }
+
+        /* A WeakElement is equal to another WeakElement iff they both refer to objects
+               that are, in turn, equal according to their own equals methods */
+        public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (!(o instanceof WeakElement))
+                return false;
+            Object t = this.get();
+            Object u = ((WeakElement) o).get();
+            if (t == u) 
+                return true;
+            if ((t == null) || (u == null))
+                return false;
+            return t.equals(u);
+        }
+
+        public int hashCode() {
+            return hash;
+        }
+    }
+
+}
+
+

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakValueHashMap.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakValueHashMap.java?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakValueHashMap.java (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/WeakValueHashMap.java Sun May 22 10:44:19 2005
@@ -0,0 +1,440 @@
+/*
+ * 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.util;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * A WeakValueHashMap is implemented as a HashMap that maps keys to
+ * WeakValues.  Because we don't have access to the innards of the
+ * HashMap, we have to wrap/unwrap value objects with WeakValues on
+ * every operation.  Fortunately WeakValues are small, short-lived
+ * objects, so the added allocation overhead is tolerable. This
+ * implementaton directly extends java.util.HashMap.
+ *
+ * @author	Markus Fuchs
+ * @see		java.util.HashMap
+ * @see         java.lang.ref.WeakReference
+ */
+
+public class WeakValueHashMap extends HashMap {
+
+    /* Reference queue for cleared WeakValues */
+    private ReferenceQueue queue = new ReferenceQueue();
+
+    /**
+     * Returns the number of key-value mappings in this map.<p>
+     * @return the number of key-value mappings in this map.
+     */
+    public int size() {
+        // delegate to entrySet, as super.size() also counts WeakValues
+        return entrySet().size();
+    }
+
+    /**
+     * Returns <tt>true</tt> if this map contains no key-value mappings.<p>
+     * @return <tt>true</tt> if this map contains no key-value mappings.
+     */
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * Returns <tt>true</tt> if this map contains a mapping for the specified
+     * key.<p>
+     * @param key key whose presence in this map is to be tested
+     * @return <tt>true</tt> if this map contains a mapping for the specified
+     * key.
+     */
+    public boolean containsKey(Object key) {
+        // need to clean up gc'ed values before invoking super method
+        processQueue();
+        return super.containsKey(key);
+    }
+
+   /**
+     * Returns <tt>true</tt> if this map maps one or more keys to the
+     * specified value.<p>
+     * @param value value whose presence in this map is to be tested
+     * @return <tt>true</tt> if this map maps one or more keys to this value.
+     */
+    public boolean containsValue(Object value) {
+        return super.containsValue(WeakValue.create(value));
+    }
+
+    /**
+     * Gets the value for the given key.<p>
+     * @param key key whose associated value, if any, is to be returned
+     * @return the value to which this map maps the specified key.
+     */
+    public Object get(Object key) {
+        // We don't need to remove garbage collected values here;
+        // if they are garbage collected, the get() method returns null;
+        // the next put() call with the same key removes the old value
+        // automatically so that it can be completely garbage collected
+        return getReferenceObject((WeakReference) super.get(key));
+    }
+
+    /**
+     * Puts a new (key,value) into the map.<p>
+     * @param key key with which the specified value is to be associated.
+     * @param value value to be associated with the specified key.
+     * @return previous value associated with specified key, or null
+     * if there was no mapping for key or the value has been garbage
+     * collected by the garbage collector.
+     */
+    public Object put(Object key, Object value) {
+        // If the map already contains an equivalent key, the new key
+        // of a (key, value) pair is NOT stored in the map but the new
+        // value only. But as the key is strongly referenced by the
+        // map, it can not be removed from the garbage collector, even
+        // if the key becomes weakly reachable due to the old
+        // value. So, it isn't necessary to remove all garbage
+        // collected values with their keys from the map before the
+        // new entry is made. We only clean up here to distribute
+        // clean up calls on different operations.
+        processQueue();
+
+        WeakValue oldValue = 
+            (WeakValue)super.put(key, WeakValue.create(key, value, queue));
+        return getReferenceObject(oldValue);
+    }
+
+    /**
+     * Removes key and value for the given key.<p>
+     * @param key key whose mapping is to be removed from the map.
+     * @return previous value associated with specified key, or null
+     * if there was no mapping for key or the value has been garbage
+     * collected by the garbage collector.
+     */
+    public Object remove(Object key) {
+        return getReferenceObject((WeakReference) super.remove(key));
+    }
+
+    /**
+     * A convenience method to return the object held by the
+     * weak reference or <code>null</code> if it does not exist.
+     */
+    private final Object getReferenceObject(WeakReference ref) {
+        return (ref == null) ? null : ref.get();
+    }
+
+    /**
+     * Removes all garbage collected values with their keys from the map.
+     * Since we don't know how much the ReferenceQueue.poll() operation
+     * costs, we should not call it every map operation.
+     */
+    private void processQueue() {
+        WeakValue wv = null;
+
+        while ((wv = (WeakValue) this.queue.poll()) != null) {
+            // "super" is not really necessary but use it
+            // to be on the safe side
+            super.remove(wv.key);
+        }
+    }
+
+    /* -- Helper classes -- */
+
+    /**
+     * We need this special class to keep the backward reference from
+     * the value to the key, so that we are able to remove the key if
+     * the value is garbage collected.
+     */
+    private static class WeakValue extends WeakReference {
+        /**
+         * It's the same as the key in the map. We need the key to remove
+         * the value if it is garbage collected.
+         */
+        private Object key;
+
+        private WeakValue(Object value) {
+            super(value);
+        }
+
+        /**
+         * Creates a new weak reference without adding it to a
+         * ReferenceQueue.
+         */
+	private static WeakValue create(Object value) {
+	    if (value == null) return null;
+	    else return new WeakValue(value);
+        }
+
+        private WeakValue(Object key, Object value, ReferenceQueue queue) {
+            super(value, queue);
+            this.key = key;
+        }
+
+        /**
+         * Creates a new weak reference and adds it to the given queue.
+         */
+        private static WeakValue create(Object key, Object value, 
+                                        ReferenceQueue queue) {
+	    if (value == null) return null;
+	    else return new WeakValue(key, value, queue);
+        }
+
+        /**
+         * A WeakValue is equal to another WeakValue iff they both refer
+         * to objects that are, in turn, equal according to their own
+         * equals methods.
+         */
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+
+            if (!(obj instanceof WeakValue))
+                return false;
+
+            Object ref1 = this.get();
+            Object ref2 = ((WeakValue) obj).get();
+
+            if (ref1 == ref2)
+                return true;
+
+            if ((ref1 == null) || (ref2 == null))
+                return false;
+
+            return ref1.equals(ref2);
+        }
+
+        /**
+         *
+         */
+        public int hashCode() {
+            Object ref = this.get();
+
+            return (ref == null) ? 0 : ref.hashCode();
+        }
+    }
+
+    /** 
+     * Internal class for entries. This class wraps/unwraps the
+     * values of the Entry objects returned from the underlying map.
+     */
+    private class Entry implements Map.Entry {
+        private Map.Entry ent;
+        private Object value;	/* Strong reference to value, so that the
+				   GC will leave it alone as long as this
+				   Entry exists */
+
+        Entry(Map.Entry ent, Object value) {
+            this.ent = ent;
+            this.value = value;
+        }
+
+        public Object getKey() {
+            return ent.getKey();
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object setValue(Object value) {
+            // This call changes the map. Please see the comment on 
+            // the put method for the correctness remark.
+            Object oldValue = this.value;
+            this.value = value;
+            ent.setValue(WeakValue.create(getKey(), value, queue));
+            return oldValue;
+        }
+
+        private boolean valEquals(Object o1, Object o2) {
+            return (o1 == null) ? (o2 == null) : o1.equals(o2);
+        }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof Map.Entry)) return false;
+            Map.Entry e = (Map.Entry) o;
+            return (valEquals(ent.getKey(), e.getKey())
+                    && valEquals(value, e.getValue()));
+        }
+
+        public int hashCode() {
+            Object k;
+            return ((((k = ent.getKey()) == null) ? 0 : k.hashCode())
+                    ^ ((value == null) ? 0 : value.hashCode()));
+        }
+
+    }
+
+    /**
+     * Internal class for entry sets to unwrap/wrap WeakValues stored
+     * in the map.
+     */
+    private class EntrySet extends AbstractSet {
+
+        public Iterator iterator() {
+            // remove garbage collected elements
+            processQueue();
+
+            return new Iterator() {
+                Iterator hashIterator = hashEntrySet.iterator();
+                Entry next = null;
+
+                public boolean hasNext() {
+                    if (hashIterator.hasNext()) {
+                        // since we removed garbage collected elements,
+                        // we can simply return the next entry.
+                        Map.Entry ent = (Map.Entry) hashIterator.next();
+                        WeakValue wv = (WeakValue) ent.getValue();
+                        Object v = (wv == null) ? null : wv.get();
+                        next = new Entry(ent, v);
+                        return true;
+                    }
+                    return false;
+                }
+
+                public Object next() {
+                    if ((next == null) && !hasNext())
+                        throw new NoSuchElementException();
+                    Entry e = next;
+                    next = null;
+                    return e;
+                }
+
+                public void remove() {
+                    hashIterator.remove();
+                }
+
+            };
+        }
+
+        public boolean isEmpty() {
+            return !(iterator().hasNext());
+        }
+
+        public int size() {
+            int j = 0;
+            for (Iterator i = iterator(); i.hasNext(); i.next()) j++;
+            return j;
+        }
+
+        public boolean remove(Object o) {
+            if (!(o instanceof Map.Entry)) return false;
+            Map.Entry e = (Map.Entry) o;
+            Object ek = e.getKey();
+            Object ev = e.getValue();
+            Object hv = WeakValueHashMap.this.get(ek);
+            if (hv == null) {
+                // if the map's value is null, we have to check, if the
+                // entry's value is null and the map contains the key
+                if ((ev == null) && WeakValueHashMap.this.containsKey(ek)) {
+                    WeakValueHashMap.this.remove(ek);
+                    return true;
+                } else {
+                    return false;
+                }
+                // otherwise, simply compare the values
+            } else if (hv.equals(ev)) {
+                WeakValueHashMap.this.remove(ek);
+                return true;
+            }                
+                
+            return false;
+        }
+
+        public int hashCode() {
+            int h = 0;
+            for (Iterator i = hashEntrySet.iterator(); i.hasNext(); ) {
+                Map.Entry ent = (Map.Entry) i.next();
+                Object k;
+                WeakValue wv = (WeakValue) ent.getValue();
+                if (wv == null) continue;
+                h += ((((k = ent.getKey()) == null) ? 0 : k.hashCode())
+                        ^ wv.hashCode());
+            }
+            return h;
+        }
+
+    }
+
+    // internal helper variable, because we can't access
+    // entrySet from the superclass inside the EntrySet class
+    private Set hashEntrySet = null;
+    // stores the EntrySet instance
+    private Set entrySet = null;
+
+    /**
+     * Returns a <code>Set</code> view of the mappings in this map.<p>
+     * @return a <code>Set</code> view of the mappings in this map.
+     */
+    public Set entrySet() {
+        if (entrySet == null) {
+            hashEntrySet = super.entrySet();
+            entrySet = new EntrySet();
+        }
+        return entrySet;
+    }
+
+    // stores the value collection
+    private transient Collection values = null;
+
+    /**
+     * Returns a <code>Collection</code> view of the values contained
+     * in this map.<p>
+     * @return a <code>Collection</code> view of the values contained
+     * in this map.
+     */
+    public Collection values() {
+        // delegates to entrySet, because super method returns
+        // WeakValues instead of value objects
+	if (values == null) {
+	    values = new AbstractCollection() {
+		public Iterator iterator() {
+		    return new Iterator() {
+			private Iterator i = entrySet().iterator();
+
+			public boolean hasNext() {
+			    return i.hasNext();
+			}
+
+			public Object next() {
+			    return ((Entry)i.next()).getValue();
+			}
+
+			public void remove() {
+			    i.remove();
+			}
+                    };
+                }
+
+		public int size() {
+		    return WeakValueHashMap.this.size();
+		}
+
+		public boolean contains(Object v) {
+		    return WeakValueHashMap.this.containsValue(v);
+		}
+	    };
+	}
+	return values;
+    }
+
+}

Added: incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/package.html
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/package.html?rev=171348&view=auto
==============================================================================
--- incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/package.html (added)
+++ incubator/jdo/trunk/core20/src/java/org/apache/jdo/util/package.html Sun May 22 10:44:19 2005
@@ -0,0 +1,26 @@
+<!--
+ 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.
+-->
+
+<html>
+<head>
+<title>Package org.apache.jdo.ejb</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
+</head>
+
+<body bgcolor="#FFFFFF">
+<p>This package contains utility classes used across the JDORI including I18N support, Logger.</p>
+</body>
+</html>