You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by wi...@apache.org on 2007/07/31 18:19:27 UTC

svn commit: r561376 - in /openjpa/trunk: openjpa-jdbc-5/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc-5/src/main/java/org/apache/openjpa/meta/ openjpa-kernel/src/main/java/org/apache/openjpa/meta/ openjpa-persistence-jdbc/src/test/java/org/a...

Author: wisneskid
Date: Tue Jul 31 09:19:24 2007
New Revision: 561376

URL: http://svn.apache.org/viewvc?view=rev&rev=561376
Log:
OPENJPA-240 XMLMapping Query - refactoring JAXB XML annotaion parser
Help Catalina committing OPENJPA-240.r560665.patch for refactoring JAXB XML annotation parser.

Added:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLClassMetaData.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceXMLMetaDataParser.java
Removed:
    openjpa/trunk/openjpa-jdbc-5/src/main/java/org/apache/openjpa/jdbc/meta/XMLMappingRepository.java
    openjpa/trunk/openjpa-jdbc-5/src/main/java/org/apache/openjpa/meta/XMLClassMetaData.java
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/DelegatingMetaDataFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLFieldMetaData.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLMetaData.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.java
    openjpa/trunk/openjpa-persistence/pom.xml
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataFactory.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/DelegatingMetaDataFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/DelegatingMetaDataFactory.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/DelegatingMetaDataFactory.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/DelegatingMetaDataFactory.java Tue Jul 31 09:19:24 2007
@@ -122,4 +122,8 @@
     public void addFieldExtensionKeys(Collection exts) {
         _delegate.addFieldExtensionKeys(exts);
     }
+
+    public void loadXMLMetaData(FieldMetaData fmd) {
+        _delegate.loadXMLMetaData(fmd);
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataFactory.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataFactory.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataFactory.java Tue Jul 31 09:19:24 2007
@@ -144,4 +144,10 @@
      * Add any extension keys used by this instance to the given set.
      */
     public void addFieldExtensionKeys (Collection exts);
+
+    /**
+     * Load XMLClassMetadata for the given class. Loaded
+     * metadata should be added directly to the repository.
+     */
+    public void loadXMLMetaData(FieldMetaData fmd);
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java Tue Jul 31 09:19:24 2007
@@ -117,6 +117,10 @@
     // map of classes to lists of their subclasses
     private final Map _subs = Collections.synchronizedMap(new HashMap());
 
+    // xml mapping
+    protected final XMLMetaData[] EMPTY_XMLMETAS;
+    private final Map _xmlmetas = new HashMap();
+
     private transient OpenJPAConfiguration _conf = null;
     private transient Log _log = null;
     private transient InterfaceImplGenerator _implGen = null;
@@ -148,6 +152,7 @@
         EMPTY_METAS = newClassMetaDataArray(0);
         EMPTY_FIELDS = newFieldMetaDataArray(0);
         EMPTY_ORDERS = newOrderArray(0);
+        EMPTY_XMLMETAS = newXMLClassMetaDataArray(0);
     }
 
     /**
@@ -786,6 +791,13 @@
     }
 
     /**
+     * Create a new array of the proper xml class metadata subclass.
+     */
+    protected XMLMetaData[] newXMLClassMetaDataArray(int length) {
+        return new XMLClassMetaData[length];
+    }
+
+    /**
      * Create a new embedded class metadata instance.
      */
     protected ClassMetaData newEmbeddedClassMetaData(ValueMetaData owner) {
@@ -1861,9 +1873,67 @@
     /**
      * Return XML metadata for a given field metadata
      * @param fmd
-     * @return null
+     * @return XML metadata
      */
-    public XMLMetaData getXMLMetaData(FieldMetaData fmd) {
-        return null;
+    public synchronized XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+        Class cls = fmd.getDeclaredType();
+        // check if cached before
+        XMLMetaData xmlmeta = (XMLClassMetaData) _xmlmetas.get(cls);
+        if (xmlmeta != null)
+            return xmlmeta;
+        
+        // load JAXB XML metadata
+        _factory.loadXMLMetaData(fmd);
+        
+        xmlmeta = (XMLClassMetaData) _xmlmetas.get(cls);
+
+        return xmlmeta;
+    }
+
+    /**
+     * Create a new metadata, populate it with default information, add it to
+     * the repository, and return it.
+     *
+     * @param access the access type to use in populating metadata
+     */
+    public XMLClassMetaData addXMLMetaData(Class type, String name) {
+        XMLClassMetaData meta = newXMLClassMetaData(type, name);
+        
+        // synchronize on this rather than the map, because all other methods
+        // that access _xmlmetas are synchronized on this
+        synchronized (this) {
+            _xmlmetas.put(type, meta);
+        }
+        return meta;
+    }
+
+    /**
+     * Return the cached XMLClassMetaData for the given class
+     * Return null if none.
+     */
+    public XMLMetaData getCachedXMLMetaData(Class cls) {
+        return (XMLMetaData) _xmlmetas.get(cls);
+    }
+    
+    /**
+     * Create a new xml class metadata
+     * @param type
+     * @param name
+     * @return a XMLClassMetaData
+     */
+    protected XMLClassMetaData newXMLClassMetaData(Class type, String name) {
+        return new XMLClassMetaData(type, name);
+    }
+    
+    /**
+     * Create a new xml field meta, add it to the fieldMap in the given 
+     *     xml class metadata
+     * @param type
+     * @param name
+     * @param meta
+     * @return a XMLFieldMetaData
+     */
+    public XMLFieldMetaData newXMLFieldMetaData(Class type, String name) {
+        return new XMLFieldMetaData(type, name);
     }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java Tue Jul 31 09:19:24 2007
@@ -134,4 +134,7 @@
     public Class getUnimplementedExceptionType() {
         return null;
     }
+    
+    public void loadXMLMetaData(FieldMetaData fmd) {
+    }
 }

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLClassMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLClassMetaData.java?view=auto&rev=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLClassMetaData.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLClassMetaData.java Tue Jul 31 09:19:24 2007
@@ -0,0 +1,125 @@
+/*
+ * 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.meta;
+
+import java.util.HashMap;
+
+import org.apache.commons.lang.StringUtils;
+
+public class XMLClassMetaData implements XMLMetaData     
+{
+    private Class _type;
+    private int _code = JavaTypes.OBJECT;
+    private int _xmltype = XMLTYPE;
+    private String _name = null;
+    private String _xmlname = null;
+    private String _xmlnamespace = null;
+    private boolean _isXMLRootElement = false;
+    private HashMap _fieldMap = new HashMap();
+    
+    /**
+     * Constructor.
+     * 
+     * @param type the class that contains XmlType annotation.
+     * @name  the persistent field name that maps to xml column
+     */
+    public XMLClassMetaData(Class type, String name) {
+        _type = type;
+        _name = name;
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param type the class that contains XmlType annotation.
+     */
+    public XMLClassMetaData(Class type) {
+        _type = type;
+    }
+
+    public void setName(String name) {
+        _name = name;
+    }
+    
+    public String getName() {
+        return _name;
+    }    
+    
+    public void setXmlname(String name) {
+        _xmlname = name;
+    }
+    
+    public String getXmlname() {
+        return _isXMLRootElement ? null : _xmlname;
+    }
+
+    public void setXmlnamespace(String name) {
+        // avoid JAXB XML bind default name
+        if (!StringUtils.equals(defaultName, name))
+            _xmlnamespace = name;
+    }
+    
+    public String getXmlnamespace() {
+        return _xmlnamespace;
+    }
+
+    public void setXmlRootElement(boolean isXMLRootElement) {
+        _isXMLRootElement = isXMLRootElement;        
+    }
+
+    public boolean isXmlRootElement() {
+        return _isXMLRootElement;
+    }
+    
+    public boolean isXmlElement() {
+        return false;
+    }
+    
+    public boolean isXmlAttribute() {
+        return false;
+    }
+    
+    public XMLMetaData getFieldMapping(String name) {
+        return (XMLMetaData) _fieldMap.get(name);
+    }
+    
+    public void setType(Class type) {
+        _type = type;
+    }
+    
+    public Class getType() {
+        return _type;
+    }
+    
+    public int getTypeCode() {
+        return _code;
+    }
+
+    public void setXmltype(int type) {
+        _xmltype = type;
+    }
+
+    public int getXmltype() {
+        return _xmltype;
+    }
+    
+    public void addField(String name, XMLMetaData field) {
+        _fieldMap.put(name, field);
+    }
+}
\ No newline at end of file

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLFieldMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLFieldMetaData.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLFieldMetaData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLFieldMetaData.java Tue Jul 31 09:19:24 2007
@@ -40,6 +40,11 @@
     public XMLFieldMetaData() {        
     }
     
+    public XMLFieldMetaData(Class type, String name) {
+        setType(type);
+        _name = name;
+    }
+    
     public Class getType() {
         return (_type == null) ? _decType : _type;
     }
@@ -107,5 +112,11 @@
     
     public XMLMetaData getFieldMapping(String name) {
         return null;
+    }
+    
+    public void setXmlRootElement(boolean isXmlRootElement) {
+    }
+
+    public void addField(String name, XMLMetaData field) {
     }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLMetaData.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLMetaData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/XMLMetaData.java Tue Jul 31 09:19:24 2007
@@ -116,4 +116,8 @@
      * @return xmltype
      */
     public int getXmltype();
+    
+    public void setXmlRootElement(boolean isXmlRootElement);
+    
+    public void addField(String name, XMLMetaData field);
 }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.java Tue Jul 31 09:19:24 2007
@@ -54,12 +54,6 @@
                 .CustomerKey.class
             , org.apache.openjpa.persistence.xmlmapping.entities.Order.class
             , org.apache.openjpa.persistence.xmlmapping.entities.EAddress.class
-            ,  "openjpa.MetaDataRepository"
-            ,  "org.apache.openjpa.jdbc.meta.XMLMappingRepository"
-//            ,  "openjpa.ConnectionDriverName"
-//            ,  "org.apache.commons.dbcp.BasicDataSource"
-//            ,  "openjpa.ConnectionProperties"
-//            ,  "DriverClassName=com.ibm.db2.jcc.DB2Driver,Url=jdbc:db2:testdb"
             );
     }
 

Modified: openjpa/trunk/openjpa-persistence/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/pom.xml?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-persistence/pom.xml (original)
+++ openjpa/trunk/openjpa-persistence/pom.xml Tue Jul 31 09:19:24 2007
@@ -45,6 +45,11 @@
             <version>1.0</version>
             <scope>compile</scope>
         </dependency>
+	    <dependency>
+		    <groupId>javax.xml.bind</groupId>
+		    <artifactId>jaxb-api</artifactId>
+		    <version>2.0</version>
+	    </dependency>
     </dependencies>
     <build>
         <plugins>

Added: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceXMLMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceXMLMetaDataParser.java?view=auto&rev=561376
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceXMLMetaDataParser.java (added)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceXMLMetaDataParser.java Tue Jul 31 09:19:24 2007
@@ -0,0 +1,234 @@
+/*
+ * 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;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.DelegatingMetaDataFactory;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.MetaDataFactory;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.XMLFieldMetaData;
+import org.apache.openjpa.meta.XMLMetaData;
+
+/**
+ * JAXB xml annotation metadata parser.
+ *
+ * @author Catalina Wei
+ * @nojavadoc
+ */
+public class AnnotationPersistenceXMLMetaDataParser {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (AnnotationPersistenceXMLMetaDataParser.class);
+
+    private final OpenJPAConfiguration _conf;
+    private final Log _log;
+    private MetaDataRepository _repos = null;
+
+    // the class we were invoked to parse
+    private Class _cls = null;
+    private FieldMetaData _fmd = null;
+
+    /**
+     * Constructor; supply configuration.
+     */
+    public AnnotationPersistenceXMLMetaDataParser(OpenJPAConfiguration conf) {
+        _conf = conf;
+        _log = conf.getLog(OpenJPAConfiguration.LOG_METADATA);
+    }
+
+    /**
+     * Configuration supplied on construction.
+     */
+    public OpenJPAConfiguration getConfiguration() {
+        return _conf;
+    }
+
+    /**
+     * Metadata log.
+     */
+    public Log getLog() {
+        return _log;
+    }
+
+    /**
+     * Returns the repository for this parser. If none has been set,
+     * create a new repository and sets it.
+     */
+    public MetaDataRepository getRepository() {
+        if (_repos == null) {
+            MetaDataRepository repos = _conf.newMetaDataRepositoryInstance();
+            MetaDataFactory mdf = repos.getMetaDataFactory();
+            if (mdf instanceof DelegatingMetaDataFactory)
+                mdf = ((DelegatingMetaDataFactory) mdf).getInnermostDelegate();
+            if (mdf instanceof PersistenceMetaDataFactory)
+                ((PersistenceMetaDataFactory) mdf).setXMLAnnotationParser(this);
+            _repos = repos;
+        }
+        return _repos;
+    }
+
+    /**
+     * Set the metadata repository for this parser.
+     */
+    public void setRepository(MetaDataRepository repos) {
+        _repos = repos;
+    }
+
+    /**
+     * Clear caches.
+     */
+    public void clear() {
+        _cls = null;
+        _fmd = null;
+    }
+
+    /**
+     * Parse persistence metadata for the given field metadata.
+     */
+    public void parse(FieldMetaData fmd) {
+        _fmd = fmd;
+        _cls = fmd.getDeclaredType();
+        if (_log.isTraceEnabled())
+            _log.trace(_loc.get("parse-class", _cls.getName()));
+
+        try {
+            parseXMLClassAnnotations();
+        } finally {
+            _cls = null;
+            _fmd = null;
+        }
+    }
+
+    /**
+     * Read annotations for the current type.
+     */
+    private XMLMetaData parseXMLClassAnnotations() {
+        // check immediately whether the class has JAXB XML annotations
+        if (!_cls.isAnnotationPresent(XmlType.class))
+            return null;
+
+        // find / create metadata
+        XMLMetaData meta = getXMLMetaData();
+        
+        return meta;
+    }
+
+    /**
+     * Find or create xml metadata for the current type. 
+     */
+    private synchronized XMLMetaData getXMLMetaData() {
+        XMLMetaData meta = getRepository().getCachedXMLMetaData(_cls);
+        if (meta == null) {
+            // if not in cache, create metadata
+            meta = getRepository().addXMLMetaData(_cls, _fmd.getName());
+            parseXmlRootElement(_cls, meta);
+            populateFromReflection(_cls, meta);
+        }
+        return meta;
+    }
+    
+    private void parseXmlRootElement(Class type, XMLMetaData meta) {
+        if (type.getAnnotation(XmlRootElement.class) != null) {
+            meta.setXmlRootElement(true);
+            meta.setXmlname(((XmlRootElement) type.getAnnotation
+                (XmlRootElement.class)).name());
+            meta.setXmlnamespace(((XmlRootElement) type.getAnnotation
+                (XmlRootElement.class)).namespace());
+        }
+        else {
+            meta.setXmlname(((XmlType) type.getAnnotation
+                (XmlType.class)).name());
+            meta.setXmlnamespace(((XmlType) type.getAnnotation
+                (XmlType.class)).namespace());           
+        }        
+    }
+
+    private void populateFromReflection(Class cls, XMLMetaData meta) {
+        Member[] members;
+        
+        Class superclass = cls.getSuperclass();
+
+        // handle inheritance at sub-element level
+        if (superclass.isAnnotationPresent(XmlType.class))
+            populateFromReflection(superclass, meta);
+
+        if (((XmlAccessorType) cls.getAnnotation(XmlAccessorType.class)).value()
+            == XmlAccessType.FIELD)
+            members = cls.getDeclaredFields();
+        else
+            members = cls.getDeclaredMethods();
+
+        for (int i = 0; i < members.length; i++) {
+            Member member = members[i];
+            AnnotatedElement el = (AnnotatedElement) member;
+            XMLMetaData field = null;
+            if (el.getAnnotation(XmlElement.class) != null) {
+                String xmlname = el.getAnnotation(XmlElement.class).name();
+                // avoid JAXB XML bind default name
+                if (StringUtils.equals(XMLMetaData.defaultName, xmlname))
+                    xmlname = member.getName();
+                if (((Field) member).getType()
+                    .isAnnotationPresent(XmlType.class)) {
+                    field = _repos.addXMLMetaData(((Field) member).getType()
+                        , member.getName());
+                    parseXmlRootElement(((Field) member).getType(), field);
+                    populateFromReflection(((Field) member).getType(), field);
+                    field.setXmltype(XMLMetaData.XMLTYPE);
+                    field.setXmlname(xmlname);
+                }
+                else {
+                    field = _repos.newXMLFieldMetaData(((Field) member)
+                        .getType(), member.getName());
+                    field.setXmltype(XMLMetaData.ELEMENT);
+                    field.setXmlname(xmlname);
+                    field.setXmlnamespace(el.getAnnotation(XmlElement.class)
+                        .namespace());                    
+                }
+            }
+            else if (el.getAnnotation(XmlAttribute.class) != null) {
+                field = _repos.newXMLFieldMetaData(((Field) member).getType()
+                    , member.getName());
+                field.setXmltype(XMLFieldMetaData.ATTRIBUTE);
+                String xmlname = el.getAnnotation(XmlAttribute.class).name();
+                // avoid JAXB XML bind default name
+                if (StringUtils.equals(XMLMetaData.defaultName, xmlname))
+                    xmlname = member.getName();
+                field.setXmlname("@"+xmlname);
+                field.setXmlnamespace(el.getAnnotation(XmlAttribute.class)
+                    .namespace());                
+            }
+            meta.addField(member.getName(), field);
+        }        
+    }
+}

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataFactory.java?view=diff&rev=561376&r1=561375&r2=561376
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataFactory.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataFactory.java Tue Jul 31 09:19:24 2007
@@ -56,6 +56,7 @@
 import org.apache.openjpa.meta.MetaDataFactory;
 import org.apache.openjpa.meta.QueryMetaData;
 import org.apache.openjpa.meta.SequenceMetaData;
+import org.apache.openjpa.meta.XMLMetaData;
 import org.apache.openjpa.util.GeneralException;
 import org.apache.openjpa.util.MetaDataException;
 
@@ -75,6 +76,7 @@
     private final PersistenceMetaDataDefaults _def = 
         new PersistenceMetaDataDefaults();
     private AnnotationPersistenceMetaDataParser _annoParser = null;
+    private AnnotationPersistenceXMLMetaDataParser _annoXMLParser = null;
     private XMLPersistenceMetaDataParser _xmlParser = null;
     private Map<URL, Set> _xml = null; // xml rsrc -> class names
     private Set<URL> _unparsed = null; // xml rsrc
@@ -466,5 +468,43 @@
 
     public void setInto(Options opts) {
         opts.keySet().retainAll(opts.setInto(_def).keySet());
+    }
+
+    /**
+     * Return JAXB XML annotation parser, 
+     * creating it if it does not already exist.
+     */
+    public AnnotationPersistenceXMLMetaDataParser getXMLAnnotationParser() {
+        if (_annoXMLParser == null) {
+            _annoXMLParser = newXMLAnnotationParser();
+            _annoXMLParser.setRepository(repos);
+        }
+        return _annoXMLParser;
+    }
+
+    /**
+     * Set the JAXB XML annotation parser.
+     */
+    public void setXMLAnnotationParser(
+        AnnotationPersistenceXMLMetaDataParser parser) {
+        if (_annoXMLParser != null)
+            _annoXMLParser.setRepository(null);
+        if (parser != null)
+            parser.setRepository(repos);
+        _annoXMLParser = parser;
+    }
+
+    /**
+     * Create a new JAXB XML annotation parser.
+     */
+    protected AnnotationPersistenceXMLMetaDataParser newXMLAnnotationParser() {
+        return new AnnotationPersistenceXMLMetaDataParser
+            (repos.getConfiguration());
+    }
+
+    public void loadXMLMetaData(FieldMetaData fmd) {
+        AnnotationPersistenceXMLMetaDataParser parser
+            = getXMLAnnotationParser();
+        parser.parse(fmd);
     }
 }