cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r396882 [7/11] - in /incubator/cayenne: branches/ tags/ trunk/ trunk/cayenne-jpa-tck/ trunk/cayenne-jpa-tck/.settings/ trunk/cayenne-jpa-tck/src/ trunk/cayenne-jpa-tck/src/main/ trunk/cayenne-jpa-tck/src/main/java/ trunk/cayenne-jpa-tck/src...
Date Wed, 26 Apr 2006 20:58:50 GMT
Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaTableGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaTableGenerator.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaTableGenerator.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaTableGenerator.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,201 @@
+/* ====================================================================
+ * 
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ * 
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ * 
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ * 
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ * 
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.jpa.map;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.TableGenerator;
+
+/**
+ * A primary key generator based on a database table.
+ * 
+ * @author Andrus Adamchik
+ */
+public class JpaTableGenerator {
+
+    protected String name;
+    protected String table;
+    protected String catalog;
+    protected String schema;
+    protected String pkColumnName;
+    protected String valueColumnName;
+    protected String pkColumnValue;
+    protected int initialValue = 0;
+    protected int allocationSize = 50;
+
+    protected Collection<JpaUniqueConstraint> uniqueConstraints;
+
+    public JpaTableGenerator() {
+
+    }
+
+    public JpaTableGenerator(TableGenerator annotation) {
+        name = annotation.name();
+        table = annotation.table();
+        catalog = annotation.catalog();
+        schema = annotation.schema();
+        pkColumnName = annotation.pkColumnName();
+        valueColumnName = annotation.valueColumnName();
+        pkColumnValue = annotation.pkColumnValue();
+        initialValue = annotation.initialValue();
+        allocationSize = annotation.allocationSize();
+
+        getUniqueConstraints();
+        for (int i = 0; i < annotation.uniqueConstraints().length; i++) {
+            uniqueConstraints.add(new JpaUniqueConstraint(
+                    annotation.uniqueConstraints()[i]));
+        }
+    }
+
+    public int getAllocationSize() {
+        return allocationSize;
+    }
+
+    public void setAllocationSize(int allocationSize) {
+        this.allocationSize = allocationSize;
+    }
+
+    public String getCatalog() {
+        return catalog;
+    }
+
+    public void setCatalog(String catalog) {
+        this.catalog = catalog;
+    }
+
+    public int getInitialValue() {
+        return initialValue;
+    }
+
+    public void setInitialValue(int initialValue) {
+        this.initialValue = initialValue;
+    }
+
+    /**
+     * Returns table generator name.
+     * <h3>Specification Documenatation</h3>
+     * <p>
+     * <b>Description:</b> A unique generator name that can be referenced by one or more
+     * classes to be the generator for id values.
+     * </p>
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPkColumnName() {
+        return pkColumnName;
+    }
+
+    public void setPkColumnName(String pkColumnName) {
+        this.pkColumnName = pkColumnName;
+    }
+
+    public String getPkColumnValue() {
+        return pkColumnValue;
+    }
+
+    public void setPkColumnValue(String pkColumnValue) {
+        this.pkColumnValue = pkColumnValue;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public void setSchema(String schema) {
+        this.schema = schema;
+    }
+
+    /**
+     * Returns table generator table name.
+     * <h3>Specification Documentation</h3>
+     * <p>
+     * <b>Description:</b> Name of table that stores the generated id value.
+     * </p>
+     * <p>
+     * <b>Default:</b> Name is chosen by persistence provider.
+     * </p>
+     */
+    public String getTable() {
+        return table;
+    }
+
+    public void setTable(String table) {
+        this.table = table;
+    }
+
+    public String getValueColumnName() {
+        return valueColumnName;
+    }
+
+    public void setValueColumnName(String valueColumnName) {
+        this.valueColumnName = valueColumnName;
+    }
+
+    public Collection<JpaUniqueConstraint> getUniqueConstraints() {
+        if (uniqueConstraints == null) {
+            uniqueConstraints = new ArrayList<JpaUniqueConstraint>(2);
+        }
+
+        return uniqueConstraints;
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaUniqueConstraint.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaUniqueConstraint.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaUniqueConstraint.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/map/JpaUniqueConstraint.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,86 @@
+/* ====================================================================
+ * 
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ * 
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ * 
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ * 
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ * 
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.jpa.map;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.UniqueConstraint;
+
+public class JpaUniqueConstraint {
+
+    protected Collection<String> columnNames;
+
+    public JpaUniqueConstraint() {
+
+    }
+
+    public JpaUniqueConstraint(UniqueConstraint annotation) {
+        // resolve collection
+        getColumnNames();
+
+        for (int i = 0; i < annotation.columnNames().length; i++) {
+            columnNames.add(annotation.columnNames()[i]);
+        }
+    }
+
+    public Collection<String> getColumnNames() {
+        if (columnNames == null) {
+            columnNames = new ArrayList<String>(2);
+        }
+        return columnNames;
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JndiJpaDataSourceFactory.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JndiJpaDataSourceFactory.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JndiJpaDataSourceFactory.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JndiJpaDataSourceFactory.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,36 @@
+package org.objectstyle.cayenne.jpa.spi;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.sql.DataSource;
+
+
+/**
+ * A JNDI-based implementation of the JPADataSourceFactory.
+ * 
+ * @author Andrus Adamchik
+ */
+public class JndiJpaDataSourceFactory implements JpaDataSourceFactory {
+
+    public DataSource getJtaDataSource(String name, PersistenceUnitInfo info) {
+        return getDataSource(name);
+    }
+
+    public DataSource getNonJtaDataSource(String name, PersistenceUnitInfo info) {
+        return getDataSource(name);
+    }
+
+    protected DataSource getDataSource(String name) {
+        if (name == null) {
+            return null;
+        }
+
+        try {
+            return (DataSource) new InitialContext().lookup(name);
+        }
+        catch (NamingException namingEx) {
+            return null;
+        }
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaDataSourceFactory.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaDataSourceFactory.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaDataSourceFactory.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaDataSourceFactory.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,16 @@
+package org.objectstyle.cayenne.jpa.spi;
+
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.sql.DataSource;
+
+/**
+ * A factory that provides DataSources to PersistenceUnitInfo instances.
+ * 
+ * @author Andrus Adamchik
+ */
+public interface JpaDataSourceFactory {
+
+    DataSource getJtaDataSource(String name, PersistenceUnitInfo info);
+
+    DataSource getNonJtaDataSource(String name, PersistenceUnitInfo info);
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceProvider.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceProvider.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceProvider.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceProvider.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,87 @@
+package org.objectstyle.cayenne.jpa.spi;
+
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
+import org.objectstyle.cayenne.jpa.conf.PersistenceUnitLoader;
+
+/**
+ * <code>PersistenceProvider</code> implementation that doesn't provide its own ORM
+ * stack. Useful as a base implementation of concrete providers.
+ * 
+ * @author Andrus Adamchik
+ */
+public abstract class JpaPersistenceProvider implements PersistenceProvider {
+
+    // common properties
+    public static final String PROVIDER_PROPERTY = "javax.persistence.provider";
+    public static final String TRANSACTION_TYPE_PROPERTY = "javax.persistence.transactionType";
+    public static final String JTA_DATA_SOURCE_PROPERTY = "javax.persistence.jtaDataSource";
+    public static final String NON_JTA_DATA_SOURCE_PROPERTY = "javax.persistence.nonJtaDataSource ";
+
+    // provider-specific properties
+    public static final String DATA_SOURCE_FACTORY_PROPERTY = "org.objectstyle.cayenne.jpa.jpaDataSourceFactory";
+
+    protected PersistenceUnitLoader unitLoader;
+    protected Properties defaultProperties;
+
+    /**
+     * Creates a new JpaPersistenceProvider configuring it with default appropriate for
+     * running in conatiner.
+     */
+    public JpaPersistenceProvider() {
+        this(false);
+    }
+
+    /**
+     * A constructor that allows to specify whether descriptors should be validated
+     * against schema.
+     */
+    public JpaPersistenceProvider(boolean validateDescriptors) {
+        this.defaultProperties = new Properties();
+        this.unitLoader = new PersistenceUnitLoader(validateDescriptors);
+
+        defaultProperties.put(
+                DATA_SOURCE_FACTORY_PROPERTY,
+                JndiJpaDataSourceFactory.class.getName());
+        defaultProperties.put(
+                TRANSACTION_TYPE_PROPERTY,
+                PersistenceUnitTransactionType.JTA.name());
+    }
+
+    public EntityManagerFactory createEntityManagerFactory(String emName, Map map) {
+
+        // TODO: Andrus, 2/11/2006 - cache loaded units (or factories)...
+
+        JpaPersistenceUnitInfo ui = unitLoader.getInfo(emName);
+
+        if (ui == null) {
+            return null;
+        }
+
+        // override properties
+        if (map != null) {
+            ui.addProperties(map);
+        }
+
+        // check if we are allowed to handle this unit (JPA Spec, 7.2)
+        String provider = ui.getPersistenceProviderClassName();
+        if (provider != null && !provider.equals(this.getClass().getName())) {
+            return null;
+        }
+
+        return createContainerManagerFactory(ui);
+    }
+
+    public abstract EntityManagerFactory createContainerManagerFactory(
+            PersistenceUnitInfo info);
+
+    public String getDefaultProperty(String key) {
+        return defaultProperties.getProperty(key);
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceUnitInfo.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceUnitInfo.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceUnitInfo.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/JpaPersistenceUnitInfo.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,207 @@
+package org.objectstyle.cayenne.jpa.spi;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.spi.ClassTransformer;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.sql.DataSource;
+
+/**
+ * A java bean that provides access to persistent unit properties per
+ * <code>javax.persistence.spi.PersistenceUnitInfo</code> interface.
+ * 
+ * @author Andrus Adamchik
+ */
+public class JpaPersistenceUnitInfo implements PersistenceUnitInfo {
+
+    // spec defaults
+    static final PersistenceUnitTransactionType DEFAULT_TRANSACTION_TYPE = PersistenceUnitTransactionType.JTA;
+
+    protected JpaPersistenceProvider provider;
+
+    protected String persistenceUnitName;
+    protected List<String> mappingFileNames;
+    protected List<URL> jarFileUrls;
+    protected List<String> managedClassNames;
+    protected URL persistenceUnitRootUrl;
+    protected boolean excludeUnlistedClasses;
+    protected Properties properties;
+    protected String description;
+
+    // properties not exposed directly
+    protected List<ClassTransformer> classTransformers;
+    protected ClassLoader classLoader;
+
+    public JpaPersistenceUnitInfo() {
+        this(null);
+    }
+
+    public JpaPersistenceUnitInfo(JpaPersistenceProvider provider) {
+        this.provider = provider;
+
+        this.mappingFileNames = new ArrayList<String>(2);
+        this.jarFileUrls = new ArrayList<URL>(2);
+        this.managedClassNames = new ArrayList<String>(30);
+        this.properties = new Properties();
+        this.classTransformers = new ArrayList<ClassTransformer>(2);
+        this.classLoader = Thread.currentThread().getContextClassLoader();
+    }
+
+    public String getPersistenceUnitName() {
+        return persistenceUnitName;
+    }
+
+    public String getPersistenceProviderClassName() {
+        return getProperty(JpaPersistenceProvider.PROVIDER_PROPERTY);
+    }
+
+    public PersistenceUnitTransactionType getTransactionType() {
+        String type = getProperty(JpaPersistenceProvider.TRANSACTION_TYPE_PROPERTY);
+        return type != null
+                ? PersistenceUnitTransactionType.valueOf(type)
+                : DEFAULT_TRANSACTION_TYPE;
+    }
+
+    String getProperty(String key) {
+        String property = properties.getProperty(key);
+        return property != null || provider == null ? property : provider
+                .getDefaultProperty(key);
+    }
+
+    JpaDataSourceFactory getJpaDataSourceFactory() {
+        String factory = getProperty(JpaPersistenceProvider.DATA_SOURCE_FACTORY_PROPERTY);
+
+        try {
+            return (JpaDataSourceFactory) Class.forName(
+                    factory,
+                    true,
+                    Thread.currentThread().getContextClassLoader()).newInstance();
+        }
+        catch (Throwable th) {
+            throw new RuntimeException("Error instantiating a JPADataSourceFactory: "
+                    + factory, th);
+        }
+    }
+
+    public DataSource getJtaDataSource() {
+        String name = getProperty(JpaPersistenceProvider.JTA_DATA_SOURCE_PROPERTY);
+        return getJpaDataSourceFactory().getJtaDataSource(name, this);
+    }
+
+    public DataSource getNonJtaDataSource() {
+        String name = getProperty(JpaPersistenceProvider.NON_JTA_DATA_SOURCE_PROPERTY);
+        return getJpaDataSourceFactory().getNonJtaDataSource(name, this);
+    }
+
+    public List<String> getMappingFileNames() {
+        return mappingFileNames;
+    }
+
+    public List<URL> getJarFileUrls() {
+        return jarFileUrls;
+    }
+
+    public URL getPersistenceUnitRootUrl() {
+        return persistenceUnitRootUrl;
+    }
+
+    public List<String> getManagedClassNames() {
+        return managedClassNames;
+    }
+
+    /**
+     * Returns whether classes not listed in the persistence.xml descriptor file should be
+     * excluded from persistence unit. Should be ignored in J2SE environment.
+     */
+    public boolean excludeUnlistedClasses() {
+        return excludeUnlistedClasses;
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public ClassLoader getClassLoader() {
+        return classLoader;
+    }
+
+    public void addTransformer(ClassTransformer transformer) {
+        classTransformers.add(transformer);
+    }
+
+    /**
+     * Creates and returns a child of the main unit ClassLoader.
+     */
+    public ClassLoader getNewTempClassLoader() {
+        return new URLClassLoader(new URL[0], classLoader);
+    }
+
+    public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses) {
+        this.excludeUnlistedClasses = excludeUnlistedClasses;
+    }
+
+    public void addJarFileUrl(String jarName) {
+        // resolve URLs relative to the unit root
+
+        if (persistenceUnitRootUrl == null) {
+            throw new IllegalStateException("Persistence Unit Root URL is not set");
+        }
+
+        try {
+            this.jarFileUrls.add(new URL(persistenceUnitRootUrl, jarName));
+        }
+        catch (MalformedURLException e) {
+            throw new IllegalArgumentException("Invalid Jar file name:" + jarName, e);
+        }
+    }
+
+    public void setPersistenceUnitName(String persistenceUnitName) {
+        this.persistenceUnitName = persistenceUnitName;
+    }
+
+    /**
+     * Sets new "main" ClassLoader of this unit.
+     */
+    public void setClassLoader(ClassLoader classLoader) {
+        if (classLoader == null) {
+            classLoader = Thread.currentThread().getContextClassLoader();
+        }
+
+        this.classLoader = classLoader;
+    }
+
+    public void addManagedClassName(String managedClassName) {
+        this.managedClassNames.add(managedClassName);
+    }
+
+    public void addMappingFileName(String mappingFileName) {
+        this.mappingFileNames.add(mappingFileName);
+    }
+
+    public void setPersistenceUnitRootUrl(URL persistenceUnitRootUrl) {
+        this.persistenceUnitRootUrl = persistenceUnitRootUrl;
+    }
+
+    public void addProperties(Map properties) {
+        this.properties.putAll(properties);
+    }
+
+    public void putProperty(String key, String value) {
+        this.properties.put(key, value);
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/TransformingClassLoader.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/TransformingClassLoader.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/TransformingClassLoader.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/jpa/spi/TransformingClassLoader.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,129 @@
+package org.objectstyle.cayenne.jpa.spi;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.SecureClassLoader;
+
+import javax.persistence.spi.ClassTransformer;
+
+/**
+ * A ClassLoader that transforms loaded classes using ClassTransformers from
+ * CayennePersisteceUnitInfo.
+ * 
+ * @author Andrus Adamchik
+ */
+class TransformingClassLoader extends SecureClassLoader {
+
+    JpaPersistenceUnitInfo owner;
+
+    TransformingClassLoader(JpaPersistenceUnitInfo owner, ClassLoader parent) {
+        super(parent);
+        this.owner = owner;
+    }
+
+    /**
+     * Returns true if the class does not need to be enhanced.
+     */
+    protected boolean skipClassEnhancement(String className) {
+        return owner.classTransformers.isEmpty()
+                || !owner.getManagedClassNames().contains(className);
+    }
+
+    @Override
+    protected synchronized Class<?> loadClass(String name, boolean resolve)
+            throws ClassNotFoundException {
+
+        if (skipClassEnhancement(name)) {
+            return super.loadClass(name, resolve);
+        }
+
+        Class c = findLoadedClass(name);
+
+        if (c == null) {
+            c = findClass(name);
+        }
+
+        if (resolve) {
+            resolveClass(c);
+        }
+
+        return c;
+    }
+
+    /**
+     * If a class name is one of the managed classes, loads it
+     */
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        if (skipClassEnhancement(name)) {
+            return Class.forName(name, true, getParent());
+        }
+        else {
+            return findManagedClass(name);
+        }
+    }
+
+    /**
+     * Loads class bytes, and passes them through the registered ClassTransformers.
+     */
+    protected Class<?> findManagedClass(String name) throws ClassNotFoundException {
+        String path = name.replace('.', '/') + ".class";
+
+        InputStream in = getResourceAsStream(path);
+        if (in == null) {
+            return Class.forName(name, true, getParent());
+        }
+
+        try {
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+            byte[] buffer = new byte[1024];
+            int read;
+
+            while ((read = in.read(buffer, 0, 1024)) > 0) {
+                out.write(buffer, 0, read);
+            }
+
+            out.close();
+            byte[] classBytes = out.toByteArray();
+
+            for (ClassTransformer transformer : owner.classTransformers) {
+                // TODO: Andrus, 2/10/2006 - ProtectionDomain
+
+                byte[] bytes;
+                try {
+                    bytes = transformer.transform(
+                            getParent(),
+                            name,
+                            null,
+                            null,
+                            classBytes);
+                }
+                catch (IllegalClassFormatException e) {
+                    throw new ClassNotFoundException("Could not transform class '"
+                            + name
+                            + "' due to invalid format", e);
+                }
+
+                if (bytes != null) {
+                    classBytes = bytes;
+                }
+            }
+
+            return defineClass(name, classBytes, 0, classBytes.length);
+        }
+        catch (IOException e) {
+            throw new ClassNotFoundException(name, e);
+        }
+        finally {
+            try {
+                in.close();
+            }
+            catch (IOException e) {
+                // ignore close exceptions...
+            }
+        }
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/BaseTreeVisitor.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/BaseTreeVisitor.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/BaseTreeVisitor.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/BaseTreeVisitor.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,113 @@
+/* ====================================================================
+ * 
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ * 
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ * 
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ * 
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ * 
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.objectstyle.cayenne.project.ProjectPath;
+
+/**
+ * A common superclass for specialized tree visitors. Can also be used as a noop
+ * pass-through visitor for nodes that need no processing by themselves.
+ * 
+ * @author Andrus Adamchik
+ */
+// TODO, andrus, 4/24/2006 - move to Cayenne core in 2.0
+public class BaseTreeVisitor implements HierarchicalTreeVisitor {
+
+    protected Map childVisitors;
+    protected boolean terminatingOnNoChildVisitor;
+
+    public BaseTreeVisitor() {
+        this.terminatingOnNoChildVisitor = true;
+    }
+
+    public boolean isTerminatingOnNoChildVisitor() {
+        return terminatingOnNoChildVisitor;
+    }
+
+    public void setTerminatingOnNoChildVisitor(boolean terminatingOnNoChildVisitor) {
+        this.terminatingOnNoChildVisitor = terminatingOnNoChildVisitor;
+    }
+
+    public HierarchicalTreeVisitor childVisitor(ProjectPath path, Class childType) {
+        if (childVisitors == null) {
+            return terminatingOnNoChildVisitor ? null : this;
+        }
+
+        HierarchicalTreeVisitor childVisitor = (HierarchicalTreeVisitor) childVisitors
+                .get(childType.getName());
+        return childVisitor != null ? childVisitor : terminatingOnNoChildVisitor
+                ? null
+                : this;
+    }
+
+    public void onFinishNode(ProjectPath path) {
+    }
+
+    public boolean onStartNode(ProjectPath path) {
+        return true;
+    }
+
+    public void addChildVisitor(Class childClass, HierarchicalTreeVisitor visitor) {
+        if (childVisitors == null) {
+            childVisitors = new HashMap();
+        }
+
+        childVisitors.put(childClass.getName(), visitor);
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/HierarchicalTreeVisitor.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/HierarchicalTreeVisitor.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/HierarchicalTreeVisitor.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/HierarchicalTreeVisitor.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,86 @@
+/* ====================================================================
+ * 
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ * 
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ * 
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ * 
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ * 
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.util;
+
+import org.objectstyle.cayenne.project.ProjectPath;
+
+/**
+ * A hierarchical visitor interface used for tree structures traversal.
+ * 
+ * @author Andrus Adamchik
+ */
+//TODO, andrus, 4/24/2006 - move to Cayenne core in 2.0
+public interface HierarchicalTreeVisitor {
+
+    /**
+     * Invoked in the beginning of the element subtree traversal. Traversal is done in a
+     * depth-first manner, so returning false from this method would suppress child
+     * elements traversal.
+     */
+    boolean onStartNode(ProjectPath path);
+
+    /**
+     * Invoked at the end of the annotation tree traversal, which is done in a depth-first
+     * manner.
+     */
+    void onFinishNode(ProjectPath path);
+
+    /**
+     * Returns an instance of the child visitor for a given project path and a type of
+     * child. Returning null would result in skipping the particular child type.
+     */
+    HierarchicalTreeVisitor childVisitor(ProjectPath path, Class childType);
+}
\ No newline at end of file

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversableTreeNode.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversableTreeNode.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversableTreeNode.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversableTreeNode.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,73 @@
+/* ====================================================================
+ * 
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ * 
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ * 
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ * 
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ * 
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.util;
+
+/**
+ * An API of an non-leaf tree object that supports traversal with
+ * {@link org.objectstyle.cayenne.util.TraversalUtil}. Note that leaf nodes do not need
+ * to implement this interface.
+ * 
+ * @author Andrus Adamchik
+ */
+public interface TraversableTreeNode {
+
+    Class[] getTraversableChildTypes();
+
+    /**
+     * Returns either a single object or a collection of children for a given type.
+     */
+    Object getTraversableChild(int nodeTypeIndex);
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversalUtil.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversalUtil.java?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversalUtil.java (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/java/org/objectstyle/cayenne/util/TraversalUtil.java Tue Apr 25 06:43:00 2006
@@ -0,0 +1,125 @@
+/* ====================================================================
+ * 
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ * 
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ * 
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ * 
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ * 
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.util;
+
+import java.util.Collection;
+
+import org.objectstyle.cayenne.project.ProjectPath;
+
+/**
+ * Defines tree traversal utility methods.
+ * 
+ * @author Andrus Adamchik
+ */
+public class TraversalUtil {
+
+    /**
+     * Performs tree traversal with a given visitor. Any tree node object that implements
+     * {@link TraversableTreeNode} will have its children traversed as well.
+     */
+    public static void traverse(Object treeRoot, HierarchicalTreeVisitor visitor) {
+        traverse(treeRoot, visitor, null);
+    }
+
+    static void traverse(
+            Object node,
+            HierarchicalTreeVisitor visitor,
+            ProjectPath parentPath) {
+
+        ProjectPath path = parentPath != null
+                ? parentPath.appendToPath(node)
+                : new ProjectPath(node);
+
+        if (visitor.onStartNode(path)) {
+
+            if (node instanceof TraversableTreeNode) {
+
+                TraversableTreeNode treeNode = (TraversableTreeNode) node;
+
+                Class[] childTypes = treeNode.getTraversableChildTypes();
+                if (childTypes != null && childTypes.length > 0) {
+                    for (int i = 0; i < childTypes.length; i++) {
+
+                        HierarchicalTreeVisitor childVisitor = visitor.childVisitor(
+                                path,
+                                childTypes[i]);
+                        if (childVisitor != null) {
+                            Object child = treeNode.getTraversableChild(i);
+
+                            if (child == null) {
+                                continue;
+                            }
+                            else if (child instanceof Collection) {
+                                Collection children = (Collection) child;
+
+                                if (children != null && !children.isEmpty()) {
+                                    for (Object collectionChild : children) {
+                                        traverse(collectionChild, childVisitor, path);
+                                    }
+                                }
+                            }
+                            else {
+                                traverse(child, childVisitor, path);
+                            }
+                        }
+                    }
+                }
+            }
+
+            visitor.onFinishNode(path);
+        }
+    }
+}

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/orm-coder.xml
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/orm-coder.xml?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/orm-coder.xml (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/orm-coder.xml Tue Apr 25 06:43:00 2006
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- A mapping from orm_1_0.xsd to Cayenne JPA mapping objects used by Cayenne XML coding classes. -->
+<model>
+	
+	<!-- ROOT Element - must be listed first in the mapping per mapping descriptor spec. -->
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEntityMap" xmlTag="entity-mappings">
+		
+		<property name="entities" xmlTag="entity"/>
+		<property name="embeddables" xmlTag="embeddable"/>
+		<property name="mappedSuperclasses" xmlTag="mapped-superclass"/>
+		<property name="namedQueries" xmlTag="named-query"/>
+		<property name="namedNativeQueries" xmlTag="named-native-query"/>
+		<property name="sqlResultSetMappings" xmlTag="sql-result-set-mapping"/>
+		<property name="sequenceGenerators" xmlTag="sequence-generator"/>
+		<property name="tableGenerators" xmlTag="table-generator"/>
+		<property name="defaultEntityListeners" xmlTag="default-entity-listeners"/>
+		<property name="cascades" xmlTag="cascade"/>
+		
+		<property name="packageName" xmlTag="package" attribute="YES"/>
+		<property name="catalog" xmlTag="catalog" attribute="YES"/>
+		<property name="schema" xmlTag="schema" attribute="YES"/>
+		<property name="access" xmlTag="access" attribute="YES"/>
+		<property name="flushMode" xmlTag="flush-mode" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaAttribute" xmlTag="attribute">
+		<property name="basic" xmlTag="basic"/>
+		<property name="version" xmlTag="version"/>
+		<property name="manyToOne" xmlTag="many-to-one"/>
+		<property name="oneToMany" xmlTag="one-to-many"/>
+		<property name="oneToOne" xmlTag="one-to-one"/>
+		<property name="manyToMany" xmlTag="many-to-many"/>
+		<property name="embedded" xmlTag="embedded"/>
+		<property name="transient" xmlTag="transient"/>
+		
+		<property name="column" xmlTag="column"/>
+		<property name="joinColumns" xmlTag="join-column"/>
+		<property name="joinTable" xmlTag="join-table"/>
+		
+		<property name="lobTrue" xmlTag="lob"/>
+		<property name="temporal" xmlTag="temporal"/>
+		<property name="enumerated" xmlTag="enumerated"/>
+		<property name="mapKey" xmlTag="map-key"/>
+		<property name="orderBy" xmlTag="order-by"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaAttributeOverride" xmlTag="attribute-override">
+		<property name="column" xmlTag="column"/>
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaBasic" xmlTag="basic">
+		<property name="fetch" xmlTag="fetch" attribute="YES"/>
+		<property name="optional" xmlTag="optional" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaColumn" xmlTag="column">
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="unique" xmlTag="unique" attribute="YES"/>
+		<property name="nullable" xmlTag="nullable" attribute="YES"/>
+		<property name="insertable" xmlTag="insertable" attribute="YES"/>
+		<property name="updatable" xmlTag="updatable" attribute="YES"/>
+		<property name="columnDefinition" xmlTag="column-definition" attribute="YES"/>
+		<property name="table" xmlTag="table" attribute="YES"/>
+		<property name="length" xmlTag="length" attribute="YES"/>
+		<property name="precision" xmlTag="precision" attribute="YES"/>
+		<property name="scale" xmlTag="scale" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaColumnResult" xmlTag="column-result">
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaDiscriminatorColumn" xmlTag="discriminator-column">
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="discriminatorType" xmlTag="discriminator-type" attribute="YES"/>
+		<property name="columnDefinition" xmlTag="column-definition" attribute="YES"/>
+		<property name="length" xmlTag="length" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEmbeddedId" xmlTag="embedded-id">
+		<property name="attributeOverrides" xmlTag="attribute-override"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEmbeddable" xmlTag="embeddable">
+		<property name="className" xmlTag="class" attribute="YES"/>
+		<property name="access" xmlTag="access" attribute="YES"/>
+		
+		<property name="embeddableAttributes" xmlTag="embeddable-attribute"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEmbeddableAttribute" xmlTag="embeddable-attribute">
+		<property name="basic" xmlTag="basic"/>
+		<property name="lobTrue" xmlTag="lob"/>
+		<property name="temporal" xmlTag="temporal"/>
+		<property name="enumerated" xmlTag="enumerated"/>
+		<property name="column" xmlTag="column"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEntity" xmlTag="entity">
+		<property name="table" xmlTag="table"/>
+		<property name="secondaryTables" xmlTag="secondary-table"/>
+		<property name="primaryKeyJoinColumns" xmlTag="primary-key-join-column"/>
+		<property name="idClassName" xmlTag="id-class"/>
+		<property name="inheritance" xmlTag="inheritance"/>
+		<property name="discriminatorValue" xmlTag="discriminator-value"/>
+		<property name="discriminatorColumn" xmlTag="discriminator-column"/>
+		<property name="sequenceGenerator" xmlTag="sequence-generator"/>
+		<property name="tableGenerator" xmlTag="table-generator"/>
+		<property name="attributeOverrides" xmlTag="attribute-override"/>
+		<property name="namedQueries" xmlTag="named-query"/>
+		<property name="namedNativeQueries" xmlTag="named-native-query"/>
+		<property name="sqlResultSetMapping" xmlTag="sql-result-set-mapping"/>
+		<property name="excludeDefaultListeners" xmlTag="exclude-default-listeners"/>
+		<property name="excludeSuperclassListeners" xmlTag="exclude-superclass-listeners"/>
+		<property name="entityListeners" xmlTag="entity-listeners"/>
+		<property name="prePersist" xmlTag="pre-persist"/>
+		<property name="postPersist" xmlTag="post-persist"/>
+		<property name="preRemove" xmlTag="pre-remove"/>
+		<property name="postRemove" xmlTag="post-remove"/>
+		<property name="preUpdate" xmlTag="pre-update"/>
+		<property name="postUpdate" xmlTag="post-update"/>
+		<property name="postLoad" xmlTag="post-load"/>
+		<property name="ids" xmlTag="id"/>
+		<property name="embeddedId" xmlTag="embedded-id"/>
+		<property name="attributes" xmlTag="attribute"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="className" xmlTag="class" attribute="YES"/>
+		<property name="access" xmlTag="access" attribute="YES"/>
+	</entity>
+
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEntityListener" xmlTag="entity-listener">
+		<property name="prePersist" xmlTag="pre-persist"/>
+		<property name="postPersist" xmlTag="post-persist"/>
+		<property name="preRemove" xmlTag="pre-remove"/>
+		<property name="postRemove" xmlTag="post-remove"/>
+		<property name="preUpdate" xmlTag="pre-update"/>
+		<property name="postUpdate" xmlTag="post-update"/>
+		<property name="postLoad" xmlTag="post-load"/>
+		
+		<property name="className" xmlTag="class" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEntityListeners" xmlTag="entity-listeners">
+		<property name="entityListeners" xmlTag="entity-listener"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEntityListeners" xmlTag="default-entity-listeners">
+		<property name="entityListeners" xmlTag="entity-listener"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaEntityResult" xmlTag="entity-result">
+		<property name="fieldResults" xmlTag="field-result"/>
+		
+		<property name="entityClassName" xmlTag="entity-class" attribute="YES"/>
+		<property name="discriminatorColumn" xmlTag="discriminator-column" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaFieldResult" xmlTag="field-result">
+		<property name="column" xmlTag="column" attribute="YES"/>
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaGeneratedValue" xmlTag="generated-value">
+		<property name="strategy" xmlTag="strategy" attribute="YES"/>
+		<property name="generator" xmlTag="generator" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaId" xmlTag="id">
+		<property name="column" xmlTag="column"/>
+		<property name="generatedValue" xmlTag="generated-value"/>
+		<property name="temporal" xmlTag="temporal"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaInheritance" xmlTag="inheritance">
+		<property name="strategy" xmlTag="strategy" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaJoinColumn" xmlTag="join-column">
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="referencedColumnName" xmlTag="referenced-column-name" attribute="YES"/>
+		<property name="unique" xmlTag="unique" attribute="YES"/>
+		<property name="nullable" xmlTag="nullable" attribute="YES"/>
+		<property name="insertable" xmlTag="insertable" attribute="YES"/>
+		<property name="updatable" xmlTag="updatable" attribute="YES"/>
+		<property name="columnDefinition" xmlTag="column-definition" attribute="YES"/>
+		<property name="table" xmlTag="table" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaJoinTable" xmlTag="join-table">
+		<property name="joinColumns" xmlTag="join-column"/>
+		<property name="inverseJoinColumns" xmlTag="inverse-join-column"/>
+		<property name="uniqueConstraints" xmlTag="unique-constraint"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="catalog" xmlTag="catalog" attribute="YES"/>
+		<property name="schema" xmlTag="schema" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="pre-persist">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="post-persist">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="pre-remove">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="post-remove">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="pre-update">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="post-update">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaLifecycleCallback" xmlTag="post-load">
+		<property name="methodName" xmlTag="method-name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaManyToMany" xmlTag="many-to-many">
+		<property name="cascades" xmlTag="cascade"/>
+		<property name="targetEntityName" xmlTag="target-entity" attribute="YES"/>
+		<property name="fetch" xmlTag="fetch" attribute="YES"/>
+		<property name="mappedBy" xmlTag="mapped-by" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaManyToOne" xmlTag="many-to-one">
+		<property name="cascades" xmlTag="cascade"/>
+		<property name="targetEntityName" xmlTag="target-entity" attribute="YES"/>
+		<property name="fetch" xmlTag="fetch" attribute="YES"/>
+		<property name="optional" xmlTag="optional" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaMappedSuperclass" xmlTag="mapped-superclass">
+		<property name="idClassName" xmlTag="id-class"/>
+		<property name="excludeDefaultListeners" xmlTag="exclude-default-listeners"/>
+		<property name="excludeSuperclassListeners" xmlTag="exclude-superclass-listeners"/>
+		<property name="entityListeners.entityListeners" xmlTag="entity-listener"/>
+		<property name="prePersist" xmlTag="pre-persist"/>
+		<property name="postPersist" xmlTag="post-persist"/>
+		<property name="preRemove" xmlTag="pre-remove"/>
+		<property name="postRemove" xmlTag="post-remove"/>
+		<property name="preUpdate" xmlTag="pre-update"/>
+		<property name="postUpdate" xmlTag="post-update"/>
+		<property name="postLoad" xmlTag="post-load"/>
+		<property name="ids" xmlTag="id"/>
+		<property name="embeddedId" xmlTag="embedded-id"/>
+		<property name="attributes" xmlTag="attribute"/>
+		
+		<property name="className" xmlTag="class" attribute="YES"/>
+		<property name="access" xmlTag="access" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaNamedNativeQuery" xmlTag="named-native-query">
+		<property name="hints" xmlTag="hint"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="query" xmlTag="query" attribute="YES"/>
+		<property name="resultClassName" xmlTag="result-class" attribute="YES"/>
+		<property name="resultSetMapping" xmlTag="result-set-mapping" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaNamedQuery" xmlTag="named-query">
+		<property name="hints" xmlTag="hint"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="query" xmlTag="query" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaOneToMany" xmlTag="one-to-many">
+		<property name="cascades" xmlTag="cascade"/>
+		
+		<property name="targetEntityName" xmlTag="target-entity" attribute="YES"/>
+		<property name="fetch" xmlTag="fetch" attribute="YES"/>
+		<property name="mappedBy" xmlTag="mapped-by" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaOneToOne" xmlTag="one-to-one">
+		<property name="cascades" xmlTag="cascade"/>
+		
+		<property name="targetEntityName" xmlTag="target-entity" attribute="YES"/>
+		<property name="fetch" xmlTag="fetch" attribute="YES"/>
+		<property name="optional" xmlTag="optional" attribute="YES"/>
+		<property name="mappedBy" xmlTag="mapped-by" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaPrimaryKeyJoinColumn" xmlTag="primary-key-join-column">
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="referencedColumnName" xmlTag="referenced-column-name" attribute="YES"/>
+		<property name="columnDefinition" xmlTag="column-definition" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaQueryHint" xmlTag="hint">
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="value" xmlTag="value" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaSecondaryTable" xmlTag="secondary-table">
+		<property name="primaryKeyJoinColumns" xmlTag="primary-key-join-column"/>
+		<property name="uniqueConstraints" xmlTag="unique-constraint"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="catalog" xmlTag="catalog" attribute="YES"/>
+		<property name="schema" xmlTag="schema" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaSequenceGenerator" xmlTag="sequence-generator">
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="sequenceName" xmlTag="sequence-name" attribute="YES"/>
+		<property name="initialValue" xmlTag="initial-value" attribute="YES"/>
+		<property name="allocationSize" xmlTag="allocation-size" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaSqlResultSetMapping" xmlTag="sql-result-set-mapping">
+		<property name="entityResults" xmlTag="entity-result"/>
+		<property name="columnResults" xmlTag="column-result"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaTable" xmlTag="table">
+		<property name="uniqueConstraints" xmlTag="unique-constraint"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="catalog" xmlTag="catalog" attribute="YES"/>
+		<property name="schema" xmlTag="schema" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaTableGenerator" xmlTag="table-generator">
+		<property name="uniqueConstraints" xmlTag="unique-constraint"/>
+		
+		<property name="name" xmlTag="name" attribute="YES"/>
+		<property name="table" xmlTag="table" attribute="YES"/>
+		<property name="catalog" xmlTag="catalog" attribute="YES"/>
+		<property name="schema" xmlTag="schema" attribute="YES"/>
+		<property name="pkColumnName" xmlTag="pk-column-name" attribute="YES"/>
+		<property name="valueColumnName" xmlTag="value-column-name" attribute="YES"/>
+		<property name="pkColumnValue" xmlTag="pk-column-value" attribute="YES"/>
+		<property name="initialValue" xmlTag="initial-value" attribute="YES"/>
+		<property name="allocationSize" xmlTag="allocation-size" attribute="YES"/>
+	</entity>
+	
+	<entity name="org.objectstyle.cayenne.jpa.map.JpaUniqueConstraint" xmlTag="unique-constraint">
+		<property name="columnNames" xmlTag="column-name"/>
+	</entity>
+</model>
\ No newline at end of file

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-subclass.vm
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-subclass.vm?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-subclass.vm (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-subclass.vm Tue Apr 25 06:43:00 2006
@@ -0,0 +1,24 @@
+##  A default Cayenne template for a client-side subclass in a generated subclass/superclass pair.
+## 
+##  Terminology:
+##  Base class - super superclass of entity, ie, org.objectstyle.cayenne.CayenneDataObject or MyBaseClass
+##  Super class - superclass of entity, ie,  org.objectstyle.cayenne.art.auto._Artist
+##  Sub class - class of entity, ie, org.objectstyle.cayenne.art.Artist
+##
+##  Classes available in template
+##    objEntity - the ObjEntity class: See org.objectstyle.cayenne.map.ObjectEntity
+##    stringUtils - class for string "helper" functions: See org.objectstyle.cayenne.gen.StringUtils
+##    entityUtils - class for entity "helper" functions: See org.objectstyle.cayenne.gen.EntityUtils
+##    importUtils - class for import statement management: See org.objectstyle.cayenne.gen.ImportUtils
+##
+${importUtils.setPackage($entityUtils.subPackageName)}##
+${importUtils.addReservedType("${$entityUtils.subPackageName}.${entityUtils.subClassName}")}##
+${importUtils.addType("${entityUtils.superPackageName}.${entityUtils.superClassName}")}##
+${importUtils.generate()}
+
+/**
+ * A persistent class mapped as "${objEntity.name}" Cayenne entity.
+ */
+public class ${entityUtils.subClassName} extends ${entityUtils.superClassName} {
+
+}
\ No newline at end of file

Added: incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-superclass.vm
URL: http://svn.apache.org/viewcvs/incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-superclass.vm?rev=396882&view=auto
==============================================================================
--- incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-superclass.vm (added)
+++ incubator/cayenne/trunk/cayenne-jpa/src/main/resources/META-INF/cayenne/templates/jpa-superclass.vm Tue Apr 25 06:43:00 2006
@@ -0,0 +1,95 @@
+##Terminology:
+##	Base class - super superclass of entity, ie, org.objectstyle.cayenne.PersistentObject or MyBaseClass
+##  Super class - superclass of entity, ie,  org.objectstyle.cayenne.art.auto._Artist
+##	Sub class - class of entity, ie, org.objectstyle.cayenne.art.Artist
+##
+##  Classes available in template
+##    objEntity - the ObjEntity class: See org.objectstyle.cayenne.map.ObjectEntity
+##    stringUtils - class for string "helper" functions: See org.objectstyle.cayenne.gen.StringUtils
+##    entityUtils - class for entity "helper" functions: See org.objectstyle.cayenne.gen.EntityUtils
+##    importUtils - class for import statement management: See org.objectstyle.cayenne.gen.ImportUtils
+##
+##
+${importUtils.setPackage($entityUtils.superPackageName)}##
+${importUtils.addReservedType("${$entityUtils.superPackageName}.${entityUtils.superClassName}")}##
+#foreach( $attr in ${objEntity.DeclaredAttributes} )
+$importUtils.addType(${attr.Type})##
+#end
+#foreach( $rel in ${objEntity.DeclaredRelationships} )
+$importUtils.addType(${rel.TargetEntity.ClassName})##
+#end
+#if( ${entityUtils.hasToManyDeclaredRelationships()} )
+${importUtils.addType('java.util.List')}##
+#end
+${importUtils.generate()}
+
+/**
+ * A generated persistent class mapped as "${objEntity.name}" Cayenne entity. It is a good idea to
+ * avoid changing this class manually, since it will be overwritten next time code is
+ * regenerated. If you need to make any customizations, put them in a subclass.
+ */
+ ## TODO: support custom superclasses set in the model...
+public class ${entityUtils.superClassName} {
+
+## Create ivars names
+#foreach( $attr in ${objEntity.DeclaredAttributes} )
+    public static final String ${stringUtils.capitalizedAsConstant($attr.Name)}_PROPERTY = "${attr.Name}";
+#end
+#foreach( $rel in ${objEntity.DeclaredRelationships} )
+    public static final String ${stringUtils.capitalizedAsConstant($rel.Name)}_PROPERTY = "${rel.Name}";
+#end
+
+## Create ivars
+#foreach( $attr in ${objEntity.DeclaredAttributes} )
+    protected $importUtils.formatJavaType(${attr.Type}) ${attr.Name};
+#end
+#foreach( $rel in ${objEntity.DeclaredRelationships} )
+#if( $rel.ToMany )
+    protected List ${rel.Name};
+#else
+    protected $importUtils.formatJavaType(${rel.TargetEntity.ClassName}) ${rel.Name};
+#end
+#end
+
+## Create attribute set/get methods
+#foreach( $attr in ${objEntity.DeclaredAttributes} )
+    public $importUtils.formatJavaType(${attr.Type}) get${stringUtils.capitalized($attr.Name)}() {
+        return ${attr.Name};
+    }
+#if ("true" != "${objEntity.isReadOnly()}")
+    public void set${stringUtils.capitalized($attr.Name)}($importUtils.formatJavaType(${attr.Type}) $stringUtils.formatVariableName(${attr.Name})) {
+        this.${stringUtils.formatVariableName($attr.Name)} = ${stringUtils.formatVariableName($attr.Name)};
+    }
+#end
+    
+    
+#end
+##
+##
+## Create list add/remove/get methods
+#foreach( $rel in ${objEntity.DeclaredRelationships} )
+#if( $rel.ToMany )
+    public List<$importUtils.formatJavaType(${rel.TargetEntity.ClassName})> get${stringUtils.capitalized($rel.Name)}() {        
+        return ${rel.Name};
+    }
+#if ( ! $rel.ReadOnly )
+    public void addTo${stringUtils.capitalized($rel.Name)}($importUtils.formatJavaType(${rel.TargetEntity.ClassName}) object) {
+        this.${rel.Name}.add(object);
+    }
+    public void removeFrom${stringUtils.capitalized($rel.Name)}($importUtils.formatJavaType(${rel.TargetEntity.ClassName}) object) {      
+        this.${rel.Name}.remove(object);
+    }
+#end
+#else
+    public $importUtils.formatJavaType(${rel.TargetEntity.ClassName}) get${stringUtils.capitalized($rel.Name)}() {
+        return ${rel.Name};
+    }
+#if ( !${objEntity.isReadOnly()} && !$rel.ReadOnly )
+    public void set${stringUtils.capitalized($rel.Name)}(${importUtils.formatJavaType($rel.TargetEntity.ClassName)} $stringUtils.formatVariableName(${rel.Name})) {
+        this.${stringUtils.formatVariableName($rel.Name)} = ${stringUtils.formatVariableName($rel.Name)};
+    }
+#end
+#end
+    
+#end
+}
\ No newline at end of file



Mime
View raw message