You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/02/01 13:23:56 UTC
[08/10] cayenne git commit: CAY-2215 split cayenne-tools into
cayenne-cgen and cayenne-ant
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/test/resources/testmap.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-ant/src/test/resources/testmap.map.xml b/cayenne-ant/src/test/resources/testmap.map.xml
new file mode 100644
index 0000000..60b94a6
--- /dev/null
+++ b/cayenne-ant/src/test/resources/testmap.map.xml
@@ -0,0 +1,744 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/3.0/modelMap"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/3.0/modelMap http://cayenne.apache.org/schema/3.0/modelMap.xsd"
+ project-version="6">
+ <property name="defaultPackage" value="org.apache.cayenne.testdo.testmap"/>
+ <property name="defaultSuperclass" value="org.apache.cayenne.CayenneDataObject"/>
+ <property name="clientSupported" value="true"/>
+ <property name="defaultClientPackage" value="test.client"/>
+ <property name="defaultClientSuperclass" value="org.apache.cayenne.PersistentObject"/>
+ <procedure name="cayenne_tst_out_proc">
+ <procedure-parameter name="in_param" type="INTEGER" direction="in"/>
+ <procedure-parameter name="out_param" type="INTEGER" direction="out"/>
+ </procedure>
+ <procedure name="cayenne_tst_select_proc">
+ <procedure-parameter name="aName" type="VARCHAR" length="254" direction="in"/>
+ <procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
+ </procedure>
+ <procedure name="cayenne_tst_upd_proc">
+ <procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
+ </procedure>
+ <procedure name="cayenne_tst_upd_proc2">
+ </procedure>
+ <db-entity name="ARRAYS_ENTITY">
+ <db-attribute name="BYTE_ARRAY" type="VARBINARY" length="200"/>
+ <db-attribute name="BYTE_WRAPPER_ARRAY" type="VARBINARY" length="200"/>
+ <db-attribute name="CHAR_ARRAY" type="VARCHAR" length="200"/>
+ <db-attribute name="CHAR_WRAPPER_ARRAY" type="VARCHAR" length="200"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="ARTGROUP">
+ <db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" isMandatory="true" length="100"/>
+ <db-attribute name="PARENT_GROUP_ID" type="INTEGER"/>
+ </db-entity>
+ <db-entity name="ARTIST">
+ <db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
+ <db-attribute name="DATE_OF_BIRTH" type="DATE"/>
+ </db-entity>
+ <db-entity name="ARTIST_CT">
+ <db-attribute name="ARTIST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="ARTIST_NAME" type="CHAR" isMandatory="true" length="254"/>
+ <db-attribute name="DATE_OF_BIRTH" type="DATE"/>
+ </db-entity>
+ <db-entity name="ARTIST_EXHIBIT">
+ <db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="ARTIST_GROUP">
+ <db-attribute name="ARTIST_ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="GROUP_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="BIGDECIMAL_ENTITY">
+ <db-attribute name="BIGDECIMAL_FIELD" type="NUMERIC" length="12" scale="2"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="BIGINTEGER_ENTITY">
+ <db-attribute name="BIG_INTEGER_FIELD" type="BIGINT"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="BINARY_PK_TEST1">
+ <db-attribute name="BIN_ID" type="VARBINARY" isPrimaryKey="true" isMandatory="true" length="32"/>
+ <db-attribute name="NAME" type="VARCHAR" length="10"/>
+ </db-entity>
+ <db-entity name="BINARY_PK_TEST2">
+ <db-attribute name="DETAIL_NAME" type="VARCHAR" length="10"/>
+ <db-attribute name="FK_ID" type="VARBINARY" length="32"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="BIT_TEST">
+ <db-attribute name="BIT_COLUMN" type="BIT" isMandatory="true"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="BLOB_TEST">
+ <db-attribute name="BLOB_COL" type="BLOB"/>
+ <db-attribute name="BLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="BOOLEAN_TEST">
+ <db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN" isMandatory="true"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="CALENDAR_TEST">
+ <db-attribute name="CALENDAR_FIELD" type="TIMESTAMP"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="CHARACTER_ENTITY">
+ <db-attribute name="CHARACTER_FIELD" type="CHAR" length="1"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="CHAR_FK_TEST">
+ <db-attribute name="FK_COL" type="CHAR" length="10"/>
+ <db-attribute name="NAME" type="VARCHAR" length="100"/>
+ <db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="CHAR_PK_TEST">
+ <db-attribute name="OTHER_COL" type="CHAR" length="10"/>
+ <db-attribute name="PK_COL" type="CHAR" isPrimaryKey="true" isMandatory="true" length="10"/>
+ </db-entity>
+ <db-entity name="CLOB_TEST">
+ <db-attribute name="CLOB_COL" type="CLOB"/>
+ <db-attribute name="CLOB_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="CLOB_TEST_RELATION">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="ID_CLOB" type="INTEGER" isMandatory="true"/>
+ <db-attribute name="VALUE" type="INTEGER"/>
+ </db-entity>
+ <db-entity name="COMPOUND_FK_TEST">
+ <db-attribute name="F_KEY1" type="VARCHAR" length="20"/>
+ <db-attribute name="F_KEY2" type="VARCHAR" length="20"/>
+ <db-attribute name="NAME" type="VARCHAR" length="255"/>
+ <db-attribute name="PKEY" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="COMPOUND_PK_TEST">
+ <db-attribute name="KEY1" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
+ <db-attribute name="KEY2" type="VARCHAR" isPrimaryKey="true" isMandatory="true" length="20"/>
+ <db-attribute name="NAME" type="VARCHAR" length="255"/>
+ </db-entity>
+ <db-entity name="DATE_TEST">
+ <db-attribute name="DATE_COLUMN" type="DATE"/>
+ <db-attribute name="DATE_TEST_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
+ <db-attribute name="TIME_COLUMN" type="TIME"/>
+ </db-entity>
+ <db-entity name="DECIMAL_PK_TST">
+ <db-attribute name="DECIMAL_PK" type="DECIMAL" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="100"/>
+ </db-entity>
+ <db-entity name="ENUM_ENTITY">
+ <db-attribute name="ENUM_ATTRIBUTE" type="VARCHAR" length="250"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="EXHIBIT">
+ <db-attribute name="CLOSING_DATE" type="TIMESTAMP" isMandatory="true"/>
+ <db-attribute name="EXHIBIT_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="GALLERY_ID" type="INTEGER" isMandatory="true"/>
+ <db-attribute name="OPENING_DATE" type="TIMESTAMP" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="EXTENDED_TYPE_TEST">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="200"/>
+ </db-entity>
+ <db-entity name="FLOAT_TEST">
+ <db-attribute name="FLOAT_COL" type="FLOAT"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="GALLERY">
+ <db-attribute name="GALLERY_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="GALLERY_NAME" type="VARCHAR" isMandatory="true" length="100"/>
+ </db-entity>
+ <db-entity name="GENERATED_COLUMN_COMP_KEY">
+ <db-attribute name="AUTO_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="100"/>
+ <db-attribute name="PROPAGATED_PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="GENERATED_COLUMN_COMP_M">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="100"/>
+ </db-entity>
+ <db-entity name="GENERATED_COLUMN_DEP">
+ <db-attribute name="GENERATED_COLUMN_FK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="100"/>
+ </db-entity>
+ <db-entity name="GENERATED_COLUMN_TEST">
+ <db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="250"/>
+ </db-entity>
+ <db-entity name="GENERATED_COLUMN_TEST2">
+ <db-attribute name="GENERATED_COLUMN" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="100"/>
+ </db-entity>
+ <db-entity name="GENERATED_F1">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="GENERATED_F2">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="GENERATED_JOIN">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true"/>
+ <db-attribute name="ID1" type="INTEGER"/>
+ <db-attribute name="ID2" type="INTEGER"/>
+ </db-entity>
+ <db-entity name="LONG_ENTITY">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="LONG_FIELD" type="BIGINT"/>
+ </db-entity>
+ <db-entity name="MEANINGFUL_PK_DEP">
+ <db-attribute name="DESCR" type="VARCHAR" length="50"/>
+ <db-attribute name="MASTER_PK" type="INTEGER"/>
+ <db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="MEANINGFUL_PK_TEST1">
+ <db-attribute name="DESCR" type="VARCHAR" length="50"/>
+ <db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="MIXED_PERSISTENCE_STRATEGY">
+ <db-attribute name="DESCRIPTION" type="VARCHAR" length="200"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="NAME" type="VARCHAR" length="200"/>
+ </db-entity>
+ <db-entity name="MIXED_PERSISTENCE_STRATEGY2">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="MASTER_ID" type="INTEGER"/>
+ <db-attribute name="NAME" type="VARCHAR" length="200"/>
+ </db-entity>
+ <db-entity name="NO_PK_TEST">
+ <db-attribute name="ATTRIBUTE1" type="INTEGER"/>
+ </db-entity>
+ <db-entity name="PAINTING">
+ <db-attribute name="ARTIST_ID" type="BIGINT"/>
+ <db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
+ <db-attribute name="GALLERY_ID" type="INTEGER"/>
+ <db-attribute name="PAINTING_DESCRIPTION" type="VARCHAR" length="255"/>
+ <db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
+ </db-entity>
+ <db-entity name="PAINTING1">
+ <db-attribute name="ARTIST_ID" type="BIGINT"/>
+ <db-attribute name="ESTIMATED_PRICE" type="DECIMAL" length="10" scale="2"/>
+ <db-attribute name="GALLERY_ID" type="INTEGER"/>
+ <db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="PAINTING_TITLE" type="VARCHAR" isMandatory="true" length="255"/>
+ </db-entity>
+ <db-entity name="PAINTING_INFO">
+ <db-attribute name="IMAGE_BLOB" type="LONGVARBINARY"/>
+ <db-attribute name="PAINTING_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="TEXT_REVIEW" type="LONGVARCHAR"/>
+ </db-entity>
+ <db-entity name="PRIMITIVES_TEST">
+ <db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="INT_COLUMN" type="INTEGER"/>
+ </db-entity>
+ <db-entity name="SERIALIZABLE_ENTITY">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="SERIALIZABLE_FIELD" type="BLOB"/>
+ </db-entity>
+ <db-entity name="SMALLINT_TEST">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="SMALLINT_COL" type="SMALLINT"/>
+ </db-entity>
+ <db-entity name="TINYINT_TEST">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="TINYINT_COL" type="TINYINT"/>
+ </db-entity>
+ <db-entity name="TYPES_MAPPING_TEST1">
+ <db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="BIGINT_COLUMN" type="BIGINT"/>
+ <db-attribute name="BIT_COLUMN" type="BIT"/>
+ <db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/>
+ <db-attribute name="CHAR_COLUMN" type="CHAR" length="254"/>
+ <db-attribute name="CLOB_COLUMN" type="CLOB"/>
+ <db-attribute name="DATE_COLUMN" type="DATE"/>
+ <db-attribute name="DECIMAL_COLUMN" type="DECIMAL" length="12" scale="5"/>
+ <db-attribute name="DOUBLE_COLUMN" type="DOUBLE" scale="7"/>
+ <db-attribute name="FLOAT_COLUMN" type="FLOAT" scale="3"/>
+ <db-attribute name="INTEGER_COLUMN" type="INTEGER"/>
+ <db-attribute name="LONGVARCHAR_COLUMN" type="LONGVARCHAR"/>
+ <db-attribute name="NUMERIC_COLUMN" type="NUMERIC" length="12" scale="5"/>
+ <db-attribute name="REAL_COLUMN" type="REAL" scale="5"/>
+ <db-attribute name="SMALLINT_COLUMN" type="SMALLINT"/>
+ <db-attribute name="TIMESTAMP_COLUMN" type="TIMESTAMP"/>
+ <db-attribute name="TIME_COLUMN" type="TIME"/>
+ <db-attribute name="TINYINT_COLUMN" type="TINYINT"/>
+ <db-attribute name="VARCHAR_COLUMN" type="VARCHAR" length="255"/>
+ </db-entity>
+ <db-entity name="TYPES_MAPPING_TEST2">
+ <db-attribute name="AAAID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="BINARY_COLUMN" type="BINARY" length="14"/>
+ <db-attribute name="BLOB_COLUMN" type="BLOB"/>
+ <db-attribute name="LONGVARBINARY_COLUMN" type="LONGVARBINARY"/>
+ <db-attribute name="VARBINARY_COLUMN" type="VARBINARY" length="1000"/>
+ </db-entity>
+ <db-entity name="UUID_TEST">
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="UUID" type="VARCHAR" length="100"/>
+ </db-entity>
+ <obj-entity name="ArraysEntity" className="org.apache.cayenne.testdo.misc_types.ArraysEntity" dbEntityName="ARRAYS_ENTITY">
+ <obj-attribute name="byteArray" type="byte[]" db-attribute-path="BYTE_ARRAY"/>
+ <obj-attribute name="byteWrapperArray" type="java.lang.Byte[]" db-attribute-path="BYTE_WRAPPER_ARRAY"/>
+ <obj-attribute name="charArray" type="char[]" db-attribute-path="CHAR_ARRAY"/>
+ <obj-attribute name="charWrapperArray" type="java.lang.Character[]" db-attribute-path="CHAR_WRAPPER_ARRAY"/>
+ </obj-entity>
+ <obj-entity name="ArtGroup" className="org.apache.cayenne.testdo.testmap.ArtGroup" dbEntityName="ARTGROUP">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="Artist" className="org.apache.cayenne.testdo.testmap.Artist" dbEntityName="ARTIST">
+ <obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+ <obj-attribute name="dateOfBirth" type="java.util.Date" db-attribute-path="DATE_OF_BIRTH"/>
+ </obj-entity>
+ <obj-entity name="ArtistCallbackTest" className="org.apache.cayenne.testdo.testmap.ArtistCallbackTest" dbEntityName="ARTIST_CT" exclude-superclass-listeners="true" exclude-default-listeners="true">
+ <obj-attribute name="artistName" type="java.lang.String"/>
+ <obj-attribute name="dateOfBirth" type="java.util.Date"/>
+ <entity-listener class="org.apache.cayenne.testdo.testmap.EntityListenerObjEntity">
+ <post-add method-name="prePersistEntityListener"/>
+ <post-persist method-name="postPersistEntityListener"/>
+ <pre-update method-name="preUpdateEntityListener"/>
+ <post-update method-name="postUpdateEntityListener"/>
+ <pre-remove method-name="preRemoveEntityListener"/>
+ <post-remove method-name="postRemoveEntityListener"/>
+ <post-load method-name="postLoadEntityListener"/>
+ </entity-listener>
+ <post-add method-name="prePersistEntityObjEntity"/>
+ <post-persist method-name="postPersistEntityObjEntity"/>
+ <pre-update method-name="preUpdateEntityObjEntity"/>
+ <post-update method-name="postUpdateEntityObjEntity"/>
+ <pre-remove method-name="preRemoveEntityObjEntity"/>
+ <post-remove method-name="postRemoveEntityObjEntity"/>
+ <post-load method-name="postLoadEntityObjEntity"/>
+ </obj-entity>
+ <obj-entity name="ArtistExhibit" className="org.apache.cayenne.testdo.testmap.ArtistExhibit" dbEntityName="ARTIST_EXHIBIT">
+ </obj-entity>
+ <obj-entity name="BigDecimalEntity" className="org.apache.cayenne.testdo.numeric_types.BigDecimalEntity" dbEntityName="BIGDECIMAL_ENTITY">
+ <obj-attribute name="bigDecimalField" type="java.math.BigDecimal" db-attribute-path="BIGDECIMAL_FIELD"/>
+ </obj-entity>
+ <obj-entity name="BigIntegerEntity" className="org.apache.cayenne.testdo.numeric_types.BigIntegerEntity" dbEntityName="BIGINTEGER_ENTITY">
+ <obj-attribute name="bigIntegerField" type="java.math.BigInteger" db-attribute-path="BIG_INTEGER_FIELD"/>
+ </obj-entity>
+ <obj-entity name="BinaryPKTest1" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest1" dbEntityName="BINARY_PK_TEST1">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="BinaryPKTest2" className="org.apache.cayenne.testdo.binary_pk.BinaryPKTest2" dbEntityName="BINARY_PK_TEST2">
+ <obj-attribute name="detailName" type="java.lang.String" db-attribute-path="DETAIL_NAME"/>
+ </obj-entity>
+ <obj-entity name="BitNumberTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitNumberTestEntity" dbEntityName="BIT_TEST">
+ <obj-attribute name="bitColumn" type="java.lang.Integer" db-attribute-path="BIT_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="BitTestEntity" className="org.apache.cayenne.testdo.numeric_types.BitTestEntity" dbEntityName="BIT_TEST">
+ <obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="BlobTestEntity" className="org.apache.cayenne.testdo.lob.BlobTestEntity" dbEntityName="BLOB_TEST">
+ <obj-attribute name="blobCol" type="byte[]" db-attribute-path="BLOB_COL"/>
+ </obj-entity>
+ <obj-entity name="BooleanTestEntity" className="org.apache.cayenne.testdo.numeric_types.BooleanTestEntity" dbEntityName="BOOLEAN_TEST">
+ <obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="CalendarEntity" className="org.apache.cayenne.testdo.date_time.CalendarEntity" dbEntityName="CALENDAR_TEST">
+ <obj-attribute name="calendarField" type="java.util.Calendar" db-attribute-path="CALENDAR_FIELD"/>
+ </obj-entity>
+ <obj-entity name="CharFkTestEntity" className="org.apache.cayenne.testdo.compound.CharFkTestEntity" dbEntityName="CHAR_FK_TEST">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="CharPkTestEntity" className="org.apache.cayenne.testdo.compound.CharPkTestEntity" dbEntityName="CHAR_PK_TEST">
+ <obj-attribute name="otherCol" type="java.lang.String" db-attribute-path="OTHER_COL"/>
+ <obj-attribute name="pkCol" type="java.lang.String" db-attribute-path="PK_COL"/>
+ </obj-entity>
+ <obj-entity name="CharacterEntity" className="org.apache.cayenne.testdo.misc_types.CharacterEntity" dbEntityName="CHARACTER_ENTITY">
+ <obj-attribute name="characterField" type="java.lang.Character" db-attribute-path="CHARACTER_FIELD"/>
+ </obj-entity>
+ <obj-entity name="ClobTestEntity" className="org.apache.cayenne.testdo.lob.ClobTestEntity" dbEntityName="CLOB_TEST">
+ <obj-attribute name="clobCol" type="java.lang.String" db-attribute-path="CLOB_COL"/>
+ </obj-entity>
+ <obj-entity name="ClobTestRelation" className="org.apache.cayenne.testdo.lob.ClobTestRelation" dbEntityName="CLOB_TEST_RELATION">
+ <obj-attribute name="id" type="java.lang.Integer" db-attribute-path="ID"/>
+ <obj-attribute name="value" type="java.lang.Integer" db-attribute-path="VALUE"/>
+ </obj-entity>
+ <obj-entity name="CompoundFkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundFkTestEntity" dbEntityName="COMPOUND_FK_TEST">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="CompoundPainting" className="org.apache.cayenne.testdo.testmap.CompoundPainting" dbEntityName="PAINTING">
+ <obj-attribute name="artistName" type="java.lang.String" db-attribute-path="toArtist.ARTIST_NAME"/>
+ <obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+ <obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="toGallery.GALLERY_NAME"/>
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ <obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
+ </obj-entity>
+ <obj-entity name="CompoundPkTestEntity" className="org.apache.cayenne.testdo.compound.CompoundPkTestEntity" dbEntityName="COMPOUND_PK_TEST">
+ <obj-attribute name="key1" type="java.lang.String" db-attribute-path="KEY1"/>
+ <obj-attribute name="key2" type="java.lang.String" db-attribute-path="KEY2"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="DateTestEntity" className="org.apache.cayenne.testdo.date_time.DateTestEntity" dbEntityName="DATE_TEST">
+ <obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+ <obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
+ <obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="DecimalPKTest1" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTest1" dbEntityName="DECIMAL_PK_TST">
+ <obj-attribute name="decimalPK" type="java.lang.Double" db-attribute-path="DECIMAL_PK"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="DecimalPKTestEntity" className="org.apache.cayenne.testdo.numeric_types.DecimalPKTestEntity" dbEntityName="DECIMAL_PK_TST">
+ <obj-attribute name="decimalPK" type="java.math.BigDecimal" db-attribute-path="DECIMAL_PK"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="EnumEntity" className="org.apache.cayenne.testdo.enum_test.EnumEntity" dbEntityName="ENUM_ENTITY">
+ <obj-attribute name="enumAttribute" type="org.apache.cayenne.testdo.enum_test.Enum1" db-attribute-path="ENUM_ATTRIBUTE"/>
+ </obj-entity>
+ <obj-entity name="Exhibit" className="org.apache.cayenne.testdo.testmap.Exhibit" dbEntityName="EXHIBIT">
+ <obj-attribute name="closingDate" type="java.util.Date" db-attribute-path="CLOSING_DATE"/>
+ <obj-attribute name="openingDate" type="java.util.Date" db-attribute-path="OPENING_DATE"/>
+ </obj-entity>
+ <obj-entity name="ExtendedTypeEntity" className="org.apache.cayenne.testdo.extended_type.ExtendedTypeEntity" dbEntityName="EXTENDED_TYPE_TEST">
+ <obj-attribute name="name" type="org.apache.cayenne.testdo.extended_type.StringET1" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="Gallery" className="org.apache.cayenne.testdo.testmap.Gallery" dbEntityName="GALLERY">
+ <obj-attribute name="galleryName" type="java.lang.String" db-attribute-path="GALLERY_NAME"/>
+ </obj-entity>
+ <obj-entity name="GeneratedColumnCompKey" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompKey" dbEntityName="GENERATED_COLUMN_COMP_KEY">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="GeneratedColumnCompMaster" className="org.apache.cayenne.testdo.generated.GeneratedColumnCompMaster" dbEntityName="GENERATED_COLUMN_COMP_M">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="GeneratedColumnDep" className="org.apache.cayenne.testdo.generated.GeneratedColumnDep" dbEntityName="GENERATED_COLUMN_DEP">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="GeneratedColumnTest2" className="org.apache.cayenne.testdo.generated.GeneratedColumnTest2" dbEntityName="GENERATED_COLUMN_TEST2">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="GeneratedColumnTestEntity" className="org.apache.cayenne.testdo.generated.GeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="GeneratedF1" className="org.apache.cayenne.testdo.generated.GeneratedF1" clientClassName="test.client.GeneratedF1" dbEntityName="GENERATED_F1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+ </obj-entity>
+ <obj-entity name="GeneratedF2" className="org.apache.cayenne.testdo.generated.GeneratedF2" clientClassName="test.client.GeneratedF2" dbEntityName="GENERATED_F2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+ </obj-entity>
+ <obj-entity name="LongEntity" className="org.apache.cayenne.testdo.numeric_types.LongEntity" dbEntityName="LONG_ENTITY">
+ <obj-attribute name="longField" type="java.lang.Long" db-attribute-path="LONG_FIELD"/>
+ </obj-entity>
+ <obj-entity name="MeaningfulGeneratedColumnTestEntity" className="org.apache.cayenne.testdo.testmap.MeaningfulGeneratedColumnTestEntity" dbEntityName="GENERATED_COLUMN_TEST">
+ <obj-attribute name="generatedColumn" type="java.lang.Integer" db-attribute-path="GENERATED_COLUMN"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="MeaningfulPKDep" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep" dbEntityName="MEANINGFUL_PK_DEP">
+ <obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
+ </obj-entity>
+ <obj-entity name="MeaningfulPKTest1" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1" dbEntityName="MEANINGFUL_PK_TEST1">
+ <obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
+ <obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
+ </obj-entity>
+ <obj-entity name="MixedPersistenceStrategy" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy" dbEntityName="MIXED_PERSISTENCE_STRATEGY">
+ <obj-attribute name="description" type="java.lang.String" db-attribute-path="DESCRIPTION"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="MixedPersistenceStrategy2" className="org.apache.cayenne.testdo.mixed_persistence_strategy.MixedPersistenceStrategy2" dbEntityName="MIXED_PERSISTENCE_STRATEGY2">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="NoPkTestEntity" className="org.apache.cayenne.testdo.no_pk.NoPkTestEntity" dbEntityName="NO_PK_TEST">
+ <obj-attribute name="attribute1" type="java.lang.Integer" db-attribute-path="ATTRIBUTE1"/>
+ </obj-entity>
+ <obj-entity name="Painting" className="org.apache.cayenne.testdo.testmap.Painting" dbEntityName="PAINTING" superClassName="org.apache.cayenne.testdo.testmap.ArtDataObject">
+ <obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+ <obj-attribute name="paintingDescription" type="java.lang.String" db-attribute-path="PAINTING_DESCRIPTION"/>
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ </obj-entity>
+ <obj-entity name="Painting1" className="org.apache.cayenne.testdo.testmap.Painting1" dbEntityName="PAINTING1">
+ <obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ </obj-entity>
+ <obj-entity name="PaintingInfo" className="org.apache.cayenne.testdo.testmap.PaintingInfo" dbEntityName="PAINTING_INFO">
+ <obj-attribute name="imageBlob" type="byte[]" db-attribute-path="IMAGE_BLOB"/>
+ <obj-attribute name="textReview" type="java.lang.String" db-attribute-path="TEXT_REVIEW"/>
+ </obj-entity>
+ <obj-entity name="PrimitivesTestEntity" className="org.apache.cayenne.testdo.primitive.PrimitivesTestEntity" dbEntityName="PRIMITIVES_TEST">
+ <obj-attribute name="booleanColumn" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+ <obj-attribute name="intColumn" type="int" db-attribute-path="INT_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="ROArtist" className="org.apache.cayenne.testdo.testmap.ROArtist" readOnly="true" dbEntityName="ARTIST">
+ <obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+ <obj-attribute name="dateOfBirth" type="java.sql.Date" db-attribute-path="DATE_OF_BIRTH"/>
+ </obj-entity>
+ <obj-entity name="ROPainting" className="org.apache.cayenne.testdo.testmap.ROPainting" readOnly="true" dbEntityName="PAINTING">
+ <obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ </obj-entity>
+ <obj-entity name="RWCompoundPainting" className="org.apache.cayenne.testdo.testmap.RWCompoundPainting" dbEntityName="PAINTING">
+ <obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="ESTIMATED_PRICE"/>
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ <obj-attribute name="textReview" type="java.lang.String" db-attribute-path="toPaintingInfo.TEXT_REVIEW"/>
+ </obj-entity>
+ <obj-entity name="ReturnTypesMap1" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap1" clientClassName="test.client.ReturnTypesMap1" dbEntityName="TYPES_MAPPING_TEST1" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+ <obj-attribute name="bigintColumn" type="java.lang.Long" db-attribute-path="BIGINT_COLUMN"/>
+ <obj-attribute name="bitColumn" type="java.lang.Boolean" db-attribute-path="BIT_COLUMN"/>
+ <obj-attribute name="booleanColumn" type="java.lang.Boolean" db-attribute-path="BOOLEAN_COLUMN"/>
+ <obj-attribute name="charColumn" type="java.lang.String" db-attribute-path="CHAR_COLUMN"/>
+ <obj-attribute name="clobColumn" type="java.lang.String" db-attribute-path="CLOB_COLUMN"/>
+ <obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+ <obj-attribute name="decimalColumn" type="java.math.BigDecimal" db-attribute-path="DECIMAL_COLUMN"/>
+ <obj-attribute name="doubleColumn" type="java.lang.Double" db-attribute-path="DOUBLE_COLUMN"/>
+ <obj-attribute name="floatColumn" type="java.lang.Float" db-attribute-path="FLOAT_COLUMN"/>
+ <obj-attribute name="integerColumn" type="java.lang.Integer" db-attribute-path="INTEGER_COLUMN"/>
+ <obj-attribute name="longvarcharColumn" type="java.lang.String" db-attribute-path="LONGVARCHAR_COLUMN"/>
+ <obj-attribute name="numericColumn" type="java.math.BigDecimal" db-attribute-path="NUMERIC_COLUMN"/>
+ <obj-attribute name="realColumn" type="java.lang.Float" db-attribute-path="REAL_COLUMN"/>
+ <obj-attribute name="smallintColumn" type="java.lang.Short" db-attribute-path="SMALLINT_COLUMN"/>
+ <obj-attribute name="timeColumn" type="java.util.Date" db-attribute-path="TIME_COLUMN"/>
+ <obj-attribute name="timestampColumn" type="java.util.Date" db-attribute-path="TIMESTAMP_COLUMN"/>
+ <obj-attribute name="tinyintColumn" type="java.lang.Byte" db-attribute-path="TINYINT_COLUMN"/>
+ <obj-attribute name="varcharColumn" type="java.lang.String" db-attribute-path="VARCHAR_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="ReturnTypesMap2" className="org.apache.cayenne.testdo.return_types.ReturnTypesMap2" clientClassName="test.client.ReturnTypesMap2" dbEntityName="TYPES_MAPPING_TEST2" superClassName="org.apache.cayenne.CayenneDataObject" clientSuperClassName="org.apache.cayenne.PersistentObject">
+ <obj-attribute name="binaryColumn" type="byte[]" db-attribute-path="BINARY_COLUMN"/>
+ <obj-attribute name="blobColumn" type="byte[]" db-attribute-path="BLOB_COLUMN"/>
+ <obj-attribute name="longvarbinaryColumn" type="byte[]" db-attribute-path="LONGVARBINARY_COLUMN"/>
+ <obj-attribute name="varbinaryColumn" type="byte[]" db-attribute-path="VARBINARY_COLUMN"/>
+ </obj-entity>
+ <obj-entity name="SerializableEntity" className="org.apache.cayenne.testdo.misc_types.SerializableEntity" dbEntityName="SERIALIZABLE_ENTITY">
+ <obj-attribute name="serializableField" type="org.apache.cayenne.MockSerializable" db-attribute-path="SERIALIZABLE_FIELD"/>
+ </obj-entity>
+ <obj-entity name="SmallintTestEntity" className="org.apache.cayenne.testdo.numeric_types.SmallintTestEntity" dbEntityName="SMALLINT_TEST">
+ <obj-attribute name="smallintCol" type="java.lang.Short" db-attribute-path="SMALLINT_COL"/>
+ </obj-entity>
+ <obj-entity name="SubPainting" className="org.apache.cayenne.testdo.testmap.SubPainting" dbEntityName="PAINTING">
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ </obj-entity>
+ <obj-entity name="TinyintTestEntity" className="org.apache.cayenne.testdo.numeric_types.TinyintTestEntity" dbEntityName="TINYINT_TEST">
+ <obj-attribute name="tinyintCol" type="java.lang.Byte" db-attribute-path="TINYINT_COL"/>
+ </obj-entity>
+ <obj-entity name="UuidTestEntity" className="org.apache.cayenne.testdo.uuid.UuidTestEntity" dbEntityName="UUID_TEST">
+ <obj-attribute name="uuid" type="java.util.UUID" db-attribute-path="UUID"/>
+ </obj-entity>
+ <db-relationship name="artistGroupArray" source="ARTGROUP" target="ARTIST_GROUP" toMany="true">
+ <db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
+ </db-relationship>
+ <db-relationship name="toChildGroups" source="ARTGROUP" target="ARTGROUP" toMany="true">
+ <db-attribute-pair source="GROUP_ID" target="PARENT_GROUP_ID"/>
+ </db-relationship>
+ <db-relationship name="toParentGroup" source="ARTGROUP" target="ARTGROUP" toMany="false">
+ <db-attribute-pair source="PARENT_GROUP_ID" target="GROUP_ID"/>
+ </db-relationship>
+ <db-relationship name="artistExhibitArray" source="ARTIST" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="artistGroupArray" source="ARTIST" target="ARTIST_GROUP" toMany="true">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="paintingArray" source="ARTIST" target="PAINTING" toMany="true">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="toArtist" source="ARTIST_EXHIBIT" target="ARTIST" toMany="false">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="toExhibit" source="ARTIST_EXHIBIT" target="EXHIBIT" toMany="false">
+ <db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
+ </db-relationship>
+ <db-relationship name="toArtist" source="ARTIST_GROUP" target="ARTIST" toMany="false">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="toGroup" source="ARTIST_GROUP" target="ARTGROUP" toMany="false">
+ <db-attribute-pair source="GROUP_ID" target="GROUP_ID"/>
+ </db-relationship>
+ <db-relationship name="binaryPKDetails" source="BINARY_PK_TEST1" target="BINARY_PK_TEST2" toMany="true">
+ <db-attribute-pair source="BIN_ID" target="FK_ID"/>
+ </db-relationship>
+ <db-relationship name="toBinaryPKMaster" source="BINARY_PK_TEST2" target="BINARY_PK_TEST1" toMany="false">
+ <db-attribute-pair source="FK_ID" target="BIN_ID"/>
+ </db-relationship>
+ <db-relationship name="toCharPK" source="CHAR_FK_TEST" target="CHAR_PK_TEST" toMany="false">
+ <db-attribute-pair source="FK_COL" target="PK_COL"/>
+ </db-relationship>
+ <db-relationship name="charFKs" source="CHAR_PK_TEST" target="CHAR_FK_TEST" toMany="true">
+ <db-attribute-pair source="PK_COL" target="FK_COL"/>
+ </db-relationship>
+ <db-relationship name="clob" source="CLOB_TEST" target="CLOB_TEST_RELATION" toMany="true">
+ <db-attribute-pair source="CLOB_TEST_ID" target="ID_CLOB"/>
+ </db-relationship>
+ <db-relationship name="CLOB_REL" source="CLOB_TEST_RELATION" target="CLOB_TEST" toMany="false">
+ <db-attribute-pair source="ID_CLOB" target="CLOB_TEST_ID"/>
+ </db-relationship>
+ <db-relationship name="toCompoundPk" source="COMPOUND_FK_TEST" target="COMPOUND_PK_TEST" toMany="false">
+ <db-attribute-pair source="F_KEY1" target="KEY1"/>
+ <db-attribute-pair source="F_KEY2" target="KEY2"/>
+ </db-relationship>
+ <db-relationship name="compoundFkArray" source="COMPOUND_PK_TEST" target="COMPOUND_FK_TEST" toMany="true">
+ <db-attribute-pair source="KEY1" target="F_KEY1"/>
+ <db-attribute-pair source="KEY2" target="F_KEY2"/>
+ </db-relationship>
+ <db-relationship name="artistExhibitArray" source="EXHIBIT" target="ARTIST_EXHIBIT" toDependentPK="true" toMany="true">
+ <db-attribute-pair source="EXHIBIT_ID" target="EXHIBIT_ID"/>
+ </db-relationship>
+ <db-relationship name="toGallery" source="EXHIBIT" target="GALLERY" toMany="false">
+ <db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+ </db-relationship>
+ <db-relationship name="exhibitArray" source="GALLERY" target="EXHIBIT" toMany="true">
+ <db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+ </db-relationship>
+ <db-relationship name="paintingArray" source="GALLERY" target="PAINTING" toMany="true">
+ <db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+ </db-relationship>
+ <db-relationship name="toMaster" source="GENERATED_COLUMN_COMP_KEY" target="GENERATED_COLUMN_COMP_M" toMany="false">
+ <db-attribute-pair source="PROPAGATED_PK" target="ID"/>
+ </db-relationship>
+ <db-relationship name="toDetail" source="GENERATED_COLUMN_COMP_M" target="GENERATED_COLUMN_COMP_KEY" toDependentPK="true" toMany="true">
+ <db-attribute-pair source="ID" target="PROPAGATED_PK"/>
+ </db-relationship>
+ <db-relationship name="toMaster" source="GENERATED_COLUMN_DEP" target="GENERATED_COLUMN_TEST" toMany="false">
+ <db-attribute-pair source="GENERATED_COLUMN_FK" target="GENERATED_COLUMN"/>
+ </db-relationship>
+ <db-relationship name="toDep" source="GENERATED_COLUMN_TEST" target="GENERATED_COLUMN_DEP" toDependentPK="true" toMany="false">
+ <db-attribute-pair source="GENERATED_COLUMN" target="GENERATED_COLUMN_FK"/>
+ </db-relationship>
+ <db-relationship name="join" source="GENERATED_F1" target="GENERATED_JOIN" toMany="true">
+ <db-attribute-pair source="ID" target="ID1"/>
+ </db-relationship>
+ <db-relationship name="join" source="GENERATED_F2" target="GENERATED_JOIN" toMany="true">
+ <db-attribute-pair source="ID" target="ID2"/>
+ </db-relationship>
+ <db-relationship name="f1" source="GENERATED_JOIN" target="GENERATED_F1" toMany="false">
+ <db-attribute-pair source="ID1" target="ID"/>
+ </db-relationship>
+ <db-relationship name="f2" source="GENERATED_JOIN" target="GENERATED_F2" toMany="false">
+ <db-attribute-pair source="ID2" target="ID"/>
+ </db-relationship>
+ <db-relationship name="toMeaningfulPK" source="MEANINGFUL_PK_DEP" target="MEANINGFUL_PK_TEST1" toMany="false">
+ <db-attribute-pair source="MASTER_PK" target="PK_ATTRIBUTE"/>
+ </db-relationship>
+ <db-relationship name="meaningfulPKDepArray" source="MEANINGFUL_PK_TEST1" target="MEANINGFUL_PK_DEP" toMany="true">
+ <db-attribute-pair source="PK_ATTRIBUTE" target="MASTER_PK"/>
+ </db-relationship>
+ <db-relationship name="details" source="MIXED_PERSISTENCE_STRATEGY" target="MIXED_PERSISTENCE_STRATEGY2" toMany="true">
+ <db-attribute-pair source="ID" target="MASTER_ID"/>
+ </db-relationship>
+ <db-relationship name="master" source="MIXED_PERSISTENCE_STRATEGY2" target="MIXED_PERSISTENCE_STRATEGY" toMany="false">
+ <db-attribute-pair source="MASTER_ID" target="ID"/>
+ </db-relationship>
+ <db-relationship name="toArtist" source="PAINTING" target="ARTIST" toMany="false">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="toGallery" source="PAINTING" target="GALLERY" toMany="false">
+ <db-attribute-pair source="GALLERY_ID" target="GALLERY_ID"/>
+ </db-relationship>
+ <db-relationship name="toPaintingInfo" source="PAINTING" target="PAINTING_INFO" toDependentPK="true" toMany="false">
+ <db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
+ </db-relationship>
+ <db-relationship name="toArtist" source="PAINTING1" target="ARTIST" toMany="false">
+ <db-attribute-pair source="ARTIST_ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="painting" source="PAINTING_INFO" target="PAINTING" toMany="false">
+ <db-attribute-pair source="PAINTING_ID" target="PAINTING_ID"/>
+ </db-relationship>
+ <obj-relationship name="artistArray" source="ArtGroup" target="Artist" deleteRule="Nullify" db-relationship-path="artistGroupArray.toArtist"/>
+ <obj-relationship name="childGroupsArray" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toChildGroups"/>
+ <obj-relationship name="toParentGroup" source="ArtGroup" target="ArtGroup" deleteRule="Nullify" db-relationship-path="toParentGroup"/>
+ <obj-relationship name="artistExhibitArray" source="Artist" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
+ <obj-relationship name="groupArray" source="Artist" target="ArtGroup" deleteRule="Cascade" db-relationship-path="artistGroupArray.toGroup"/>
+ <obj-relationship name="paintingArray" source="Artist" target="Painting" deleteRule="Cascade" db-relationship-path="paintingArray"/>
+ <obj-relationship name="toArtist" source="ArtistExhibit" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+ <obj-relationship name="toExhibit" source="ArtistExhibit" target="Exhibit" deleteRule="Nullify" db-relationship-path="toExhibit"/>
+ <obj-relationship name="binaryPKDetails" source="BinaryPKTest1" target="BinaryPKTest2" db-relationship-path="binaryPKDetails"/>
+ <obj-relationship name="toBinaryPKMaster" source="BinaryPKTest2" target="BinaryPKTest1" db-relationship-path="toBinaryPKMaster"/>
+ <obj-relationship name="toCharPK" source="CharFkTestEntity" target="CharPkTestEntity" db-relationship-path="toCharPK"/>
+ <obj-relationship name="charFKs" source="CharPkTestEntity" target="CharFkTestEntity" db-relationship-path="charFKs"/>
+ <obj-relationship name="clobValue" source="ClobTestEntity" target="ClobTestRelation" db-relationship-path="clob"/>
+ <obj-relationship name="clobId" source="ClobTestRelation" target="ClobTestEntity" db-relationship-path="CLOB_REL"/>
+ <obj-relationship name="toCompoundPk" source="CompoundFkTestEntity" target="CompoundPkTestEntity" db-relationship-path="toCompoundPk"/>
+ <obj-relationship name="toArtist" source="CompoundPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+ <obj-relationship name="toGallery" source="CompoundPainting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+ <obj-relationship name="toPaintingInfo" source="CompoundPainting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
+ <obj-relationship name="compoundFkArray" source="CompoundPkTestEntity" target="CompoundFkTestEntity" db-relationship-path="compoundFkArray"/>
+ <obj-relationship name="artistExhibitArray" source="Exhibit" target="ArtistExhibit" deleteRule="Cascade" db-relationship-path="artistExhibitArray"/>
+ <obj-relationship name="toGallery" source="Exhibit" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+ <obj-relationship name="exhibitArray" source="Gallery" target="Exhibit" deleteRule="Cascade" db-relationship-path="exhibitArray"/>
+ <obj-relationship name="paintingArray" source="Gallery" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
+ <obj-relationship name="toMaster" source="GeneratedColumnCompKey" target="GeneratedColumnCompMaster" db-relationship-path="toMaster"/>
+ <obj-relationship name="toDetail" source="GeneratedColumnCompMaster" target="GeneratedColumnCompKey" db-relationship-path="toDetail"/>
+ <obj-relationship name="toMaster" source="GeneratedColumnDep" target="GeneratedColumnTestEntity" db-relationship-path="toMaster"/>
+ <obj-relationship name="toDep" source="GeneratedColumnTestEntity" target="GeneratedColumnDep" db-relationship-path="toDep"/>
+ <obj-relationship name="f2" source="GeneratedF1" target="GeneratedF2" deleteRule="Nullify" db-relationship-path="join.f2"/>
+ <obj-relationship name="f1" source="GeneratedF2" target="GeneratedF1" deleteRule="Nullify" db-relationship-path="join.f1"/>
+ <obj-relationship name="toMeaningfulPK" source="MeaningfulPKDep" target="MeaningfulPKTest1" db-relationship-path="toMeaningfulPK"/>
+ <obj-relationship name="meaningfulPKDepArray" source="MeaningfulPKTest1" target="MeaningfulPKDep" db-relationship-path="meaningfulPKDepArray"/>
+ <obj-relationship name="details" source="MixedPersistenceStrategy" target="MixedPersistenceStrategy2" db-relationship-path="details"/>
+ <obj-relationship name="master" source="MixedPersistenceStrategy2" target="MixedPersistenceStrategy" db-relationship-path="master"/>
+ <obj-relationship name="toArtist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+ <obj-relationship name="toGallery" source="Painting" target="Gallery" deleteRule="Nullify" db-relationship-path="toGallery"/>
+ <obj-relationship name="toPaintingInfo" source="Painting" target="PaintingInfo" deleteRule="Cascade" db-relationship-path="toPaintingInfo"/>
+ <obj-relationship name="toArtist" source="Painting1" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+ <obj-relationship name="painting" source="PaintingInfo" target="Painting" deleteRule="Nullify" db-relationship-path="painting"/>
+ <obj-relationship name="paintingArray" source="ROArtist" target="Painting" deleteRule="Deny" db-relationship-path="paintingArray"/>
+ <obj-relationship name="toArtist" source="ROPainting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+ <query name="EjbqlQueryTest" type="EJBQLQuery">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+ <property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+ <ejbql><![CDATA[select a from Artist a]]></ejbql>
+ </query>
+ <query name="NonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap">
+ <property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+ <sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+VALUES (512, 'No Painting Like This', 12.5)]]></sql>
+ <sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) VALUES (512, 'No Painting Like This', 12.5)]]></sql>
+ </query>
+ <query name="ObjectQuery" type="SelectQuery" root="obj-entity" root-name="Painting">
+ <qualifier><![CDATA[toArtist = $artist]]></qualifier>
+ <ordering><![CDATA[paintingTitle]]></ordering>
+ </query>
+ <query name="ParameterizedNonSelectingQuery" type="SQLTemplate" root="data-map" root-name="testmap">
+ <sql><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+VALUES (#bind($id), #bind($title), #bind($price))]]></sql>
+ <sql adapter-class="org.apache.cayenne.dba.db2.DB2Adapter"><![CDATA[INSERT INTO PAINTING (PAINTING_ID, PAINTING_TITLE, ESTIMATED_PRICE) values (#bind($id), #bind($title), #bind($price))]]></sql>
+ </query>
+ <query name="ParameterizedQueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+ <property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
+ <qualifier><![CDATA[artistName like $name]]></qualifier>
+ </query>
+ <query name="ParameterizedQueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+ <property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+ <qualifier><![CDATA[artistName like $name]]></qualifier>
+ </query>
+ <query name="ProcedureQuery" type="ProcedureQuery" root="procedure" root-name="cayenne_tst_select_proc" result-entity="Artist">
+ </query>
+ <query name="QueryWithLocalCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+ <property name="cayenne.GenericSelectQuery.cacheStrategy" value="LOCAL_CACHE"/>
+ </query>
+ <query name="QueryWithOrdering" type="SelectQuery" root="obj-entity" root-name="Artist">
+ <ordering descending="true" ignore-case="true"><![CDATA[artistName]]></ordering>
+ <ordering><![CDATA[dateOfBirth]]></ordering>
+ </query>
+ <query name="QueryWithPrefetch" type="SelectQuery" root="obj-entity" root-name="Gallery">
+ <prefetch>paintingArray</prefetch>
+ </query>
+ <query name="QueryWithQualifier" type="SelectQuery" root="obj-entity" root-name="Artist">
+ <qualifier><![CDATA[artistName = $param1]]></qualifier>
+ </query>
+ <query name="QueryWithSharedCache" type="SelectQuery" root="obj-entity" root-name="Artist">
+ <property name="cayenne.GenericSelectQuery.cacheStrategy" value="SHARED_CACHE"/>
+ </query>
+ <query name="SelectDateTest" type="SQLTemplate" root="data-map" root-name="testmap">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+ <property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+ <sql><![CDATA[SELECT * FROM DATE_TEST]]></sql>
+ </query>
+ <query name="SelectReturnTypesMap1" type="SQLTemplate" root="data-map" root-name="testmap">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+ <property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+ <sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST1]]></sql>
+ </query>
+ <query name="SelectReturnTypesMap2" type="SQLTemplate" root="data-map" root-name="testmap">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+ <property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+ <sql><![CDATA[SELECT * FROM TYPES_MAPPING_TEST2]]></sql>
+ </query>
+ <query name="SelectTestLower" type="SQLTemplate" root="data-map" root-name="testmap">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+ <property name="cayenne.SQLTemplate.columnNameCapitalization" value="LOWER"/>
+ <sql><![CDATA[select * from ARTIST]]></sql>
+ </query>
+ <query name="SelectTestUpper" type="SQLTemplate" root="data-map" root-name="testmap">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows" value="true"/>
+ <property name="cayenne.SQLTemplate.columnNameCapitalization" value="UPPER"/>
+ <sql><![CDATA[select * from ARTIST]]></sql>
+ </query>
+</data-map>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-cgen/pom.xml b/cayenne-cgen/pom.xml
new file mode 100644
index 0000000..7aa0d84
--- /dev/null
+++ b/cayenne-cgen/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>cayenne-parent</artifactId>
+ <groupId>org.apache.cayenne</groupId>
+ <version>4.0.M5-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>cayenne-cgen</artifactId>
+ <packaging>jar</packaging>
+ <name>cayenne-cgen: Cayenne Class Generation Tools</name>
+
+ <dependencies>
+ <!--
+ using org.apache.cayenne.project.validation.NameValidationHelper from cayenne-project
+ and org.apache.cayenne.dbsync.filter.NameFilter from cayenne-dbsync
+ -->
+ <dependency>
+ <groupId>org.apache.cayenne</groupId>
+ <artifactId>cayenne-dbsync</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- This ensures LICENSE and NOTICE inclusion in all jars -->
+ <plugin>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/src/main/java/org/apache/cayenne/gen/Artifact.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/Artifact.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/Artifact.java
new file mode 100644
index 0000000..fcd9118
--- /dev/null
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/Artifact.java
@@ -0,0 +1,65 @@
+/*****************************************************************
+ * 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.cayenne.gen;
+
+import org.apache.velocity.VelocityContext;
+
+/**
+ * Represents a class generation "artifact" which is a facade to a metadata object used
+ * for a given single generation template run.
+ *
+ * @since 3.0
+ */
+public interface Artifact {
+
+ public static String STRING_UTILS_KEY = "stringUtils";
+ public static String IMPORT_UTILS_KEY = "importUtils";
+
+ /**
+ * Root object, such as ObjEntity or Embeddable, etc.
+ */
+ public static String OBJECT_KEY = "object";
+ public static String SUPER_CLASS_KEY = "superClassName";
+ public static String SUPER_PACKAGE_KEY = "superPackageName";
+ public static String SUB_CLASS_KEY = "subClassName";
+ public static String SUB_PACKAGE_KEY = "subPackageName";
+ public static String BASE_CLASS_KEY = "baseClassName";
+ public static String BASE_PACKAGE_KEY = "basePackageName";
+ public static String CREATE_PROPERTY_NAMES = "createPropertyNames";
+
+ TemplateType[] getTemplateTypes(ArtifactGenerationMode mode);
+
+ String getQualifiedBaseClassName();
+
+ String getQualifiedClassName();
+
+ /**
+ * Returns a mapping metadata object for this artifact.
+ */
+ Object getObject();
+
+ /**
+ * A callback method that allows each artifact to add its own special keys to the
+ * context. Invoked from
+ * {@link ClassGenerationAction#resetContextForArtifactTemplate(Artifact, TemplateType)},
+ * after the context is initialized by code generator, so this method can use
+ * predefined keys from the context.
+ */
+ void postInitContext(VelocityContext context);
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactGenerationMode.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactGenerationMode.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactGenerationMode.java
new file mode 100644
index 0000000..b0c20cc
--- /dev/null
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactGenerationMode.java
@@ -0,0 +1,28 @@
+/*****************************************************************
+ * 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.cayenne.gen;
+
+/**
+ * Code generator execution mode for a single artifact.
+ *
+ * @since 3.0
+ */
+public enum ArtifactGenerationMode {
+ SINGLE_CLASS, GENERATION_GAP
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactsGenerationMode.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactsGenerationMode.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactsGenerationMode.java
new file mode 100644
index 0000000..e76c172
--- /dev/null
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ArtifactsGenerationMode.java
@@ -0,0 +1,40 @@
+/*****************************************************************
+ * 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.cayenne.gen;
+
+/**
+ * Code generator execution mode for a collection of artifacts.
+ *
+ * @since 3.0
+ */
+public enum ArtifactsGenerationMode {
+
+ // TODO: andrus 12/9/2007 - label names are old... need to call it something else...
+ DATAMAP("datamap"), ENTITY("entity"), ALL("all");
+
+ private String label;
+
+ private ArtifactsGenerationMode(String label) {
+ this.label = label;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
new file mode 100644
index 0000000..6c46977
--- /dev/null
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
@@ -0,0 +1,584 @@
+/*****************************************************************
+ * 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.cayenne.gen;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.QueryDescriptor;
+import org.apache.commons.logging.Log;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.NullLogSystem;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+public class ClassGenerationAction {
+ static final String TEMPLATES_DIR_NAME = "templates/v1_2/";
+
+ public static final String SINGLE_CLASS_TEMPLATE = TEMPLATES_DIR_NAME + "singleclass.vm";
+ public static final String SUBCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "subclass.vm";
+ public static final String SUPERCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "superclass.vm";
+
+ public static final String EMBEDDABLE_SINGLE_CLASS_TEMPLATE = TEMPLATES_DIR_NAME + "embeddable-singleclass.vm";
+ public static final String EMBEDDABLE_SUBCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "embeddable-subclass.vm";
+ public static final String EMBEDDABLE_SUPERCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "embeddable-superclass.vm";
+
+ public static final String DATAMAP_SINGLE_CLASS_TEMPLATE = TEMPLATES_DIR_NAME + "datamap-singleclass.vm";
+ public static final String DATAMAP_SUBCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "datamap-subclass.vm";
+ public static final String DATAMAP_SUPERCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "datamap-superclass.vm";
+
+ public static final String SUPERCLASS_PREFIX = "_";
+ private static final String WILDCARD = "*";
+
+ protected Collection<Artifact> artifacts;
+
+ protected String superPkg;
+ protected DataMap dataMap;
+
+ protected ArtifactsGenerationMode artifactsGenerationMode;
+ protected boolean makePairs;
+
+ protected Log logger;
+ protected File destDir;
+ protected boolean overwrite;
+ protected boolean usePkgPath;
+
+ protected String template;
+ protected String superTemplate;
+ protected String embeddableTemplate;
+ protected String embeddableSuperTemplate;
+ protected String queryTemplate;
+ protected String querySuperTemplate;
+ protected long timestamp;
+ protected String outputPattern;
+ protected String encoding;
+ protected boolean createPropertyNames;
+
+ // runtime ivars
+ protected VelocityContext context;
+ protected Map<String, Template> templateCache;
+
+ public ClassGenerationAction() {
+ this.outputPattern = "*.java";
+ this.timestamp = System.currentTimeMillis();
+ this.usePkgPath = true;
+ this.makePairs = true;
+ this.context = new VelocityContext();
+ this.templateCache = new HashMap<>(5);
+
+ this.artifacts = new ArrayList<>();
+ }
+
+ protected String defaultTemplateName(TemplateType type) {
+ switch (type) {
+ case ENTITY_SINGLE_CLASS:
+ return ClassGenerationAction.SINGLE_CLASS_TEMPLATE;
+ case ENTITY_SUBCLASS:
+ return ClassGenerationAction.SUBCLASS_TEMPLATE;
+ case ENTITY_SUPERCLASS:
+ return ClassGenerationAction.SUPERCLASS_TEMPLATE;
+ case EMBEDDABLE_SUBCLASS:
+ return ClassGenerationAction.EMBEDDABLE_SUBCLASS_TEMPLATE;
+ case EMBEDDABLE_SUPERCLASS:
+ return ClassGenerationAction.EMBEDDABLE_SUPERCLASS_TEMPLATE;
+ case EMBEDDABLE_SINGLE_CLASS:
+ return ClassGenerationAction.EMBEDDABLE_SINGLE_CLASS_TEMPLATE;
+ case DATAMAP_SINGLE_CLASS:
+ return ClassGenerationAction.DATAMAP_SINGLE_CLASS_TEMPLATE;
+ case DATAMAP_SUPERCLASS:
+ return ClassGenerationAction.DATAMAP_SUPERCLASS_TEMPLATE;
+ case DATAMAP_SUBCLASS:
+ return ClassGenerationAction.DATAMAP_SUBCLASS_TEMPLATE;
+ default:
+ throw new IllegalArgumentException("Invalid template type: " + type);
+ }
+ }
+
+ protected String customTemplateName(TemplateType type) {
+ switch (type) {
+ case ENTITY_SINGLE_CLASS:
+ return template;
+ case ENTITY_SUBCLASS:
+ return template;
+ case ENTITY_SUPERCLASS:
+ return superTemplate;
+ case EMBEDDABLE_SUBCLASS:
+ return embeddableTemplate;
+ case EMBEDDABLE_SUPERCLASS:
+ return embeddableSuperTemplate;
+ case DATAMAP_SINGLE_CLASS:
+ return queryTemplate;
+ case DATAMAP_SUPERCLASS:
+ return querySuperTemplate;
+ case DATAMAP_SUBCLASS:
+ return queryTemplate;
+ default:
+ throw new IllegalArgumentException("Invalid template type: " + type);
+ }
+ }
+
+ /**
+ * Returns a String used to prefix class name to create a generated
+ * superclass. Default value is "_".
+ */
+ protected String getSuperclassPrefix() {
+ return ClassGenerationAction.SUPERCLASS_PREFIX;
+ }
+
+ /**
+ * VelocityContext initialization method called once per artifact.
+ */
+ protected void resetContextForArtifact(Artifact artifact) {
+ StringUtils stringUtils = StringUtils.getInstance();
+
+ String qualifiedClassName = artifact.getQualifiedClassName();
+ String packageName = stringUtils.stripClass(qualifiedClassName);
+ String className = stringUtils.stripPackageName(qualifiedClassName);
+
+ String qualifiedBaseClassName = artifact.getQualifiedBaseClassName();
+ String basePackageName = stringUtils.stripClass(qualifiedBaseClassName);
+ String baseClassName = stringUtils.stripPackageName(qualifiedBaseClassName);
+
+ String superClassName = getSuperclassPrefix() + stringUtils.stripPackageName(qualifiedClassName);
+
+ String superPackageName = this.superPkg;
+ if (superPackageName == null) {
+ superPackageName = packageName + ".auto";
+ }
+
+ context.put(Artifact.BASE_CLASS_KEY, baseClassName);
+ context.put(Artifact.BASE_PACKAGE_KEY, basePackageName);
+
+ context.put(Artifact.SUB_CLASS_KEY, className);
+ context.put(Artifact.SUB_PACKAGE_KEY, packageName);
+
+ context.put(Artifact.SUPER_CLASS_KEY, superClassName);
+ context.put(Artifact.SUPER_PACKAGE_KEY, superPackageName);
+
+ context.put(Artifact.OBJECT_KEY, artifact.getObject());
+ context.put(Artifact.STRING_UTILS_KEY, stringUtils);
+
+ context.put(Artifact.CREATE_PROPERTY_NAMES, createPropertyNames);
+ }
+
+ /**
+ * VelocityContext initialization method called once per each artifact and
+ * template type combination.
+ */
+ protected void resetContextForArtifactTemplate(Artifact artifact, TemplateType templateType) {
+ context.put(Artifact.IMPORT_UTILS_KEY, new ImportUtils());
+ artifact.postInitContext(context);
+ }
+
+ /**
+ * Executes class generation once per each artifact.
+ */
+ public void execute() throws Exception {
+
+ validateAttributes();
+
+ try {
+ for (Artifact artifact : artifacts) {
+ execute(artifact);
+ }
+ } finally {
+ // must reset engine at the end of class generator run to avoid
+ // memory
+ // leaks and stale templates
+ this.templateCache.clear();
+ }
+ }
+
+ /**
+ * Executes class generation for a single artifact.
+ */
+ protected void execute(Artifact artifact) throws Exception {
+
+ resetContextForArtifact(artifact);
+
+ ArtifactGenerationMode artifactMode = makePairs ? ArtifactGenerationMode.GENERATION_GAP
+ : ArtifactGenerationMode.SINGLE_CLASS;
+
+ TemplateType[] templateTypes = artifact.getTemplateTypes(artifactMode);
+ for (TemplateType type : templateTypes) {
+
+ try (Writer out = openWriter(type);) {
+ if (out != null) {
+
+ resetContextForArtifactTemplate(artifact, type);
+ getTemplate(type).merge(context, out);
+ }
+ }
+ }
+ }
+
+ protected Template getTemplate(TemplateType type) throws Exception {
+
+ String templateName = customTemplateName(type);
+ if (templateName == null) {
+ templateName = defaultTemplateName(type);
+ }
+
+ // Velocity < 1.5 has some memory problems, so we will create a
+ // VelocityEngine
+ // every time, and store templates in an internal cache, to avoid
+ // uncontrolled
+ // memory leaks... Presumably 1.5 fixes it.
+
+ Template template = templateCache.get(templateName);
+
+ if (template == null) {
+
+ Properties props = new Properties();
+
+ // null logger that will prevent velocity.log from being generated
+ props.put(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogSystem.class.getName());
+ props.put("resource.loader", "cayenne");
+ props.put("cayenne.resource.loader.class", ClassGeneratorResourceLoader.class.getName());
+ props.put("cayenne.resource.loader.cache", "false");
+
+ VelocityEngine velocityEngine = new VelocityEngine();
+ velocityEngine.init(props);
+
+ template = velocityEngine.getTemplate(templateName);
+ templateCache.put(templateName, template);
+ }
+
+ return template;
+ }
+
+ /**
+ * Validates the state of this class generator. Throws
+ * CayenneRuntimeException if it is in an inconsistent state. Called
+ * internally from "execute".
+ */
+ protected void validateAttributes() {
+ if (destDir == null) {
+ throw new CayenneRuntimeException("'destDir' attribute is missing.");
+ }
+
+ if (!destDir.isDirectory()) {
+ throw new CayenneRuntimeException("'destDir' is not a directory.");
+ }
+
+ if (!destDir.canWrite()) {
+ throw new CayenneRuntimeException("Do not have write permissions for " + destDir);
+ }
+ }
+
+ /**
+ * Sets the destDir.
+ */
+ public void setDestDir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Sets <code>overwrite</code> property.
+ */
+ public void setOverwrite(boolean overwrite) {
+ this.overwrite = overwrite;
+ }
+
+ /**
+ * Sets <code>makepairs</code> property.
+ */
+ public void setMakePairs(boolean makePairs) {
+ this.makePairs = makePairs;
+ }
+
+ /**
+ * Sets <code>template</code> property.
+ */
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+
+ /**
+ * Sets <code>superTemplate</code> property.
+ */
+ public void setSuperTemplate(String superTemplate) {
+ this.superTemplate = superTemplate;
+ }
+
+ public void setQueryTemplate(String queryTemplate) {
+ this.queryTemplate = queryTemplate;
+ }
+
+ public void setQuerySuperTemplate(String querySuperTemplate) {
+ this.querySuperTemplate = querySuperTemplate;
+ }
+
+ /**
+ * Sets <code>usepkgpath</code> property.
+ */
+ public void setUsePkgPath(boolean usePkgPath) {
+ this.usePkgPath = usePkgPath;
+ }
+
+ /**
+ * Sets <code>outputPattern</code> property.
+ */
+ public void setOutputPattern(String outputPattern) {
+ this.outputPattern = outputPattern;
+ }
+
+ /**
+ * Sets <code>createPropertyNames</code> property.
+ */
+ public void setCreatePropertyNames(boolean createPropertyNames) {
+ this.createPropertyNames = createPropertyNames;
+ }
+
+ /**
+ * Opens a Writer to write generated output. Returned Writer is mapped to a
+ * filesystem file (although subclasses may override that). File location is
+ * determined from the current state of VelocityContext and the TemplateType
+ * passed as a parameter. Writer encoding is determined from the value of
+ * the "encoding" property.
+ */
+ protected Writer openWriter(TemplateType templateType) throws Exception {
+
+ File outFile = (templateType.isSuperclass()) ? fileForSuperclass() : fileForClass();
+ if (outFile == null) {
+ return null;
+ }
+
+ if (logger != null) {
+ String label = templateType.isSuperclass() ? "superclass" : "class";
+ logger.info("Generating " + label + " file: " + outFile.getCanonicalPath());
+ }
+
+ // return writer with specified encoding
+ FileOutputStream out = new FileOutputStream(outFile);
+
+ return (encoding != null) ? new OutputStreamWriter(out, encoding) : new OutputStreamWriter(out);
+ }
+
+ /**
+ * Returns a target file where a generated superclass must be saved. If null
+ * is returned, class shouldn't be generated.
+ */
+ protected File fileForSuperclass() throws Exception {
+
+ String packageName = (String) context.get(Artifact.SUPER_PACKAGE_KEY);
+ String className = (String) context.get(Artifact.SUPER_CLASS_KEY);
+
+ String filename = StringUtils.getInstance().replaceWildcardInStringWithString(WILDCARD, outputPattern, className);
+ File dest = new File(mkpath(destDir, packageName), filename);
+
+ // Ignore if the destination is newer than the map
+ // (internal timestamp), i.e. has been generated after the map was
+ // last saved AND the template is older than the destination file
+ if (dest.exists() && !isOld(dest)) {
+
+ if (superTemplate == null) {
+ return null;
+ }
+
+ File superTemplateFile = new File(superTemplate);
+ if (superTemplateFile.lastModified() < dest.lastModified()) {
+ return null;
+ }
+ }
+
+ return dest;
+ }
+
+ /**
+ * Returns a target file where a generated class must be saved. If null is
+ * returned, class shouldn't be generated.
+ */
+ protected File fileForClass() throws Exception {
+
+ String packageName = (String) context.get(Artifact.SUB_PACKAGE_KEY);
+ String className = (String) context.get(Artifact.SUB_CLASS_KEY);
+
+ String filename = StringUtils.getInstance().replaceWildcardInStringWithString(WILDCARD, outputPattern, className);
+ File dest = new File(mkpath(destDir, packageName), filename);
+
+ if (dest.exists()) {
+ // no overwrite of subclasses
+ if (makePairs) {
+ return null;
+ }
+
+ // skip if said so
+ if (!overwrite) {
+ return null;
+ }
+
+ // Ignore if the destination is newer than the map
+ // (internal timestamp), i.e. has been generated after the map was
+ // last saved AND the template is older than the destination file
+ if (!isOld(dest)) {
+
+ if (template == null) {
+ return null;
+ }
+
+ File templateFile = new File(template);
+ if (templateFile.lastModified() < dest.lastModified()) {
+ return null;
+ }
+ }
+ }
+
+ return dest;
+ }
+
+ /**
+ * Returns true if <code>file</code> parameter is older than internal
+ * timestamp of this class generator.
+ */
+ protected boolean isOld(File file) {
+ return file.lastModified() <= timestamp;
+ }
+
+ /**
+ * Returns a File object corresponding to a directory where files that
+ * belong to <code>pkgName</code> package should reside. Creates any missing
+ * diectories below <code>dest</code>.
+ */
+ protected File mkpath(File dest, String pkgName) throws Exception {
+
+ if (!usePkgPath || pkgName == null) {
+ return dest;
+ }
+
+ String path = pkgName.replace('.', File.separatorChar);
+ File fullPath = new File(dest, path);
+ if (!fullPath.isDirectory() && !fullPath.mkdirs()) {
+ throw new Exception("Error making path: " + fullPath);
+ }
+
+ return fullPath;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Sets file encoding. If set to null, default system encoding will be used.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Sets "superPkg" property value.
+ */
+ public void setSuperPkg(String superPkg) {
+ this.superPkg = superPkg;
+ }
+
+ /**
+ * @param dataMap
+ * The dataMap to set.
+ */
+ public void setDataMap(DataMap dataMap) {
+ this.dataMap = dataMap;
+ }
+
+ /**
+ * Adds entities to the internal entity list.
+ */
+ public void addEntities(Collection<ObjEntity> entities) {
+ if (artifactsGenerationMode == ArtifactsGenerationMode.ENTITY
+ || artifactsGenerationMode == ArtifactsGenerationMode.ALL) {
+ if (entities != null) {
+ for (ObjEntity entity : entities) {
+ artifacts.add(new EntityArtifact(entity));
+ }
+ }
+ }
+ }
+
+ public void addEmbeddables(Collection<Embeddable> embeddables) {
+ if (artifactsGenerationMode == ArtifactsGenerationMode.ENTITY
+ || artifactsGenerationMode == ArtifactsGenerationMode.ALL) {
+ if (embeddables != null) {
+ for (Embeddable embeddable : embeddables) {
+ artifacts.add(new EmbeddableArtifact(embeddable));
+ }
+ }
+ }
+ }
+
+ public void addQueries(Collection<QueryDescriptor> queries) {
+ if (artifactsGenerationMode == ArtifactsGenerationMode.DATAMAP
+ || artifactsGenerationMode == ArtifactsGenerationMode.ALL) {
+
+ // TODO: andrus 10.12.2010 - why not also check for empty query
+ // list?? Or
+ // create a better API for enabling DataMapArtifact
+ if (queries != null) {
+ artifacts.add(new DataMapArtifact(dataMap, queries));
+ }
+ }
+ }
+
+ /**
+ * Sets an optional shared VelocityContext. Useful with tools like VPP that
+ * can set custom values in the context, not known to Cayenne.
+ */
+ public void setContext(VelocityContext context) {
+ this.context = context;
+ }
+
+ /**
+ * Injects an optional logger that will be used to trace generated files at
+ * the info level.
+ */
+ public void setLogger(Log logger) {
+ this.logger = logger;
+ }
+
+ public void setEmbeddableTemplate(String embeddableTemplate) {
+ this.embeddableTemplate = embeddableTemplate;
+ }
+
+ public void setEmbeddableSuperTemplate(String embeddableSuperTemplate) {
+ this.embeddableSuperTemplate = embeddableSuperTemplate;
+ }
+
+ public void setArtifactsGenerationMode(String mode) {
+ if (ArtifactsGenerationMode.ENTITY.getLabel().equalsIgnoreCase(mode)) {
+ this.artifactsGenerationMode = ArtifactsGenerationMode.ENTITY;
+ } else if (ArtifactsGenerationMode.DATAMAP.getLabel().equalsIgnoreCase(mode)) {
+ this.artifactsGenerationMode = ArtifactsGenerationMode.DATAMAP;
+ } else {
+ this.artifactsGenerationMode = ArtifactsGenerationMode.ALL;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGeneratorResourceLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGeneratorResourceLoader.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGeneratorResourceLoader.java
new file mode 100644
index 0000000..8e8a1ee
--- /dev/null
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGeneratorResourceLoader.java
@@ -0,0 +1,102 @@
+/*****************************************************************
+ * 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.cayenne.gen;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.resource.loader.FileResourceLoader;
+
+/**
+ * Velocity template resource loader customized for Cayenne use. Supports loading
+ * templates from the thread ClassLoader and from relative and absolute paths.
+ *
+ * @since 1.2
+ */
+// must be public top-level class as it is
+// instantiated via reflection by Velocity
+public class ClassGeneratorResourceLoader extends FileResourceLoader {
+
+ /**
+ * Returns resource as InputStream. First calls super implementation. If resource
+ * wasn't found, it attempts to load it from current directory or as an absolute path.
+ */
+ @Override
+ public synchronized InputStream getResourceStream(String name)
+ throws ResourceNotFoundException {
+
+ InputStream stream = loadFromRelativePath(name);
+ if (stream != null) {
+ return stream;
+ }
+
+ stream = loadFromAbsPath(name);
+ if (stream != null) {
+ return stream;
+ }
+
+ stream = loadFromThreadClassLoader(name);
+ if (stream != null) {
+ return stream;
+ }
+
+ stream = loadFromThisClassLoader(name);
+ if (stream != null) {
+ return stream;
+ }
+
+ throw new ResourceNotFoundException("Couldn't find resource '"
+ + name
+ + "'. Searched filesystem path and classpath");
+ }
+
+ protected InputStream loadFromRelativePath(String name) {
+ try {
+ return super.getResourceStream(name);
+ }
+ catch (ResourceNotFoundException rnfex) {
+ return null;
+ }
+ }
+
+ protected InputStream loadFromAbsPath(String name) {
+ try {
+ File file = new File(name);
+ return (file.canRead()) ? new BufferedInputStream(new FileInputStream(file
+ .getAbsolutePath())) : null;
+
+ }
+ catch (FileNotFoundException fnfe) {
+ return null;
+ }
+ }
+
+ protected InputStream loadFromThreadClassLoader(String name) {
+ return Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
+ }
+
+ protected InputStream loadFromThisClassLoader(String name) {
+ return getClass().getClassLoader().getResourceAsStream(name);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java
new file mode 100644
index 0000000..c89b1eb
--- /dev/null
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java
@@ -0,0 +1,80 @@
+/*****************************************************************
+ * 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.cayenne.gen;
+
+import java.util.Collection;
+
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.QueryDescriptor;
+
+/**
+ * @since 3.0
+ */
+public class ClientClassGenerationAction extends ClassGenerationAction {
+
+ public static final String SUBCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "client-subclass.vm";
+ public static final String SUPERCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "client-superclass.vm";
+
+ public static final String DMAP_SINGLE_CLASS_TEMPLATE = TEMPLATES_DIR_NAME + "client-datamap-singleclass.vm";
+ public static final String DMAP_SUBCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "client-datamap-subclass.vm";
+ public static final String DMAP_SUPERCLASS_TEMPLATE = TEMPLATES_DIR_NAME + "client-datamap-superclass.vm";
+
+ public static final String CLIENT_SUPERCLASS_PREFIX = "_Client";
+
+ @Override
+ protected String defaultTemplateName(TemplateType type) {
+ switch (type) {
+ case ENTITY_SUBCLASS:
+ return ClientClassGenerationAction.SUBCLASS_TEMPLATE;
+ case ENTITY_SUPERCLASS:
+ return ClientClassGenerationAction.SUPERCLASS_TEMPLATE;
+ case EMBEDDABLE_SUBCLASS:
+ return EMBEDDABLE_SUBCLASS_TEMPLATE;
+ case EMBEDDABLE_SUPERCLASS:
+ return EMBEDDABLE_SUPERCLASS_TEMPLATE;
+
+ case DATAMAP_SUPERCLASS:
+ return ClientClassGenerationAction.DMAP_SUPERCLASS_TEMPLATE;
+ case DATAMAP_SUBCLASS:
+ return ClientClassGenerationAction.DMAP_SUBCLASS_TEMPLATE;
+ default:
+ throw new IllegalArgumentException("Unsupported template type: " + type);
+ }
+ }
+
+ @Override
+ public void addEntities(Collection<ObjEntity> entities) {
+ if (entities != null) {
+ for (ObjEntity entity : entities) {
+ artifacts.add(new ClientEntityArtifact(entity));
+ }
+ }
+ }
+
+ @Override
+ public void addQueries(Collection<QueryDescriptor> queries) {
+ if (artifactsGenerationMode == ArtifactsGenerationMode.DATAMAP
+ || artifactsGenerationMode == ArtifactsGenerationMode.ALL) {
+ if (queries != null) {
+ artifacts.add(new ClientDataMapArtifact(dataMap, queries));
+ }
+ }
+ }
+}