You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/06/23 23:04:35 UTC

svn commit: r787832 [5/6] - in /openjpa/trunk: ./ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-persistence-jdbc/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/ openjpa-persistence-jdbc/src/test/java/...

Added: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java?rev=787832&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java (added)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java Tue Jun 23 21:04:32 2009
@@ -0,0 +1,1031 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.PluralAttribute.CollectionType;
+
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+
+/**
+ * Implements the managed persistent type and its attributes.
+ * 
+ * Provides identity and version attribute facilities for Identifiable type but does not
+ * implement it.
+ * 
+ * @author Pinaki Poddar
+ *
+ * @param <X> the 
+ */
+public abstract class AbstractManagedType<X> extends Types.BaseType<X> 
+    implements ManagedType<X> {
+    
+    private static final Localizer _loc = Localizer.forPackage(Types.class);
+    public final MetamodelImpl model;
+    public final ClassMetaData meta;
+
+    private java.util.Set<Attribute<? super X, ?>> attrs = new HashSet<Attribute<? super X, ?>>();
+
+    private final DeclaredAttributeFilter<X> declaredAttributeFilter;
+    private final SingularAttributeFilter<X> singularAttributeFilter;
+    private final SingularAttributeFilter<X> pluralAttributeFilter;
+    
+    /**
+     * Construct a managed type. The supplied metadata must be resolved i.e. all
+     * its fields populated. Because this receiver will populate its attributes
+     * corresponding to the available fields of the metadata.
+     * 
+     */
+    public AbstractManagedType(ClassMetaData meta, MetamodelImpl model) {
+        super((Class<X>) meta.getDescribedType());
+
+        this.model = model;
+        this.meta = meta;
+        FieldMetaData[] fmds = meta.getFields();
+        for (FieldMetaData f : fmds) {
+            int decCode = f.getDeclaredTypeCode();
+            switch (decCode) {
+            case JavaTypes.BOOLEAN:
+            case JavaTypes.BOOLEAN_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Boolean>(this, f));
+                break;
+            case JavaTypes.BYTE:
+            case JavaTypes.BYTE_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Byte>(this, f));
+                break;
+            case JavaTypes.CHAR:
+            case JavaTypes.CHAR_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Character>(this, f));
+                break;
+            case JavaTypes.DOUBLE:
+            case JavaTypes.DOUBLE_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Double>(this, f));
+                break;
+            case JavaTypes.FLOAT:
+            case JavaTypes.FLOAT_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Float>(this, f));
+                break;
+            case JavaTypes.INT:
+            case JavaTypes.INT_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Integer>(this, f));
+                break;
+            case JavaTypes.LONG:
+            case JavaTypes.LONG_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Long>(this, f));
+                break;
+            case JavaTypes.SHORT:
+            case JavaTypes.SHORT_OBJ:
+                attrs.add(new Members.SingularAttributeImpl<X, Short>(this, f));
+                break;
+            case JavaTypes.STRING:
+                attrs.add(new Members.SingularAttributeImpl<X, String>(this, f));
+                break;
+            case JavaTypes.NUMBER:
+                attrs.add(new Members.SingularAttributeImpl<X, Number>(this, f));
+                break;
+            case JavaTypes.DATE:
+                attrs.add(new Members.SingularAttributeImpl<X, Date>(this, f));
+                break;
+            case JavaTypes.CALENDAR:
+                attrs.add(new Members.SingularAttributeImpl<X, Calendar>(this, f));
+                break;
+            case JavaTypes.BIGDECIMAL:
+                attrs.add(new Members.SingularAttributeImpl<X, BigDecimal>(this, f));
+                break;
+            case JavaTypes.BIGINTEGER:
+                attrs.add(new Members.SingularAttributeImpl<X, BigInteger>(this, f));
+                break;
+            case JavaTypes.LOCALE:
+                attrs.add(new Members.SingularAttributeImpl<X, Locale>(this, f));
+                break;
+            case JavaTypes.OBJECT:
+            case JavaTypes.OID:
+            case JavaTypes.PC:
+                attrs.add(new Members.SingularAttributeImpl(this, f));
+                break;
+            case JavaTypes.ARRAY:
+                attrs.add(new Members.ListAttributeImpl(this, f));
+                break;
+            case JavaTypes.COLLECTION:
+                switch (MetamodelImpl.categorizeCollection(f.getDeclaredType())) {
+                case COLLECTION:
+                    attrs.add(new Members.CollectionAttributeImpl(this, f));
+                    break;
+                case LIST:
+                    attrs.add(new Members.ListAttributeImpl(this, f));
+                    break;
+                case SET:
+                    attrs.add(new Members.SetAttributeImpl(this, f));
+                    break;
+                }
+                break;
+            case JavaTypes.MAP:
+                attrs.add(new Members.MapAttributeImpl(this, f));
+                break;
+            default:
+                throw new IllegalStateException(_loc.get("field-unrecognized",
+                        f.getFullName(false), decCode).getMessage());
+            }
+            // TODO: Account for the following codes
+            // case PC_UNTYPED = 27;
+            // case INPUT_STREAM = 30;
+            // case INPUT_READER = 31;
+        }
+        declaredAttributeFilter = new DeclaredAttributeFilter<X>(this);
+        singularAttributeFilter = new SingularAttributeFilter<X>();
+        pluralAttributeFilter = new SingularAttributeFilter<X>().inverse();
+    }
+
+    /**
+     * Returns all the attributes of the managed type including attributes of the super type.
+     * 
+     */
+    public java.util.Set<Attribute<? super X, ?>> getAttributes() {
+        return Collections.unmodifiableSet(attrs);
+    }
+
+    /**
+     * Returns all the attributes declared by this managed type only.
+     * 
+     */
+    public java.util.Set<Attribute<X, ?>> getDeclaredAttributes() {
+        return filter(attrs, new HashSet<Attribute<X, ?>>(),
+                declaredAttributeFilter);
+    }
+
+    /**
+     * Returns the single-valued attributes of the managed type.
+     * 
+     */
+    public java.util.Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
+        return filter(attrs, new HashSet<SingularAttribute<? super X, ?>>(),
+                singularAttributeFilter);
+    }
+
+    /**
+     * Returns the single-valued attributes declared by the managed type.
+     * 
+     */
+    public java.util.Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
+        return filter(attrs, new HashSet<SingularAttribute<X, ?>>(),
+                declaredAttributeFilter, 
+                singularAttributeFilter);
+    }
+
+    /**
+     * Returns the attribute of the given name and Java type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <Y> Attribute<? super X, Y> getAttribute(String name, Class<Y> type) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new AttributeNameFilter<X>(name),
+                new AttributeTypeFilter<X, Y>(type));
+        if (result == null)
+            notFoundException("attr-not-found", name, type);
+        
+        return (Attribute<? super X, Y>)result;
+    }
+    
+    /**
+     * Returns the single-valued attribute of the given name and Java type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new AttributeNameFilter<X>(name),
+                new AttributeTypeFilter<X, Y>(type), 
+                singularAttributeFilter);
+        if (result == null)
+            notFoundException("attr-not-found-single",name, type);
+         
+        return (SingularAttribute<? super X, Y>) result;
+    }
+    
+    /**
+     * Returns the declared attribute of the given name and Java type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <Y> Attribute<X, Y> getDeclaredAttribute(String name, Class<Y> type) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new AttributeNameFilter<X>(name),
+                new AttributeTypeFilter<X, Y>(type), 
+                declaredAttributeFilter);
+        if (result == null)
+            notFoundException("attr-not-found-decl-single",name, type);
+            
+        return (Attribute<X, Y>) result;
+    }
+
+    /**
+     * Returns the declared single-valued attribute of the given name and Java type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> type) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new AttributeNameFilter<X>(name),
+                new AttributeTypeFilter<X, Y>(type), 
+                declaredAttributeFilter,
+                singularAttributeFilter);
+        if (result == null)
+            notFoundException("attr-not-found-decl-single",name, type);
+
+        return (SingularAttribute<X, Y>) result;
+    }
+
+    /**
+     * Returns all collection-valued attributes of the managed type.
+     * 
+     */
+    public java.util.Set<PluralAttribute<? super X, ?, ?>> getCollections() {
+        return filter(attrs, new HashSet<PluralAttribute<? super X, ?, ?>>(),
+                pluralAttributeFilter);
+    }
+
+    /**
+     * Return all collection-valued attributes declared by the managed type.
+     * 
+     */
+    public java.util.Set<PluralAttribute<X, ?, ?>> getDeclaredCollections() {
+        return filter(attrs, new HashSet<PluralAttribute<X, ?, ?>>(),
+                declaredAttributeFilter, 
+                pluralAttributeFilter);
+    }
+
+    /**
+     * Returns the attribute of the given name, of type java.util.Collection and contains the
+     * given element type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new PluralCategoryFilter<X>(CollectionType.COLLECTION),
+                new ElementTypeFilter<X, E>(elementType),
+                new AttributeNameFilter<X>(name));
+        if (result == null)
+            notFoundException("attr-not-found-coll",name, elementType);
+
+        return (CollectionAttribute<? super X, E>) result;
+    }
+
+    /**
+     * Returns the attribute of the given name, of type java.util.Set and contains the
+     * given element type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new PluralCategoryFilter<X>(CollectionType.SET),
+                new ElementTypeFilter<X, E>(elementType),
+                new AttributeNameFilter<X>(name));
+        if (result == null)
+            notFoundException("attr-not-found-set",name, elementType);
+
+        return (SetAttribute<? super X, E>) result;
+    }
+
+    /**
+     * Returns the attribute of the given name, of type java.util.List and contains the
+     * given element type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new PluralCategoryFilter<X>(CollectionType.LIST),
+                new ElementTypeFilter<X, E>(elementType),
+                new AttributeNameFilter<X>(name));
+        if (result == null)
+            notFoundException("attr-not-found-list",name, elementType);
+
+        return (ListAttribute<? super X, E>) result;
+    }
+
+    /**
+     * Returns the attribute of the given name, of type java.util.Map and contains the
+     * given key/value type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, 
+        Class<V> valueType) {
+        Attribute<? super X, ?> result = pick(attrs,
+                new AttributeNameFilter<X>(name),
+                new PluralCategoryFilter<X>(CollectionType.MAP),
+                new EntryTypeFilter<X, K, V>(keyType, valueType));
+        if (result == null)
+            notFoundException("attr-not-found-map", name, keyType, valueType);
+
+        return (MapAttribute<? super X, K, V>) result;
+    }
+
+    /**
+     * Returns the declared attribute of the given name, of type java.util.Collection and contains 
+     * the given element type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <E> CollectionAttribute<X, E> getDeclaredCollection(String name,  Class<E> elementType) {
+        Attribute<? super X, ?> result = pick(attrs, 
+                declaredAttributeFilter,
+                new PluralCategoryFilter<X>(CollectionType.COLLECTION),
+                new ElementTypeFilter<X, E>(elementType),
+                new AttributeNameFilter<X>(name));
+        if (result == null)
+            notFoundException("attr-not-found-decl-coll", name, elementType);
+
+        return (CollectionAttribute<X, E>) result;
+    }
+
+    /**
+     * Returns the declared attribute of the given name, of type java.util.Set and contains 
+     * the given element type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
+        Attribute<? super X, ?> result = pick(attrs, 
+                declaredAttributeFilter,
+                new PluralCategoryFilter<X>(CollectionType.SET),
+                new AttributeNameFilter<X>(name));
+        if (result == null)
+            notFoundException("attr-not-found-decl-set", name, elementType);
+
+        return (SetAttribute<X, E>) result;
+    }
+
+    /**
+     * Returns the declared attribute of the given name, of type java.util.List and contains 
+     * the given element type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
+        Attribute<? super X, ?> result = pick(attrs, 
+                declaredAttributeFilter,
+                new PluralCategoryFilter<X>(CollectionType.LIST),
+                new ElementTypeFilter<X, E>(elementType),
+                new AttributeNameFilter<X>(name));
+        if (result == null)
+            notFoundException("attr-not-found-decl-list", name, elementType);
+
+        return (ListAttribute<X, E>) result;
+    }
+
+    /**
+     * Returns the declared attribute of the given name, of type java.util.Map and contains 
+     * the given key/value type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, 
+        Class<V> valueType) {
+        Attribute<? super X, ?> result = pick(attrs,
+                declaredAttributeFilter,
+                new AttributeNameFilter<X>(name),
+                new PluralCategoryFilter<X>(CollectionType.MAP),
+                new EntryTypeFilter<X, K, V>(keyType, valueType));
+        if (result == null)
+            notFoundException("attr-not-found-decl-map", name, keyType, valueType);
+
+        return (MapAttribute<X, K, V>) result;
+    }
+
+    // ==============================================================================
+    // No type checking
+    // ==============================================================================
+    
+    /**
+     * Returns the attribute of the given name of any type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public Attribute<? super X, ?> getAttribute(String name) {
+        return getAttribute(name, null);
+    }
+
+    /**
+     * Returns the declared attribute of the given name of any type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public Attribute<X, ?> getDeclaredAttribute(String name) {
+        return getDeclaredAttribute(name, null);
+    }
+
+    /**
+     * Returns the single-valued attribute of the given name of any type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
+        return getSingularAttribute(name, null);
+    }
+
+    /**
+     * Returns the declared, single-valued attribute of the given name of any type.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
+        return getDeclaredSingularAttribute(name, null);
+    }
+
+    /**
+     * Returns the attribute of the given name and of type java.util.Collection.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public CollectionAttribute<? super X, ?> getCollection(String name) {
+        return getCollection(name, null);
+    }
+
+    /**
+     * Returns the attribute of the given name and of type java.util.Set.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public SetAttribute<? super X, ?> getSet(String name) {
+        return getSet(name, null);
+    }
+
+    /**
+     * Returns the attribute of the given name and of type java.util.List.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public ListAttribute<? super X, ?> getList(String name) {
+        return getList(name, null);
+    }
+
+    /**
+     * Returns the attribute of the given name and of type java.util.Map.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public MapAttribute<? super X, ?, ?> getMap(String name) {
+        return getMap(name, null, null);
+    }
+
+    /**
+     * Returns the declared attribute of the given name and of type java.util.Collection.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
+        return getDeclaredCollection(name, null);
+    }
+
+    /**
+     * Returns the declared attribute of the given name and of type java.util.Set.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public SetAttribute<X, ?> getDeclaredSet(String name) {
+        return getDeclaredSet(name, null);
+    }
+
+    /**
+     * Returns the declared attribute of the given name and of type java.util.List.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public ListAttribute<X, ?> getDeclaredList(String name) {
+        return getDeclaredList(name, null);
+    }
+
+    /**
+     * Returns the declared attribute of the given name and of type java.util.Map.
+     * 
+     * @throws IllegalArgumentException  if no such attribute exists
+     */
+    public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
+        return getDeclaredMap(name, null, null);
+    }
+
+    //--------------------------------------------------------------------------
+    // Primary Key and Version Attribute related functions
+    //--------------------------------------------------------------------------
+    /**
+     *   Returns the attributes corresponding to the id class of the identifiable type.
+     *   
+     *   @throws IllegalArgumentException if the this type is not using an id class
+     */
+    public final java.util.Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
+        if (meta.isOpenJPAIdentity())
+            throw new IllegalArgumentException(meta + " does not use IdClass. Object Id type = " + 
+                meta.getObjectIdType() + " Identity Type = " + meta.getIdentityType());
+        return filter(attrs, new HashSet<SingularAttribute<? super X, ?>>(),
+                new IdAttributeFilter<X>());
+    }
+    
+    /**
+     *  Returns the attribute of given type that corresponds to the id attribute of this 
+     *  identifiable managed type.
+     *  
+     *  @throws IllegalArgumentException if no such attribute exists
+     */
+     public final <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
+         Attribute<? super X, ?> result =  pick(attrs, 
+                 new AttributeTypeFilter<X, Y>(type), 
+                 new IdAttributeFilter<X>());
+         if (result != null)
+             return (SingularAttribute<? super X, Y>) result;
+         throw new IllegalArgumentException();
+     }
+     
+     /**
+      *  Returns the declared attribute of given type that corresponds to the id attribute of this 
+      *  identifiable managed type.
+      *  
+      *  @throws IllegalArgumentException if no such attribute exists
+      */
+     public final <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> type) {
+         Attribute<? super X, ?> result =  pick(attrs, 
+                 declaredAttributeFilter,
+                 new AttributeTypeFilter<X, Y>(type), 
+                 new IdAttributeFilter<X>());
+         if (result != null)
+             return (SingularAttribute<X, Y>) result;
+         throw new IllegalArgumentException();
+     }
+     
+     /**
+      *  Returns the attribute of given type that corresponds to the version attribute of this 
+      *  managed type.
+      *  
+      *  @throws IllegalArgumentException if no such attribute exists
+      */
+     public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
+         Attribute<? super X, ?> result = pick(attrs, 
+                 new VersionAttributeFilter<X>(), 
+                 new AttributeTypeFilter<X,Y>(type));
+         if (result == null) 
+             notFoundException("version-not-found", "", type);
+         return (SingularAttribute<? super X, Y>)result;
+     }
+
+     /**
+      *  Returns the declared attribute of given type that corresponds to the version attribute of 
+      *  this managed type.
+      *  
+      *  @throws IllegalArgumentException if no such attribute exists
+      */
+     public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
+         Attribute<? super X, ?> result = pick(attrs,
+                 declaredAttributeFilter,
+                 new VersionAttributeFilter<X>(), 
+                 new AttributeTypeFilter<X,Y>(type));
+         if (result == null) 
+             notFoundException("decl-version-not-found", "", type);
+         return (SingularAttribute<X, Y>)result;
+     }
+
+    // =====================================================================
+    // Support functions
+    // =====================================================================
+
+    FieldMetaData getField(String name) {
+        return getField(name, null, null, null, false);
+    }
+
+    FieldMetaData getField(String name, Class type) {
+        return getField(name, type, null, null, false);
+    }
+
+    FieldMetaData getField(String name, Class type, boolean declaredOnly) {
+        return getField(name, type, null, null, declaredOnly);
+    }
+
+    /**
+     * Get the field of the given name after validating the conditions. null
+     * value on any condition implies not to validate.
+     * 
+     * @param name simple name i.e. without the class name
+     * @param type the expected type of the field.
+     * @param element
+     *            the expected element type of the field.
+     * @param key
+     *            the expected key type of the field.
+     * @param declared
+     *            is this field declared in this receiver
+     * 
+     * @exception IllegalArgumentException
+     *                if any of the validation fails.
+     * 
+     */
+    FieldMetaData getField(String name, Class<?> type, Class<?> elementType,
+            Class<?> keyType, boolean decl) {
+        FieldMetaData fmd = decl ? meta.getDeclaredField(name) : meta
+                .getField(name);
+
+        if (fmd == null) {
+            if (decl && meta.getField(name) != null) {
+                throw new IllegalArgumentException(_loc.get("field-not-decl",
+                        name, cls, meta.getField(name).getDeclaringType())
+                        .getMessage());
+            } else {
+                throw new IllegalArgumentException(_loc.get("field-missing",
+                        name, meta.getDescribedType(),
+                        Arrays.toString(meta.getFieldNames())).getMessage());
+            }
+        }
+        assertType("field-type-mismatch", fmd, fmd.getDeclaredType(), type);
+        assertType("field-element-type-mismatch", fmd, fmd.getElement()
+                .getDeclaredType(), elementType);
+        assertType("field-key-type-mismatch", fmd, fmd.getKey()
+                .getDeclaredType(), keyType);
+        return fmd;
+    }
+
+    void assertType(String msg, FieldMetaData fmd, Class<?> actual,
+            Class<?> expected) {
+        if (expected != null && !expected.isAssignableFrom(actual)) {
+            if (wrap(expected) != wrap(actual)) {
+                throw new IllegalArgumentException(_loc.get(msg, fmd.getName(),
+                        actual, expected).getMessage());
+            }
+        }
+    }
+
+    Class<?> wrap(Class<?> c) {
+        if (c.isPrimitive()) {
+            if (c == int.class)
+                return Integer.class;
+            if (c == long.class)
+                return Long.class;
+            if (c == boolean.class)
+                return Boolean.class;
+            if (c == byte.class)
+                return Byte.class;
+            if (c == char.class)
+                return Character.class;
+            if (c == double.class)
+                return Double.class;
+            if (c == float.class)
+                return Float.class;
+            if (c == short.class)
+                return Short.class;
+        }
+        return c;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Exception handling
+    // -------------------------------------------------------------------------
+    private void notFoundException(String msg, String name, Class<?> t1) {
+        throw new IllegalArgumentException(msg + " Attribute " + name + " of type " + 
+                (t1 == null ? "any" : t1.getName()) + " not found in " + meta);
+    }
+    
+    private void notFoundException(String msg, String name, Class<?> t1, Class<?> t2) {
+        throw new IllegalArgumentException("Attribute " + name + " not found");
+    }
+    // --------------------------------------------------------------------------
+    // Attribute filtering
+    // --------------------------------------------------------------------------
+    /**
+     * Affirms if a given element satisfy a condition.
+     * 
+     */
+    public static interface Filter<T> {
+        boolean selects(T attr);
+
+        Filter<T> inverse();
+    }
+    
+
+    /**
+     * Applies chain of filters ANDed on the given collection to populate the given result.
+     * A null filter evaluates always TRUE.
+     * The arguments are not passed as variable argument list to suppress warnings in in the caller
+     * for generic varargs array construction.
+     */
+    
+    public static <T, C extends java.util.Collection<E>, E> C filter(Collection<T> original, 
+        C result, Filter<T> f1, Filter<T> f2, Filter<T> f3, Filter<T> f4) {
+        for (T t : original) {
+            if ((f1 == null || f1.selects(t)) && (f2 == null || f2.selects(t)) 
+             && (f3 == null || f3.selects(t)) && (f4 == null || f4.selects(t)))
+                result.add((E) t);
+        }
+        return result;
+    }
+    
+    /**
+     * Applies chain of filters ANDed on the given collection to pick a single element.
+     * A null filter evaluates always TRUE.
+     * The arguments are not passed as variable argument list to suppress warnings in in the caller
+     * for generic varargs array construction.
+     */
+    public static <T> T pick(Collection<T> original, Filter<T> f1, Filter<T> f2, Filter<T> f3, 
+        Filter<T> f4) {
+        for (T t : original) {
+            if ((f1 == null || f1.selects(t)) && (f2 == null || f2.selects(t)) 
+             && (f3 == null || f3.selects(t)) && (f4 == null || f4.selects(t)))
+                return t;
+        }
+        return null;
+    }
+    
+    public static <T, C extends java.util.Collection<E>, E> C filter(Collection<T> original, 
+            C result, Filter<T> f1) {
+        return filter(original, result, f1, null, null, null);
+    }
+    
+    public static <T, C extends java.util.Collection<E>, E> C filter(Collection<T> original, 
+            C result, Filter<T> f1, Filter<T> f2) {
+        return filter(original, result, f1, f2, null, null);
+    }
+    
+    public static <T, C extends java.util.Collection<E>, E> C filter(Collection<T> original, 
+            C result, Filter<T> f1, Filter<T> f2, Filter<T> f3) {
+        return filter(original, result, f1, f2, f3, null);
+    }
+    
+    public static <T> T pick(Collection<T> original, Filter<T> f1) {
+        return pick(original, f1, null, null, null);
+    }
+
+    public static <T> T pick(Collection<T> original, Filter<T> f1, Filter<T> f2) {
+        return pick(original, f1, f2, null, null);
+    }
+    
+    public static <T> T pick(Collection<T> original, Filter<T> f1, Filter<T> f2, Filter<T> f3) {
+        return pick(original, f1, f2, f3, null);
+    }
+    
+
+    /**
+     * Affirms if the given attribute is a Singular attribute.
+     * 
+     */
+    public static final class SingularAttributeFilter<X> implements
+            Filter<Attribute<? super X, ?>> {
+        private final boolean _invert;
+
+        public SingularAttributeFilter() {
+            this(false);
+        }
+
+        public SingularAttributeFilter(boolean inverted) {
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            return _invert ? attr.isCollection() : !attr.isCollection();
+        }
+
+        public SingularAttributeFilter<X> inverse() {
+            return new SingularAttributeFilter<X>(!_invert);
+        }
+    }
+
+    public static final class DeclaredAttributeFilter<X> implements
+            Filter<Attribute<? super X, ?>> {
+        private final ManagedType<X> owner;
+        private final boolean _invert;
+
+        DeclaredAttributeFilter(ManagedType<X> owner) {
+            this(owner, false);
+        }
+
+        DeclaredAttributeFilter(ManagedType<X> owner, boolean inverted) {
+            this.owner = owner;
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            return _invert ? attr.getDeclaringType() != owner : attr
+                    .getDeclaringType() == owner;
+        }
+
+        public DeclaredAttributeFilter<X> inverse() {
+            return new DeclaredAttributeFilter<X>(owner, !_invert);
+        }
+    }
+
+    /**
+     * Selects if the attribute type matches the given Java class.
+     * null matches any type.
+     */
+    public static final class AttributeTypeFilter<X, Y> implements
+            Filter<Attribute<? super X, ?>> {
+        private final Class<Y> _type;
+        private final boolean _invert;
+
+        public AttributeTypeFilter(Class<Y> type) {
+            this(type, false);
+        }
+
+        public AttributeTypeFilter(Class<Y> type, boolean inverted) {
+            _type = type;
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            boolean result = _type == null || attr.getJavaType() == _type;
+            return _invert ? !result : result;
+        }
+
+        public AttributeTypeFilter<X, Y> inverse() {
+            return new AttributeTypeFilter<X, Y>(_type, !_invert);
+        }
+    }
+
+    public static final class AttributeNameFilter<X> implements
+            Filter<Attribute<? super X, ?>> {
+        private final String _name;
+        private final boolean _invert;
+
+        public AttributeNameFilter(String name) {
+            this(name, false);
+        }
+
+        public AttributeNameFilter(String name, boolean inverted) {
+            _name = name;
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            return _invert ? !attr.getName().equals(_name) : attr.getName()
+                    .equals(_name);
+        }
+
+        public AttributeNameFilter<X> inverse() {
+            return new AttributeNameFilter<X>(_name, !_invert);
+        }
+    }
+
+    public static final class PluralCategoryFilter<X> implements
+            Filter<Attribute<? super X, ?>> {
+        private final CollectionType _category;
+        private final boolean _invert;
+
+        public PluralCategoryFilter(CollectionType category) {
+            this(category, false);
+        }
+
+        public PluralCategoryFilter(CollectionType category, boolean inverted) {
+            _category = category;
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            boolean result = (attr instanceof PluralAttribute<?, ?, ?>)
+                    && ((PluralAttribute<?, ?, ?>) attr).getCollectionType() == _category;
+            return _invert ? !result : result;
+        }
+
+        public PluralCategoryFilter<X> inverse() {
+            return new PluralCategoryFilter<X>(_category, !_invert);
+        }
+    }
+
+    /**
+     * Selects plural attribute of given element type.
+     * null element type imply <em>any</em> element type.
+     */
+    
+    public static final class ElementTypeFilter<X, E> implements Filter<Attribute<? super X, ?>> {
+        private final Class<E> _elementType;
+        private final boolean _invert;
+
+        public ElementTypeFilter(Class<E> eType) {
+            this(eType, false);
+        }
+
+        public ElementTypeFilter(Class<E> eType, boolean inverted) {
+            _elementType = eType;
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            boolean result = (attr instanceof PluralAttribute<?, ?, ?>)
+                    && (_elementType == null 
+                    || ((PluralAttribute<?, ?, ?>) attr).getElementType().getJavaType() 
+                         == _elementType);
+            return _invert ? !result : result;
+        }
+
+        public ElementTypeFilter<X, E> inverse() {
+            return new ElementTypeFilter<X, E>(_elementType, !_invert);
+        }
+    }
+
+    public static final class EntryTypeFilter<X, K, V> implements
+            Filter<Attribute<? super X, ?>> {
+        private final Class<K> _keyType;
+        private final Class<V> _valueType;
+        private final boolean _invert;
+
+        public EntryTypeFilter(Class<K> kType, Class<V> vType) {
+            this(kType, vType, false);
+        }
+
+        public EntryTypeFilter(Class<K> kType, Class<V> vType, boolean inverted) {
+            _keyType = kType;
+            _valueType = vType;
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            boolean result = (attr instanceof MapAttribute<?, ?, ?>)
+                    && (_keyType == null 
+                    || ((MapAttribute<?, ?, ?>) attr).getKeyType().getJavaType() == _keyType)
+                    && (_valueType == null 
+                    || ((MapAttribute<?, ?, ?>) attr).getElementType().getJavaType() == _valueType);
+            return _invert ? !result : result;
+        }
+
+        public EntryTypeFilter<X, K, V> inverse() {
+            return new EntryTypeFilter<X, K, V>(_keyType, _valueType, !_invert);
+        }
+    }
+
+    public static final class IdAttributeFilter<X> implements
+            Filter<Attribute<? super X, ?>> {
+        private final boolean _invert;
+
+        public IdAttributeFilter() {
+            this(false);
+        }
+
+        public IdAttributeFilter(boolean inverted) {
+            _invert = inverted;
+        }
+
+        public boolean selects(Attribute<? super X, ?> attr) {
+            boolean result = ((Members.Member<?, ?>) attr).fmd.isPrimaryKey();
+            return _invert ? !result : result;
+        }
+
+        public IdAttributeFilter<X> inverse() {
+            return new IdAttributeFilter<X>(!_invert);
+        }
+    }
+    
+    public static final class VersionAttributeFilter<X> implements Filter<Attribute<? super X, ?>> {
+        private final boolean _invert;
+
+        public VersionAttributeFilter() {
+            this(false);
+        }
+        
+        public VersionAttributeFilter(boolean inverted) {
+            _invert = inverted;
+        }
+        
+        public boolean selects(Attribute<? super X, ?> attr) {
+            FieldMetaData fmd = ((Members.Member<?, ?>) attr).fmd;
+            boolean result = fmd.isVersion();
+            return _invert ? !result : result;
+        }
+        
+        public IdAttributeFilter<X> inverse() {
+            return new IdAttributeFilter<X>(!_invert);
+        }
+    }
+
+}

Propchange: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AbstractManagedType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java?rev=787832&r1=787831&r2=787832&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/AnnotationProcessor6.java Tue Jun 23 21:04:32 2009
@@ -44,7 +44,7 @@
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.Elements;
-import javax.persistence.metamodel.TypesafeMetamodel;
+import javax.persistence.metamodel.StaticMetamodel;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
@@ -106,11 +106,11 @@
      * 
      */
     private static enum TypeCategory {
-        ATTRIBUTE("javax.persistence.metamodel.Attribute"), 
-        COLLECTION("javax.persistence.metamodel.Collection"), 
-        SET("javax.persistence.metamodel.Set"), 
-        LIST("javax.persistence.metamodel.List"), 
-        MAP("javax.persistence.metamodel.Map");
+        ATTRIBUTE("javax.persistence.metamodel.SingularAttribute"), 
+        COLLECTION("javax.persistence.metamodel.CollectionAttribute"), 
+        SET("javax.persistence.metamodel.SetAttribute"), 
+        LIST("javax.persistence.metamodel.ListAttribute"), 
+        MAP("javax.persistence.metamodel.MapAttribute");
 
         private String type;
 
@@ -280,7 +280,7 @@
     
     private void annotate(SourceCode source, String originalClass) {
         SourceCode.Class cls = source.getTopLevelClass();
-        cls.addAnnotation(TypesafeMetamodel.class.getName())
+        cls.addAnnotation(StaticMetamodel.class.getName())
             .addArgument("value", originalClass + ".class", false);
         if (generatedSourceVersion >= 6) {
             cls.addAnnotation(Generated.class.getName())

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/Members.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/Members.java?rev=787832&r1=787831&r2=787832&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/Members.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/Members.java Tue Jun 23 21:04:32 2009
@@ -19,20 +19,23 @@
 
 package org.apache.openjpa.persistence.meta;
 
-import java.lang.reflect.Field;
-
-import javax.persistence.metamodel.AbstractCollection;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.ListAttribute;
 import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.SingularAttribute;
 import javax.persistence.metamodel.Type;
 
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 
 /**
- * Member according to JPA 2.0 metamodel.
+ * Persistent attribute according to JPA 2.0 metamodel.
  * 
- * Implemented as a thin adapter to OpenJPA FieldMetadata.
- * Mostly immutable.
+ * Implemented as a thin adapter to OpenJPA FieldMetadata. Mostly immutable.
  * 
  * @author Pinaki Poddar
  * 
@@ -40,225 +43,278 @@
  *
  */
 public class Members {
-	/**
-	 * Root of implementation hierarchy.
+    /**
+     * An attribute of a Java type. A persistent attribute is realized as a field and getter/setter
+     * method of a Java class. This implementation adapts kernel's {@link FieldMetaData} construct 
+     * to meet the JPA API contract.
+	 *
 	 *
-	 * @param <X> the class that owns this member
-	 * @param <Y> the class of the value held by this member
+     * @param <X> The type that contains this attribute
+     * @param <Y> The type of this attribute
 	 */
-    public static abstract class Member<X, Y> 
-       implements javax.persistence.metamodel.Member<X, Y> {
-
-        public final Types.Managed<X> owner;
+    public static abstract class Member<X, Y> implements Attribute<X, Y> {
+        public final AbstractManagedType<X> owner;
         public final FieldMetaData fmd;
 
-        protected Member(Types.Managed<X> owner, FieldMetaData fmd) {
+        /**
+         * Supply immutable parts.
+         * 
+         * @param owner the persistent type that contains this attribute
+         * @param fmd the kernel's concrete representation of this attribute
+         */
+        protected Member(AbstractManagedType<X> owner, FieldMetaData fmd) {
             this.owner = owner;
             this.fmd = fmd;
         }
 
+        /**
+         *  Returns the managed type which declared this attribute.
+         */
         public final ManagedType<X> getDeclaringType() {
-            return (ManagedType<X>)owner.model.getType(fmd.getDeclaringType());
+            return owner.model.type(fmd.getDeclaringType());
         }
         
-        public Type<?> getType() {
-            return owner.model.getType(fmd.getDeclaredType());
-        }
-
+        /**
+         *  Returns the java.lang.reflect.Member for this attribute. 
+         */
         public final java.lang.reflect.Member getJavaMember() {
             return fmd.getBackingMember();
         }
-
-        public Class<Y> getMemberJavaType() {
-            return (Class<Y>) fmd.getDeclaredType();
+        
+        /**
+         *  Gets the Java type of this attribute.
+         */
+        public final Class<Y> getJavaType() {
+            return (Class<Y>)fmd.getDeclaredType();
         }
-
+        
+        /**
+         * Gets the name of this attribute.
+         */
         public final String getName() {
             return fmd.getName();
         }
 
+        /**
+         * Returns the type that represents the type of this attribute.
+         */
+        public final Type<Y> getType() {
+            return owner.model.getType(isCollection() ?
+                   fmd.getElement().getDeclaredType() : fmd.getDeclaredType());
+        }
+        
+        /**
+         * Affirms if this attribute is an association.
+         */
         public final boolean isAssociation() {
             return fmd.isDeclaredTypePC();
         }
 
+        /**
+         * Affirms if this attribute is a collection.
+         */
         public final boolean isCollection() {
-            return fmd.getDeclaredTypeCode() == JavaTypes.COLLECTION
-                || fmd.getDeclaredTypeCode() == JavaTypes.MAP;
+            int typeCode = fmd.getDeclaredTypeCode();
+            return  typeCode == JavaTypes.COLLECTION
+                 || typeCode == JavaTypes.MAP
+                 || typeCode == JavaTypes.ARRAY;
         }
         
-        public String toString() {
-            return fmd.getName() + ":" + getType();
+        /**
+         *  Returns the persistent category for the attribute.
+         */
+        public PersistentAttributeType getPersistentAttributeType() {
+            if (fmd.isEmbedded())
+                return PersistentAttributeType.EMBEDDED;
+            if (fmd.isElementCollection())
+                return PersistentAttributeType.ELEMENT_COLLECTION;
+            return PersistentAttributeType.BASIC;
         }
     }
-
+    
+    
     /**
-     * Attributes are non-collection members.
+     * Represents single-valued persistent attributes.
      *
-	 * @param <X> the class that owns this member
-	 * @param <T> the class of the value held by this member
+     * @param <X> The type containing the represented attribute
+     * @param <T> The type of the represented attribute
      */
-    public static final class Attribute<X, T> extends Member<X, T> implements
-        javax.persistence.metamodel.Attribute<X, T> {
+    public static final class SingularAttributeImpl<X, T> extends Member<X, T> 
+        implements SingularAttribute<X, T> {
 
-        public Attribute(Types.Managed<X> owner, FieldMetaData fmd) {
+        public SingularAttributeImpl(AbstractManagedType<X> owner, FieldMetaData fmd) {
             super(owner, fmd);
         }
 
-        public Multiplicity getMultiplicity() {
-            throw new AbstractMethodError();
-        }
-
+        /**
+         *  Affirms if this attribute is an id attribute.
+         */
         public boolean isId() {
             return fmd.isPrimaryKey();
         }
 
+        /**
+         *  Affirms if this attribute represents a version attribute.
+         */
         public boolean isVersion() {
             return fmd.isVersion();
         }
 
+        /** 
+         *  Affirms if this attribute can be null.
+         */
         public boolean isOptional() {
             return fmd.getNullValue() != FieldMetaData.NULL_EXCEPTION;
         }
-        
-        public boolean isEmbedded() {
-            return fmd.isEmbedded();
-        }
-
-        public Type<T> getAttributeType() {
-            return owner.model.type(fmd.getDeclaredType());
-        }
-
-        public BindableType getBindableType() {
-            return fmd.isDeclaredTypePC() ? BindableType.MANAGED_TYPE
-                : BindableType.ATTRIBUTE;
-        }
 
-        public Class<T> getJavaType() {
-            return super.getMemberJavaType();
+        /**
+         *  Categorizes bindable type represented by this attribute.
+         */ 
+        public final BindableType getBindableType() {
+            return fmd.isDeclaredTypePC() 
+                ? BindableType.ENTITY_TYPE
+                : BindableType.SINGULAR_ATTRIBUTE;
+        }
+       
+        /**
+         * Returns the bindable Java type of this attribute.
+         * 
+         * If the bindable category of this attribute is PLURAL_ATTRIBUTE, the Java element type 
+         * is returned. If the bindable type is SINGULAR_ATTRIBUTE or ENTITY_TYPE, the Java type 
+         * of the represented entity or attribute is returned.
+         */
+        public final Class<T> getBindableJavaType() {
+            return fmd.getElement().getDeclaredType();
         }
         
-        public void validateMeta(Field f) {
-            
+        /**
+         * Categorizes the attribute.
+         */
+        public final PersistentAttributeType getPersistentAttributeType() {
+            if (!fmd.isDeclaredTypePC())
+                return super.getPersistentAttributeType();
+            return fmd.getMappedByMetaData() == null 
+                 ? PersistentAttributeType.ONE_TO_ONE
+                 : PersistentAttributeType.ONE_TO_MANY;
         }
     }
 
     /**
-     * Root of collection members.
+     * Root of multi-cardinality attribute.
      *
-	 * @param <X> the class that owns this member
-	 * @param <C> the container class that holds this member 
-	 *            (e.g. java.util.Set)
-     * @param <E> the class of the element held by this member 
+	 * @param <X> the type that owns this member
+	 * @param <C> the container type that holds this member (e.g. java.util.Set&lt;Employee&gt;)
+     * @param <E> the type of the element held by this member (e.g. Employee). 
      */
-    public static abstract class BaseCollection<X, C, E> extends Member<X, C>
-        implements AbstractCollection<X, C, E> {
-
-        public BaseCollection(Types.Managed<X> owner, FieldMetaData fmd) {
+    public static abstract class PluralAttributeImpl<X, C, E> extends Member<X, C>
+        implements PluralAttribute<X, C, E> {
+        
+        public PluralAttributeImpl(AbstractManagedType<X> owner, FieldMetaData fmd) {
             super(owner, fmd);
         }
 
+        /**
+         * Returns the type representing the element type of the collection.
+         */
         public final Type<E> getElementType() {
-            return owner.model.getType(fmd.getElement().getDeclaredType());
+            return owner.model.getType(getBindableJavaType());
         }
 
+        /**
+         *  Returns the bindable category of this attribute.
+         */ 
         public final BindableType getBindableType() {
-            return BindableType.COLLECTION;
-        }
-
-        public Class<E> getJavaType() {
-            return fmd.getDeclaredType();
+            return BindableType.PLURAL_ATTRIBUTE;
         }
         
-        public Class getMemberJavaType() {
+        /**
+         * Returns the bindable Java type of this attribute.
+         * 
+         * For PLURAL_ATTRIBUTE, the Java element type is returned. 
+         */
+        public final Class<E> getBindableJavaType() {
             return fmd.getElement().getDeclaredType();
         }
+        
+        
+        public PersistentAttributeType getPersistentAttributeType() {
+            return PersistentAttributeType.ONE_TO_MANY;
+        }
     }
 
     /**
-     * Members declared as java.util.Collection<E>.
+     * Represents attributes declared as java.util.Collection&lt;E&gt;.
      */
-    public static class Collection<X, E> extends
-        BaseCollection<X, java.util.Collection<E>, E> implements
-        javax.persistence.metamodel.Collection<X, E> {
+    public static class CollectionAttributeImpl<X, E> 
+        extends PluralAttributeImpl<X, java.util.Collection<E>, E> 
+        implements CollectionAttribute<X, E> {
 
-        public Collection(Types.Managed<X> owner, FieldMetaData fmd) {
+        public CollectionAttributeImpl(AbstractManagedType<X> owner, FieldMetaData fmd) {
             super(owner, fmd);
         }
 
-        public Multiplicity getMultiplicity() {
-            return Multiplicity.ONE_TO_MANY;
-        }
-
         public CollectionType getCollectionType() {
             return CollectionType.COLLECTION;
         }
     }
 
     /**
-     * Members declared as java.util.List<E>.
+     * Represents attributes declared as java.util.List&lt;E&gt;.
      */
-    public static class List<X, E> extends
-        BaseCollection<X, java.util.List<E>, E> implements
-        javax.persistence.metamodel.List<X, E> {
+    public static class ListAttributeImpl<X, E> 
+        extends PluralAttributeImpl<X, java.util.List<E>, E> 
+        implements ListAttribute<X, E> {
 
-        public List(Types.Managed<X> owner, FieldMetaData fmd) {
+        public ListAttributeImpl(AbstractManagedType<X> owner, FieldMetaData fmd) {
             super(owner, fmd);
         }
 
-        public Multiplicity getMultiplicity() {
-            return Multiplicity.ONE_TO_MANY;
-        }
-
         public CollectionType getCollectionType() {
             return CollectionType.LIST;
         }
     }
 
     /**
-     * Members declared as java.util.Set<E>.
+     * Represents attributes declared as java.util.Set&lt;E&gt;.
      */
-    public static class Set<X, E> extends
-        BaseCollection<X, java.util.Set<E>, E> implements
-        javax.persistence.metamodel.Set<X, E> {
+    public static class SetAttributeImpl<X, E> 
+        extends PluralAttributeImpl<X, java.util.Set<E>, E> 
+        implements SetAttribute<X, E> {
 
-        public Set(Types.Managed<X> owner, FieldMetaData fmd) {
+        public SetAttributeImpl(AbstractManagedType<X> owner, FieldMetaData fmd) {
             super(owner, fmd);
         }
 
-        public Multiplicity getMultiplicity() {
-            return Multiplicity.ONE_TO_MANY;
-        }
-
         public CollectionType getCollectionType() {
             return CollectionType.SET;
         }
     }
 
     /**
-     * Members declared as java.util.Map<K,V>.
+     * Represents attributes declared as java.util.Map&lt;E&gt;.
      */
-    public static class Map<X, K, V> extends
-        BaseCollection<X, java.util.Map<K, V>, V> implements
-        javax.persistence.metamodel.Map<X, K, V> {
+    public static class MapAttributeImpl<X, K, V> 
+        extends PluralAttributeImpl<X, java.util.Map<K, V>, V> 
+        implements MapAttribute<X, K, V> {
 
-        public Map(Types.Managed<X> owner, FieldMetaData fmd) {
+        public MapAttributeImpl(AbstractManagedType<X> owner, FieldMetaData fmd) {
             super(owner, fmd);
         }
 
         public CollectionType getCollectionType() {
             return CollectionType.MAP;
         }
-
-        public Multiplicity getMultiplicity() {
-            return Multiplicity.MANY_TO_MANY;
-        }
-
+        
         public Class<K> getKeyJavaType() {
-            return (Class<K>) fmd.getKey().getDeclaredType();
+            return fmd.getKey().getDeclaredType();
         }
 
         public Type<K> getKeyType() {
             return owner.model.getType(getKeyJavaType());
         }
+        
+        public PersistentAttributeType getPersistentAttributeType() {
+            return PersistentAttributeType.MANY_TO_MANY;
+        }
     }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java?rev=787832&r1=787831&r2=787832&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java Tue Jun 23 21:04:32 2009
@@ -34,15 +34,16 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.persistence.metamodel.Embeddable;
-import javax.persistence.metamodel.Entity;
+import javax.persistence.metamodel.EmbeddableType;
+import javax.persistence.metamodel.EntityType;
 import javax.persistence.metamodel.ManagedType;
-import javax.persistence.metamodel.MappedSuperclass;
-import javax.persistence.metamodel.Member;
+import javax.persistence.metamodel.MappedSuperclassType;
+import javax.persistence.metamodel.Attribute;
 import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.PluralAttribute;
 import javax.persistence.metamodel.Type;
-import javax.persistence.metamodel.TypesafeMetamodel;
-import javax.persistence.metamodel.AbstractCollection.CollectionType;
+import javax.persistence.metamodel.StaticMetamodel;
+import javax.persistence.metamodel.PluralAttribute.CollectionType;
 import javax.persistence.metamodel.Type.PersistenceType;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
@@ -54,6 +55,7 @@
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.meta.Members.Member;
 import org.apache.openjpa.util.InternalException;
 
 /**
@@ -64,17 +66,19 @@
  */
 public class MetamodelImpl implements Metamodel, Resolver {
     public final MetaDataRepository repos;
-    private Map<Class<?>, Entity<?>> _entities = 
-        new HashMap<Class<?>, Entity<?>>();
-    private Map<Class<?>, Embeddable<?>> _embeddables =
-        new HashMap<Class<?>, Embeddable<?>>();
-    private Map<Class<?>, MappedSuperclass<?>> _mappedsupers =
-        new HashMap<Class<?>, MappedSuperclass<?>>();
-    private Map<Class<?>, Type<?>> _basics = 
-        new HashMap<Class<?>, Type<?>>();
+    private Map<Class<?>, Type<?>> _basics = new HashMap<Class<?>, Type<?>>();
+    private Map<Class<?>, EntityType<?>> _entities = new HashMap<Class<?>, EntityType<?>>();
+    private Map<Class<?>, EmbeddableType<?>> _embeddables 
+        = new HashMap<Class<?>, EmbeddableType<?>>();
+    private Map<Class<?>, MappedSuperclassType<?>> _mappedsupers 
+        = new HashMap<Class<?>, MappedSuperclassType<?>>();
 
     private static Localizer _loc = Localizer.forPackage(MetamodelImpl.class);
 
+    /**
+     * Constructs a model with the current content of the supplied non-null repository.
+     * 
+     */
     public MetamodelImpl(MetaDataRepository repos) {
         this.repos = repos;
         Collection<Class<?>> classes = repos.loadPersistentTypes(true, null);
@@ -98,22 +102,47 @@
         }
     }
 
-    public <X> Embeddable<X> embeddable(Class<X> clazz) {
-        return (Embeddable<X>)find(clazz, _embeddables, EMBEDDABLE);
+    /**
+     *  Return the metamodel embeddable type representing the embeddable class.
+     *  
+     *  @param cls  the type of the represented embeddable class
+     *  @return the metamodel embeddable type
+     *  @throws IllegalArgumentException if not an embeddable class
+     */
+    public <X> EmbeddableType<X> embeddable(Class<X> clazz) {
+        return (EmbeddableType<X>)find(clazz, _embeddables, EMBEDDABLE);
     }
 
-    public <X> Entity<X> entity(Class<X> clazz) {
-        return (Entity<X>) find(clazz, _entities, ENTITY);
+    /**
+     *  Return the metamodel entity type representing the entity.
+     *  @param cls  the type of the represented entity
+     *  @return the metamodel entity type
+     *  @throws IllegalArgumentException if not an entity
+     */
+    public <X> EntityType<X> entity(Class<X> clazz) {
+        return (EntityType<X>) find(clazz, _entities, ENTITY);
     }
 
-    public Set<Embeddable<?>> getEmbeddables() {
+    /**
+     * Return the metamodel embeddable types.
+     * @return the metamodel embeddable types
+     */
+    public Set<EmbeddableType<?>> getEmbeddables() {
         return unmodifiableSet(_embeddables.values());
     }
 
-    public Set<Entity<?>> getEntities() {
+    /**
+     * Return the metamodel entity types.
+     * @return the metamodel entity types
+     */
+    public Set<EntityType<?>> getEntities() {
         return unmodifiableSet(_entities.values());
     }
 
+    /**
+     *  Return the metamodel managed types.
+     *  @return the metamodel managed types
+     */
     public Set<ManagedType<?>> getManagedTypes() {
         Set<ManagedType<?>> result = new HashSet<ManagedType<?>>();
         result.addAll(_entities.values());
@@ -121,22 +150,32 @@
         result.addAll(_mappedsupers.values());
         return result;
     }
-
-    public ClassMetaData getMetaData(Types.Identifiable<?> managedType) {
-        return managedType.meta;
-    }
     
+    /**
+     *  Return the metamodel managed type representing the 
+     *  entity, mapped superclass, or embeddable class.
+     *  @param cls  the type of the represented managed class
+     *  @return the metamodel managed type
+     *  @throws IllegalArgumentException if not a managed class
+     */
     public <X> ManagedType<X> type(Class<X> clazz) {
         if (_entities.containsKey(clazz))
-            return (Entity<X>) _entities.get(clazz);
+            return (EntityType<X>) _entities.get(clazz);
         if (_embeddables.containsKey(clazz))
-            return (Embeddable<X>) _embeddables.get(clazz);
+            return (EmbeddableType<X>) _embeddables.get(clazz);
         if (_mappedsupers.containsKey(clazz))
-            return (MappedSuperclass<X>) _mappedsupers.get(clazz);
+            return (MappedSuperclassType<X>) _mappedsupers.get(clazz);
         throw new IllegalArgumentException(_loc.get("type-not-managed", clazz)
             .getMessage());
     }
 
+    /**
+     *  Return the type representing the basic, 
+     *  entity, mapped superclass, or embeddable class.
+     *  @param cls  the type of the represented managed class
+     *  @return the metamodel managed type
+     *  @throws IllegalArgumentException if not a managed class
+     */
     public <X> Type<X> getType(Class<X> cls) {
         try {
             return type(cls);
@@ -159,26 +198,36 @@
         return ENTITY;
     }
 
-    private <V extends ManagedType<?>> V find(Class<?> cls, 
-        Map<Class<?>,V> container,  PersistenceType expected) {
+    /**
+     * Looks up the given container for the managed type representing the given Java class.
+     * The managed type may become instantiated as a side-effect.
+     */
+    private <V extends ManagedType<?>> V find(Class<?> cls, Map<Class<?>,V> container,  
+            PersistenceType expected) {
         if (container.containsKey(cls))
             return container.get(cls);
         ClassMetaData meta = repos.getMetaData(cls, null, false);
         if (meta != null) {
-            instantiate(cls, container, expected);
+            instantiate(cls, meta, container, expected);
         }
         return container.get(cls);
     }
 
-    private <X,V extends ManagedType<?>> void instantiate(Class<X> cls, 
-        Map<Class<?>,V> container, PersistenceType expected) {
-        ClassMetaData meta = repos.getMetaData(cls, null, true);
+    /**
+     * Instantiate
+     * @param <X>
+     * @param <V>
+     * @param cls
+     * @param container
+     * @param expected
+     */
+    private <X,V extends ManagedType<?>> void instantiate(Class<X> cls, ClassMetaData meta, 
+            Map<Class<?>,V> container, PersistenceType expected) {
         PersistenceType actual = getPersistenceType(meta);
         if (actual != expected) {
             if (!meta.isEmbeddable() || actual != PersistenceType.ENTITY ||
                 expected != PersistenceType.EMBEDDABLE) 
-                throw new IllegalArgumentException(
-                    _loc.get("type-wrong-category",
+                throw new IllegalArgumentException( _loc.get("type-wrong-category",
                     cls, actual, expected).getMessage());
         }
         switch (actual) {
@@ -186,7 +235,7 @@
             Types.Embeddable<X> embedded = new Types.Embeddable<X>(meta, this);
             _embeddables.put(cls, embedded);
             populate(embedded);
-//            break;
+            // no break : embeddables are stored as both entity and embeddable containers
         case ENTITY:
         	Types.Entity<X> entity = new Types.Entity<X>(meta, this);
             _entities.put(cls, entity);
@@ -209,7 +258,7 @@
         return result;
     }
 
-    public static CollectionType getCollectionType(Class<?> cls) {
+    public static CollectionType categorizeCollection(Class<?> cls) {
         if (Set.class.isAssignableFrom(cls))
             return CollectionType.SET;
         if (List.class.isAssignableFrom(cls))
@@ -218,24 +267,22 @@
             return CollectionType.COLLECTION;
         if (Map.class.isAssignableFrom(cls))
             return CollectionType.MAP;
-        if (cls.isArray())
-            return CollectionType.LIST;
-        return null;
+        
+        throw new InternalException(cls.getName() + " not a collection");
     }
     
     /**
      * Populate the static fields of the canonical type.
      */
-    public <X> void populate(Types.Managed<X> type) {
+    public <X> void populate(AbstractManagedType<X> type) {
 		Class<X> cls = type.getJavaType();
 		Class<?> mcls = repos.getMetaModel(cls, true);
 		if (mcls == null)
 		    return;
-        TypesafeMetamodel anno = mcls.getAnnotation(TypesafeMetamodel.class);
+        StaticMetamodel anno = mcls.getAnnotation(StaticMetamodel.class);
 		if (anno == null)
             throw new IllegalArgumentException(_loc.get("meta-class-no-anno", 
-               mcls.getName(), cls.getName(), TypesafeMetamodel.class.getName())
-		       .getMessage());
+               mcls.getName(), cls.getName(), StaticMetamodel.class.getName()).getMessage());
 		
         if (cls != anno.value()) {
             throw new IllegalStateException(_loc.get("meta-class-mismatch",
@@ -246,8 +293,8 @@
     	for (Field mf : mfields) {
             try {
                 ParameterizedType mfType = getParameterziedType(mf);
-    	        Member<? super X, ?> f = type.getMember(mf.getName());
-    	        Class<?> fClass = f.getMemberJavaType();
+    	        Attribute<? super X, ?> f = type.getAttribute(mf.getName());
+    	        Class<?> fClass = f.getJavaType();
     	       java.lang.reflect.Type[] args = mfType.getActualTypeArguments();
     	       if (args.length < 2)
     	           throw new IllegalStateException(
@@ -325,7 +372,7 @@
     }
     
     <X,Y> void validate(Field mField, Member<X, Y> member) {
-        Class<?> fType = member.getMemberJavaType();
+        Class<?> fType = member.getJavaType();
         if (!ParameterizedType.class.isInstance(mField.getGenericType())) {
             throw new IllegalArgumentException(_loc.get("meta-bad-field", 
                 mField).getMessage());