Skip to main content
summaryrefslogtreecommitdiffstats
path: root/jpa
diff options
context:
space:
mode:
authornhauge2009-03-11 03:28:11 +0000
committernhauge2009-03-11 03:28:11 +0000
commit1d908333499a3351bf79de5ebc27a953addc5c17 (patch)
tree4dfac0347008a8124a16b5725c08a0a8102ec2e3 /jpa
parentdc3c74146ae38cb08d839474e6a6dfc95f9bd37d (diff)
downloadwebtools.dali-1d908333499a3351bf79de5ebc27a953addc5c17.tar.gz
webtools.dali-1d908333499a3351bf79de5ebc27a953addc5c17.tar.xz
webtools.dali-1d908333499a3351bf79de5ebc27a953addc5c17.zip
[251293] Initial check-in for entity generation contribution. Added dependency on apache commons, commons.lang, and oro from orbit Temporarily added local dependency on velocity-1.5 until it is also included in orbit.
Diffstat (limited to 'jpa')
-rw-r--r--jpa/features/org.eclipse.jpt.feature/feature.xml21
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/.classpath1
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF16
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/build.properties3
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/lib/velocity-1.5.jarbin0 -> 392124 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/property_files/jpt_gen.properties3
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/JptGenMessages.java1
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/Association.java387
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/AssociationRole.java251
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/BaseEntityGenCustomizer.java201
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/DatabaseAnnotationNameBuilder.java96
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ForeignKeyInfo.java120
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenMessages.java35
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenPlugin.java24
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenColumn.java329
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenCustomizer.java752
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenTable.java828
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/OverwriteConfirmer.java50
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/PackageGenerator2.java266
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/TagNames.java46
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/CompilationUnitModifier.java131
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/DTPUtil.java116
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/FileUtil.java218
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/StringUtil.java648
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/UrlUtil.java125
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/column.vm52
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/join.vm61
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/main.java.vm129
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToMany.vm14
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToOne.vm7
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/mappingKind.vm30
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToMany.vm14
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToOne.vm14
-rw-r--r--jpa/plugins/org.eclipse.jpt.gen/templates/entities/pk.java.vm65
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF3
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gifbin0 -> 920 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.pngbin0 -> 1000 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.pngbin0 -> 448 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.pngbin0 -> 1072 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.pngbin0 -> 989 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.pngbin0 -> 1059 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.pngbin0 -> 1050 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gifbin0 -> 121 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.pngbin0 -> 380 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.pngbin0 -> 1004 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.pngbin0 -> 1072 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.pngbin0 -> 305 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.pngbin0 -> 284 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.pngbin0 -> 1022 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.pngbin0 -> 1057 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.pngbin0 -> 1096 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.pngbin0 -> 993 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.pngbin0 -> 1222 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.pngbin0 -> 1047 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.pngbin0 -> 232 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.pngbin0 -> 190 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.pngbin0 -> 232 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.pngbin0 -> 1219 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.pngbin0 -> 1051 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.pngbin0 -> 928 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.pngbin0 -> 978 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.pngbin0 -> 989 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.pngbin0 -> 924 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.pngbin0 -> 976 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.pngbin0 -> 196 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gifbin0 -> 113 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gifbin0 -> 1715 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/file.pngbin0 -> 456 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.pngbin0 -> 310 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gifbin0 -> 138 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gifbin0 -> 138 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/package.pngbin0 -> 319 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gifbin0 -> 953 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gifbin0 -> 561 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gifbin0 -> 82 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.pngbin0 -> 322 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.pngbin0 -> 508 bytes
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/plugin.properties2
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/plugin.xml34
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties128
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/CommonImages.java101
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/TestJunk.java59
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java3
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator2.java236
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java215
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java188
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java127
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java160
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java183
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java353
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java521
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java226
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java416
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java605
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java112
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java193
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java51
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java154
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java133
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java78
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java751
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java76
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java393
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java351
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java533
105 files changed, 11432 insertions, 7 deletions
diff --git a/jpa/features/org.eclipse.jpt.feature/feature.xml b/jpa/features/org.eclipse.jpt.feature/feature.xml
index 4288ecfa50..509f764031 100644
--- a/jpa/features/org.eclipse.jpt.feature/feature.xml
+++ b/jpa/features/org.eclipse.jpt.feature/feature.xml
@@ -73,4 +73,25 @@
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.apache.commons.collections"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.commons.lang"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.oro"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
diff --git a/jpa/plugins/org.eclipse.jpt.gen/.classpath b/jpa/plugins/org.eclipse.jpt.gen/.classpath
index 8f257414e6..731b00f305 100644
--- a/jpa/plugins/org.eclipse.jpt.gen/.classpath
+++ b/jpa/plugins/org.eclipse.jpt.gen/.classpath
@@ -2,6 +2,7 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="property_files"/>
+ <classpathentry exported="true" kind="lib" path="lib/velocity-1.5.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
diff --git a/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF
index b6698a3e63..ee9c80a83e 100644
--- a/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF
+++ b/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF
@@ -3,12 +3,20 @@ Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.jpt.gen
-Bundle-Version: 1.2.100.qualifier
-Bundle-ClassPath: .
+Bundle-Version: 1.3.0.qualifier
+Bundle-ClassPath: .,
+ lib/velocity-1.5.jar
Bundle-Localization: plugin
-Export-Package: org.eclipse.jpt.gen.internal; x-friends:="org.eclipse.jpt.ui"
+Export-Package: org.eclipse.jpt.gen.internal;x-friends:="org.eclipse.jpt.ui",
+ org.eclipse.jpt.gen.internal2,
+ org.eclipse.jpt.gen.internal2.util
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.jdt.core;bundle-version="[3.4.0,4.0.0)",
org.eclipse.jpt.utility;bundle-version="[1.2.0,2.0.0)",
- org.eclipse.jpt.db;bundle-version="[1.2.0,2.0.0)"
+ org.eclipse.jpt.db;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.jface.text;bundle-version="[3.4.0,4.0.0)",
+ org.apache.commons.collections;bundle-version="3.2.0",
+ org.apache.commons.lang;bundle-version="2.1.0",
+ org.apache.oro;bundle-version="2.0.8"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/jpa/plugins/org.eclipse.jpt.gen/build.properties b/jpa/plugins/org.eclipse.jpt.gen/build.properties
index a1fd5b8411..038c63b3f2 100644
--- a/jpa/plugins/org.eclipse.jpt.gen/build.properties
+++ b/jpa/plugins/org.eclipse.jpt.gen/build.properties
@@ -13,5 +13,6 @@ output.. = bin/
bin.includes = .,\
META-INF/,\
about.html,\
- plugin.properties
+ plugin.properties,\
+ lib/velocity-1.5.jar
jars.compile.order = .
diff --git a/jpa/plugins/org.eclipse.jpt.gen/lib/velocity-1.5.jar b/jpa/plugins/org.eclipse.jpt.gen/lib/velocity-1.5.jar
new file mode 100644
index 0000000000..7c7f2c43b4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/lib/velocity-1.5.jar
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.gen/property_files/jpt_gen.properties b/jpa/plugins/org.eclipse.jpt.gen/property_files/jpt_gen.properties
index 03e8908d0e..3427be198d 100644
--- a/jpa/plugins/org.eclipse.jpt.gen/property_files/jpt_gen.properties
+++ b/jpa/plugins/org.eclipse.jpt.gen/property_files/jpt_gen.properties
@@ -11,3 +11,6 @@
PackageGenerator_taskName=Generate Entities
GenScope_taskName=Build Database Model
EntityGenerator_taskName=Generate Entity: {0}
+Error_Generating_Entities = Error Generating Entities;
+
+Templates_notFound = Unable to find JPA entities generation templates in plugin \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/JptGenMessages.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/JptGenMessages.java
index bc3bbf0d38..b765abd340 100644
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/JptGenMessages.java
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/JptGenMessages.java
@@ -19,6 +19,7 @@ class JptGenMessages {
public static String PackageGenerator_taskName;
public static String GenScope_taskName;
public static String EntityGenerator_taskName;
+ public static String Templates_notFound;
private static final String BUNDLE_NAME = "jpt_gen"; //$NON-NLS-1$
private static final Class<?> BUNDLE_CLASS = JptGenMessages.class;
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/Association.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/Association.java
new file mode 100644
index 0000000000..aef08c4221
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/Association.java
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import java.util.List;
+
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.gen.internal2.util.StringUtil;
+
+/**
+ * Represents an ORM association.
+ * There are two types of associations:
+ * <ul><li>simple association: An association between two database tables.
+ * The <em>referrer</code> table is the one containing the foreign key
+ * , the <em>referenced</code> table is the other party.<br>
+ *
+ * <li>many to many association: An association between two tables joined by
+ * a <em>join table</em>.
+ * In the example AUTHOR, BOOK, AUTHOR_BOOK, The referrer and referenced are
+ * AUTHOR and BOOK, and the join table is AUTHOR_BOOK.
+ * </ul>
+ *
+ */
+public class Association implements java.io.Serializable
+{
+ private final static long serialVersionUID = 2;
+
+ public static final String MANY_TO_ONE = "many-to-one";
+ public static final String MANY_TO_MANY = "many-to-many";
+ public static final String ONE_TO_ONE = "one-to-one";
+ public static final String ONE_TO_MANY = "one-to-many";
+
+ public static final String BI_DI = "bi-di";
+ public static final String NORMAL_DI = "normal-di"; //referrer->referenced
+ public static final String OPPOSITE_DI = "opposite-di"; //referenced->referrer
+
+ private transient ORMGenCustomizer mCustomizer;
+ private String mReferrerTableName;
+ private String mReferencedTableName;
+ private String mJoinTableName;
+
+ private List<String> mReferrerColNames; /*String objects*/
+ private List<String> mReferencedColNames; /*String objects*/
+ private List<String> mReferrerJoinColNames; /*String objects*/
+ private List<String> mReferencedJoinColNames; /*String objects*/
+
+ private transient List<ORMGenColumn> mReferrerCols; /*ORMGenColumn objects*/
+ private transient List<ORMGenColumn> mReferencedCols; /*ORMGenColumn objects*/
+ private transient List<ORMGenColumn> mReferrerJoinCols; /*ORMGenColumn objects*/
+ private transient List<ORMGenColumn> mReferencedJoinCols; /*ORMGenColumn objects*/
+
+ private String mCardinality;
+ private String mDirectionality;
+ private byte mFlags = GENERATED;
+
+ private AssociationRole mReferrerRole;
+ private AssociationRole mReferencedRole;
+
+ private transient ForeignKey mForeignKey;
+
+ /*constants for mFlags*/
+ /*whether the association should be generated*/
+ private static final byte GENERATED = 1 << 0;
+ /*whether the association is custom (i.e is not auto computed from foreign keys relationships).*/
+ private static final byte CUSTOM = 1 << 1;
+
+ /**
+ * The simple association constructor.
+ * The 2 tables are joined when the values of each column in
+ * referrerColNames match its corresponding column in referencedColNames.
+ *
+ * @param referrerTableName The "foreign key" table.
+ * @param referrerColNames The column names in the referrer table.
+ * @param referencedTableName The "primary key" table.
+ * @param referencedColNames The column names in the referenced table.
+ */
+ public Association(ORMGenCustomizer customizer, String referrerTableName, List<String> referrerColNames
+ , String referencedTableName, List<String> referencedColNames) {
+ super();
+
+ mCustomizer = customizer;
+ mReferrerTableName = referrerTableName;
+ mReferencedTableName = referencedTableName;
+ mReferrerColNames = referrerColNames;
+ mReferencedColNames = referencedColNames;
+
+ mCardinality = MANY_TO_ONE;
+ mDirectionality = BI_DI;
+
+ setCustom(true);
+ }
+ /**
+ * The many to many constructor.
+ * The 2 tables are joined when the values of each column in
+ * referrerColNames match its corresponding column in referrerJoinColNames
+ * , and each column in referencedColNames match its corresponding column in referencedJoinColNames.
+ *
+ */
+ public Association(ORMGenCustomizer customizer, String referrerTableName, List<String> referrerColNames
+ , String referencedTableName, List<String> referencedColNames
+ , String joinTableName, List<String> referrerJoinColNames, List<String> referencedJoinColNames) {
+ super();
+
+ mCustomizer = customizer;
+ mReferrerTableName = referrerTableName;
+ mReferencedTableName = referencedTableName;
+ mReferrerColNames = referrerColNames;
+ mReferencedColNames = referencedColNames;
+ mJoinTableName = joinTableName;
+ mReferrerJoinColNames = referrerJoinColNames;
+ mReferencedJoinColNames = referencedJoinColNames;
+
+ mCardinality = MANY_TO_MANY;
+ mDirectionality = BI_DI;
+
+ setCustom(true);
+ }
+ /**
+ * Empty constructor needed by the deserialization (should not be used otherwise).
+ */
+ public Association() {
+ }
+ /**
+ * Computes the cardinality basedon the forign key definitions.
+ */
+ public void computeCardinality() {
+ /*by default the association is many-to-one unless the foreign key
+ * is also the primary key, in which case it is a one-to-one.*/
+ mCardinality = MANY_TO_ONE;
+
+ List<ORMGenColumn> referrerCols = getReferrerColumns();
+ List<ORMGenColumn> pkCols = getReferrerTable().getPrimaryKeyColumns();
+ if (pkCols.size() == referrerCols.size()) {
+ boolean isFkPk = true;
+ for (int i = 0, n = pkCols.size(); i < n; ++i) {
+ if (!((ORMGenColumn)pkCols.get(i)).getName().equals(((ORMGenColumn)referrerCols.get(i)).getName())) {
+ isFkPk = false;
+ break;
+ }
+ }
+ if (isFkPk) {
+ mCardinality = ONE_TO_ONE;
+ }
+ }
+
+ setCustom(false);
+ }
+ /**
+ * Called after the asscociations are deserialized to attach
+ * the customizer object.
+ */
+ protected void restore(ORMGenCustomizer customizer) {
+ mCustomizer = customizer;
+
+ if (mReferrerRole != null) {
+ mReferrerRole.restore(this);
+ }
+ if (mReferencedRole != null) {
+ mReferencedRole.restore(this);
+ }
+ }
+ public ORMGenTable getReferrerTable() {
+ return mCustomizer.getTable(mReferrerTableName);
+ }
+ public String getReferrerTableName() {
+ return mReferrerTableName;
+ }
+ public ORMGenTable getReferencedTable() {
+ return mCustomizer.getTable(mReferencedTableName);
+ }
+ public String getReferencedTableName() {
+ return mReferencedTableName;
+ }
+ public ORMGenTable getJoinTable() {
+ return mCustomizer.getTable(mJoinTableName);
+ }
+ public String getJoinTableName() {
+ return mJoinTableName;
+ }
+ /**
+ * Returns the <code>ORMGenColumn</code> objects for the referrer
+ * columns.
+ */
+ public List<ORMGenColumn> getReferrerColumns() {
+ if (mReferrerCols == null) {
+ mReferrerCols = getReferrerTable().getColumnsByNames(mReferrerColNames);
+ }
+ return mReferrerCols;
+ }
+ public List<String> getReferrerColumnNames() {
+ return mReferrerColNames;
+ }
+ /**
+ * Returns the <code>ORMGenColumn</code> objects for the referenced
+ * columns.
+ */
+ public List<ORMGenColumn> getReferencedColumns() {
+ if (mReferencedCols == null) {
+ mReferencedCols = getReferencedTable().getColumnsByNames(mReferencedColNames);
+ }
+ return mReferencedCols;
+ }
+ public List<String> getReferencedColumnNames() {
+ return mReferencedColNames;
+ }
+ public List<ORMGenColumn> getReferrerJoinColumns() {
+ if (mReferrerJoinCols == null) {
+ mReferrerJoinCols = getJoinTable().getColumnsByNames(mReferrerJoinColNames);
+ }
+ return mReferrerJoinCols;
+ }
+ public List<String> getReferrerJoinColumnNames() {
+ return mReferrerJoinColNames;
+ }
+ public List<ORMGenColumn> getReferencedJoinColumns() {
+ if (mReferencedJoinCols == null) {
+ mReferencedJoinCols = getJoinTable().getColumnsByNames(mReferencedJoinColNames);
+ }
+ return mReferencedJoinCols;
+ }
+ public List<String> getReferencedJoinColumnNames() {
+ return mReferencedJoinColNames;
+ }
+ /**
+ * Returns the association cardinality, one of {@link #MANY_TO_ONE}|{@link #MANY_TO_MANY}
+ * |{@link #ONE_TO_ONE}|{@link #ONE_TO_MANY}
+ */
+ public String getCardinality() {
+ return mCardinality;
+ }
+ public void setCardinality(String cardinality) {
+ assert(cardinality.equals(MANY_TO_ONE) || cardinality.equals(MANY_TO_MANY) || cardinality.equals(ONE_TO_ONE) || cardinality.equals(ONE_TO_MANY));
+ mCardinality = cardinality;
+ }
+ /**
+ * Returns the association directionality, one of {@link #BI_DI}|{@link #NORMAL_DI}
+ * |{@link #OPPOSITE_DI}
+ */
+ public String getDirectionality() {
+ return mDirectionality;
+ }
+ public void setDirectionality(String dir) {
+ assert(dir.equals(BI_DI) || dir.equals(NORMAL_DI) || dir.equals(OPPOSITE_DI));
+ if (!dir.equals(mDirectionality)) {
+ mDirectionality = dir;
+
+ if (dir.equals(NORMAL_DI)) {
+ mReferencedRole = null;
+ } else if (dir.equals(OPPOSITE_DI)) {
+ mReferrerRole = null;
+ }
+ }
+ }
+
+ /**
+ * Tests whether this association is bidirectional.
+ * This is a shortcut for <code>getDirectionality().equals(BI_DI)</code>.
+ */
+ public boolean isBidirectional() {
+ return mDirectionality.equals(BI_DI);
+ }
+ /**
+ * Returns true of this association should be generated.
+ */
+ public boolean isGenerated() {
+ return (mFlags & GENERATED) != 0;
+ }
+ public void setGenerated(boolean generated) {
+ if (generated != isGenerated()) {
+ if (generated) {
+ mFlags |= GENERATED;
+ } else {
+ mFlags &= ~GENERATED;
+ }
+ mReferrerRole = mReferencedRole = null;
+ }
+ }
+ /**
+ * Returns true of this association is custom (i.e is not auto computed from foreign keys relationships).
+ */
+ public boolean isCustom() {
+ return (mFlags & CUSTOM) != 0;
+ }
+ public void setCustom(boolean custom) {
+ if (custom) {
+ mFlags |= CUSTOM;
+ } else {
+ mFlags &= ~CUSTOM;
+ }
+ }
+ /**
+ * Returns the association role for the referrer side, or null
+ * if none (i.e if the directionality does not include it).
+ */
+ public AssociationRole getReferrerRole() {
+ if (mReferrerRole == null && isGenerated()) {
+ if (!getDirectionality().equals(OPPOSITE_DI)) { //BI_DI or NORMAL_DI
+ mReferrerRole = new AssociationRole(this, true/*isReferrerEnd*/);
+ }
+ }
+ return mReferrerRole;
+ }
+ /**
+ * Returns the association role for the referenced side, or null
+ * if none (i.e if the directionality does not include it).
+ */
+ public AssociationRole getReferencedRole() {
+ if (mReferencedRole == null && isGenerated()) {
+ if (!getDirectionality().equals(Association.NORMAL_DI)) { //BI_DI or OPPOSITE_DI
+ mReferencedRole = new AssociationRole(this, false/*isReferrerEnd*/);
+ }
+ }
+ return mReferencedRole;
+ }
+ /**
+ * Tests whether this association is valid (valid table and column names).
+ */
+ protected boolean isValid(){
+ if (!isValidTableAndColumns(mReferrerTableName, mReferrerColNames)
+ || !isValidTableAndColumns(mReferencedTableName, mReferencedColNames)) {
+ return false;
+ }
+ if (mJoinTableName != null) {
+ if (!isValidTableAndColumns(mJoinTableName, mReferrerJoinColNames)
+ || !isValidTableAndColumns(mJoinTableName, mReferencedJoinColNames)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ private boolean isValidTableAndColumns(String tableName, List<String> columnNames) {
+ ORMGenTable table = mCustomizer.getTable(tableName);
+ if (table == null) {
+ return false;
+ }
+ for (int i = 0, n = columnNames.size(); i < n; ++i) {
+ String colName = (String)columnNames.get(i);
+ if (table.getColumnByName(colName) == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void setForeignKey(ForeignKey foreignKey) {
+ this.mForeignKey = foreignKey;
+
+ }
+ public ForeignKey getForeignKey(){
+ return this.mForeignKey;
+ };
+ public boolean equals(Object obj) {
+ if( this == obj )
+ return true;
+ if( obj instanceof Association ){
+ Association association2 = (Association)obj;
+ if (!this.getReferrerTableName().equals(association2.getReferrerTableName())
+ || !this.getReferencedTableName().equals(association2.getReferencedTableName())
+ || !StringUtil.equalObjects(this.getJoinTableName(), association2.getJoinTableName())
+ || !this.getReferrerColumnNames().equals(association2.getReferrerColumnNames())
+ || !this.getReferencedColumnNames().equals(association2.getReferencedColumnNames())
+ ) {
+ return false;
+ }
+ /*the 2 association have the same referrer, referenced and join table*/
+ //If MTO or OTM association
+ if (this.getJoinTableName() == null) {
+ return true;
+ }
+ if (this.getReferrerJoinColumnNames().equals(association2.getReferrerJoinColumnNames())
+ && this.getReferencedJoinColumnNames().equals(association2.getReferencedJoinColumnNames())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ public String toString(){
+ return mReferrerTableName + " " + mCardinality + " " + mReferencedTableName ;
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/AssociationRole.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/AssociationRole.java
new file mode 100644
index 0000000000..458edfd58e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/AssociationRole.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Represents an association role (the referrer or referenced role).
+ *
+ */
+public class AssociationRole implements java.io.Serializable
+{
+ private transient Association mAssociation; //transient: see restore
+ private boolean mIsReferrerRole;
+ private String mPropertyName;
+ private String mCascade;
+
+ private final static long serialVersionUID = 1;
+
+ AssociationRole(Association association, boolean isReferrerRole) {
+ super();
+
+ mAssociation = association;
+ mIsReferrerRole = isReferrerRole;
+ }
+ /**
+ * Empty constructor needed by the deserialization (should not be used otherwise).
+ */
+ public AssociationRole() {
+ }
+ /**
+ * Called after the asscociations are deserialized to attach
+ * the customizer object.
+ */
+ protected void restore(Association association) {
+ mAssociation = association;
+ }
+ public Association getAssociation() {
+ return mAssociation;
+ }
+ public boolean isReferrerRole() {
+ return mIsReferrerRole;
+ }
+ /**
+ * Returns the opposite role or null if the association
+ * is not bi directional.
+ */
+ public AssociationRole getOppositeRole() {
+ Association association = getAssociation();
+ if (!association.getDirectionality().equals(Association.BI_DI)) {
+ return null;
+ }
+ if (isReferrerRole()) {
+ return association.getReferencedRole();
+ } else {
+ return association.getReferrerRole();
+ }
+ }
+ /**
+ * Returns the association cardinality, one of {@link #MANY_TO_ONE}|{@link #MANY_TO_MANY}
+ * |{@link #ONE_TO_ONE}|{@link #ONE_TO_MANY}
+ */
+ public String getCardinality() {
+ String type = mAssociation.getCardinality();
+ if (!mIsReferrerRole) {
+ if (type.equals(Association.ONE_TO_MANY)) {
+ type = Association.MANY_TO_ONE;
+ } else if (type.equals(Association.MANY_TO_ONE)) {
+ type = Association.ONE_TO_MANY;
+ }
+ }
+ return type;
+ }
+ public ORMGenTable getReferrerTable() {
+ if (mIsReferrerRole) {
+ return mAssociation.getReferrerTable();
+ } else {
+ return mAssociation.getReferencedTable();
+ }
+ }
+ public List<ORMGenColumn> getReferrerColumns(){
+ if (mIsReferrerRole) {
+ return mAssociation.getReferrerColumns();
+ } else {
+ return mAssociation.getReferencedColumns();
+ }
+ }
+ /**
+ * Returns the referenced column corresponding to a referrer column.
+ */
+ public ORMGenColumn getReferencedColumn(String referrerColumn) {
+ boolean hasJoinTable = mAssociation.getJoinTable() != null;
+ List<ORMGenColumn> referrerColumns = getReferrerColumns();
+ for (int i = 0, n = referrerColumns.size(); i < n; ++i) {
+ ORMGenColumn column = (ORMGenColumn)referrerColumns.get(i);
+ if (column.getName().equals(referrerColumn)) {
+ if (hasJoinTable) {
+ return (ORMGenColumn)getReferrerJoinColumns().get(i);
+ } else {
+ return (ORMGenColumn)getReferencedColumns().get(i);
+ }
+ }
+ }
+ assert(false);
+ return null;
+ }
+ /**
+ * Returns the referrer column corresponding to a referenced column.
+ */
+ public ORMGenColumn getReferrerColumn(String referencedColumn) {
+ boolean hasJoinTable = mAssociation.getJoinTable() != null;
+ List<ORMGenColumn> referencedColumns = getReferencedColumns();
+ for (int i = 0, n = referencedColumns.size(); i < n; ++i) {
+ ORMGenColumn column = (ORMGenColumn)referencedColumns.get(i);
+ if (column.getName().equals(referencedColumn)) {
+ if (hasJoinTable) {
+ return (ORMGenColumn)getReferencedJoinColumns().get(i);
+ } else {
+ return (ORMGenColumn)getReferrerColumns().get(i);
+ }
+ }
+ }
+ assert(false);
+ return null;
+ }
+ public ORMGenTable getReferencedTable() {
+ if (mIsReferrerRole) {
+ return mAssociation.getReferencedTable();
+ } else {
+ return mAssociation.getReferrerTable();
+ }
+ }
+ public List<ORMGenColumn> getReferencedColumns() {
+ if (mIsReferrerRole) {
+ return mAssociation.getReferencedColumns();
+ } else {
+ return mAssociation.getReferrerColumns();
+ }
+ }
+ public List<ORMGenColumn> getReferrerJoinColumns() {
+ if (mIsReferrerRole) {
+ return mAssociation.getReferrerJoinColumns();
+ } else {
+ return mAssociation.getReferencedJoinColumns();
+ }
+ }
+ public List<ORMGenColumn> getReferencedJoinColumns() {
+ if (mIsReferrerRole) {
+ return mAssociation.getReferencedJoinColumns();
+ } else {
+ return mAssociation.getReferrerJoinColumns();
+ }
+ }
+
+ /**
+ * Returns the name that should be used by the generator for
+ * the property corresponding to this role.
+ */
+ public String getPropertyName() {
+ if (mPropertyName != null) { //if the user explicitly set it then don't be too smart
+ return mPropertyName;
+ }
+ String propName ="";
+ ORMGenTable referrerTable = getReferrerTable();
+ ORMGenTable referencedTable = getReferencedTable();
+
+ boolean isSingular = isSingular();
+ propName = referencedTable.getVarName(isSingular);
+
+ List<AssociationRole> clashingRoles = new java.util.ArrayList<AssociationRole>(); //roles with our same referrer and referenced tables (i.e would yield the same property name in the same bean)
+ /*make sure there is no role with the same name.*/
+ for (Iterator<AssociationRole> iter = referrerTable.getAssociationRoles().iterator(); iter.hasNext(); ) {
+ AssociationRole role = (AssociationRole)iter.next();
+ if (role.getReferrerTable().getName().equals(referrerTable.getName())
+ && role.getReferencedTable().getName().equals(referencedTable.getName())
+ && role.isSingular() == isSingular) {
+ clashingRoles.add(role);
+ }
+ }
+ if (clashingRoles.size() > 1) {
+ int index = clashingRoles.indexOf(this);
+ assert(index >= 0);
+ propName += index+1;
+ }
+
+ /*make sure there is no column with the same name.*/
+ for (Iterator<ORMGenColumn> iter = referrerTable.getColumns().iterator(); iter.hasNext(); ) {
+ ORMGenColumn column = (ORMGenColumn)iter.next();
+ if (column.getPropertyName().equals(propName)) {
+ String prefix = isSingular ? "Bean" : "Set";
+ propName += prefix;
+ break;
+ }
+ }
+
+ return propName;
+ }
+ private boolean isSingular() {
+ String cardinality = getCardinality();
+ return cardinality.equals(Association.ONE_TO_ONE) || cardinality.equals(Association.MANY_TO_ONE);
+ }
+ /**
+ * Changes the name that should be used by the generator for
+ * the property corresponding to this role.
+ * If the argument name is null or empty string then the
+ * default computed name is used.
+ */
+ public void setPropertyName(String name) {
+ if (name != null && name.length() == 0) {
+ name = null;
+ }
+ if (name != null && name.equals(getPropertyName())) {
+ name = null;
+ }
+ mPropertyName = name;
+ }
+ /**
+ * Returns the cascade value for this role, or null if none.
+ */
+ public String getCascade() {
+ return mCascade;
+ }
+ public void setCascade(String cascade) {
+ if (cascade != null && cascade.length() == 0) {
+ cascade = null;
+ }
+ mCascade = cascade;
+ }
+ /**
+ * Returns a descriptive string used in a comment in the generated
+ * file (from the Velocity template).
+ */
+ public String getDescription() {
+ //<!-- $directionality $cardinality association to $referencedClassName -->
+ String directionality;
+ if (getAssociation().getDirectionality().equals(Association.BI_DI)) {
+ directionality = "bi-directional";
+ } else {
+ directionality = "uni-directional";
+ }
+ return directionality + " " + getAssociation().getCardinality() + " association to " + getReferencedTable().getClassName();
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/BaseEntityGenCustomizer.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/BaseEntityGenCustomizer.java
new file mode 100644
index 0000000000..8b6191c3ca
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/BaseEntityGenCustomizer.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.gen.internal2.util.StringUtil;
+
+/**
+ * Default implementation of ORMGenCustomizer according to JPA specification
+ * for entity generation.
+ *
+ * This is used to retrieve/change the properties from the wizard
+ * and is also passed as a context object to Velocity.
+ */
+public class BaseEntityGenCustomizer extends ORMGenCustomizer implements java.io.Serializable
+{
+ private final static long serialVersionUID = 1;
+
+ /*mapping kinds*/
+ private static final String BASIC_MAPPING_KIND = "basic";
+ private static final String ID_MAPPING_KIND = "id";
+ private static final String VERSION_MAPPING_KIND = "version";
+
+
+ /*the strings for generator names. These appear in a combo box
+ * and used by the Velocity template processing.*/
+ private static final String AUTO_GENERATOR = "auto";
+ private static final String NONE_GENERATOR = "none";
+ private static final String IDENTITY_GENERATOR = "identity";
+ private static final String SEQUENCE_GENERATOR = "sequence";
+ private static final String TABLE_GENERATOR = "table";
+
+ public BaseEntityGenCustomizer(){}
+
+ public void init(File file, Schema schema) {
+ super.init(file, schema);
+ }
+
+ //-----------------------------------------
+ //------ ORMGenCustomizer methods
+ //-----------------------------------------
+ public List<String> getAllIdGenerators() {
+ List<String> result = new java.util.ArrayList<String>(5);
+ /*add in the order in which they would appear in the combo*/
+ result.add(AUTO_GENERATOR);
+ result.add(IDENTITY_GENERATOR);
+ result.add(SEQUENCE_GENERATOR);
+ result.add(TABLE_GENERATOR);
+ result.add(NONE_GENERATOR);
+ return result;
+ }
+ public String getNoIdGenerator() {
+ return NONE_GENERATOR;
+ }
+ public String getIdentityIdGenerator() {
+ return IDENTITY_GENERATOR;
+ }
+ public Set<String> getSequenceIdGenerators() {
+ Set<String> result = new java.util.HashSet<String>(3);
+ result.add(AUTO_GENERATOR);
+ result.add(SEQUENCE_GENERATOR);
+
+ return result;
+ }
+ public String getPropertyTypeFromColumn( Column column) {
+ return DTPUtil.getJavaType( getSchema(), column );
+ }
+ public String[] getAllPropertyTypes() {
+ /*
+ * Java primitive types, wrapper of the primitive types
+ * , java.lang.String, java.math.BigInteger,
+ * java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date,
+ * java.sql.Time, java.sql.Timestamp, byte[], Byte[], char[], Character[],
+ * enums, and any other type that implements Serializable.
+ * */
+ //return in the order that will be used in the combo
+ return new String[] {
+ "boolean"
+ , "Boolean"
+ , "byte"
+ , "Byte"
+ , "byte[]"
+ , "char"
+ , "char[]"
+ , "Character"
+ , "Character[]"
+ , "double"
+ , "Double"
+ , "float"
+ , "Float"
+ , "int"
+ , "Integer"
+ , "long"
+ , "Long"
+ , "Object"
+ , "short"
+ , "Short"
+ , "String"
+
+ , java.math.BigDecimal.class.getName()
+ , java.math.BigInteger.class.getName()
+ , java.util.Calendar.class.getName()
+ , java.util.Date.class.getName()
+ , java.sql.Date.class.getName()
+ , java.sql.Time.class.getName()
+ , java.sql.Timestamp.class.getName()
+ };
+ }
+ public String[] getAllMappingKinds() {
+ return new String[] {
+ BASIC_MAPPING_KIND
+ , ID_MAPPING_KIND
+ , VERSION_MAPPING_KIND
+ };
+ }
+ /* (non-Javadoc)
+ */
+ public String getBasicMappingKind() {
+ return BASIC_MAPPING_KIND;
+ }
+ /* (non-Javadoc)
+ */
+ public String getIdMappingKind() {
+ return ID_MAPPING_KIND;
+ }
+ public boolean editCascade(AssociationRole role) {
+ return false;
+ }
+
+ protected boolean manySideIsAssociationOwner() {
+ return true;
+ }
+
+ //-----------------------------------------
+ //---- Velocity templates methods
+ //-----------------------------------------
+ /**
+ * Returns the cascades annotation member value, or empty string
+ * if none.
+ * Empty string is returned instead of null because Velocity does not like null
+ * when used in #set.
+ */
+ public String genCascades(AssociationRole role) {
+ List<String> cascades = StringUtil.strToList(role.getCascade(), ',', true/*trim*/);
+ if (cascades == null) {
+ return "";
+ }
+ StringBuffer buffer = new StringBuffer("{");
+ for (int i = 0, n = cascades.size(); i < n; ++i) {
+ String cascade = (String)cascades.get(i);
+ String enumStr;
+ if (cascade.equals(TagNames.ALL_CASCADE)) {
+ enumStr = "CascadeType.ALL";
+ } else if (cascade.equals(TagNames.PERSIST_CASCADE)) {
+ enumStr = "CascadeType.PERSIST";
+ } else if (cascade.equals(TagNames.MERGE_CASCADE)) {
+ enumStr = "CascadeType.MERGE";
+ } else if (cascade.equals(TagNames.REMOVE_CASCADE)) {
+ enumStr = "CascadeType.REMOVE";
+ } else {
+ assert(cascade.equals(TagNames.REFRESH_CASCADE));
+ enumStr = "CascadeType.REFRESH";
+ }
+ if (i != 0) {
+ buffer.append(", ");
+ }
+ buffer.append(enumStr);
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+ /**
+ * Returns the fetch type annotation member value, or empty string
+ * if none.
+ * Empty string is returned instead of null because Velocity does not like null
+ * when used in #set.
+ */
+ public String genFetch(ORMGenTable table) {
+ String fetch = table.getDefaultFetch();
+ if (fetch == null) {
+ return "";
+ } else if (fetch.equals(ORMGenTable.LAZY_FETCH)) {
+ return "FetchType.LAZY";
+ } else {
+ return "FetchType.EAGER";
+ }
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/DatabaseAnnotationNameBuilder.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/DatabaseAnnotationNameBuilder.java
new file mode 100644
index 0000000000..ce93f829e3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/DatabaseAnnotationNameBuilder.java
@@ -0,0 +1,96 @@
+package org.eclipse.jpt.gen.internal2;
+
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.db.Table;
+
+
+/**
+ * Provide a pluggable way to determine whether and how the entity generator
+ * prints the names of various database objects.
+ */
+public interface DatabaseAnnotationNameBuilder {
+
+ /**
+ * Given the name of an entity and the table to which it is mapped,
+ * build and return a string to be used as the value for the entity's
+ * Table annotation's 'name' element. Return null if the entity
+ * maps to the table by default.
+ */
+ String buildTableAnnotationName(String entityName, Table table);
+
+ /**
+ * Given the name of an attribute (field or property) and the column
+ * to which it is mapped,
+ * build and return a string to be used as the value for the attribute's
+ * Column annotation's 'name' element. Return null if the attribute
+ * maps to the column by default.
+ */
+ String buildColumnAnnotationName(String attributeName, Column column);
+
+ /**
+ * Given the name of an attribute (field or property) and the
+ * many-to-one or many-to-many foreign key to which it is mapped,
+ * build and return a string to be used as the value for the attribute's
+ * JoinColumn annotation's 'name' element. Return null if the attribute
+ * maps to the join column by default.
+ * The specified foreign key consists of a single column pair whose
+ * referenced column is the single-column primary key of the foreign
+ * key's referenced table.
+ */
+ String buildJoinColumnAnnotationName(String attributeName, ForeignKey foreignKey);
+
+ /**
+ * Build and return a string to be used as the value for a JoinColumn
+ * annotation's 'name' or 'referencedColumnName' element.
+ * This is called for many-to-one and many-to-many mappings when
+ * the default join column name and/or referenced column name are/is
+ * not applicable.
+ * @see buildJoinColumnAnnotationName(String, ForeignKey)
+ */
+ String buildJoinColumnAnnotationName(Column column);
+
+ /**
+ * Build and return a string to be used as the value for a JoinTable
+ * annotation's 'name' element.
+ * This is called for many-to-many mappings when the default
+ * join table name is not applicable.
+ */
+ String buildJoinTableAnnotationName(Table table);
+
+
+ /**
+ * The default implementation simple returns the database object's name,
+ * unaltered.
+ */
+ final class Default implements DatabaseAnnotationNameBuilder {
+ public static final DatabaseAnnotationNameBuilder INSTANCE = new Default();
+ public static DatabaseAnnotationNameBuilder instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Default() {
+ super();
+ }
+ public String buildTableAnnotationName(String entityName, Table table) {
+ return table.getName();
+ }
+ public String buildColumnAnnotationName(String attributeName, Column column) {
+ return column.getName();
+ }
+ public String buildJoinColumnAnnotationName(String attributeName, ForeignKey foreignKey) {
+ return foreignKey.getColumnPair().getBaseColumn().getName();
+ }
+ public String buildJoinColumnAnnotationName(Column column) {
+ return column.getName();
+ }
+ public String buildJoinTableAnnotationName(Table table) {
+ return table.getName();
+ }
+ @Override
+ public String toString() {
+ return "DatabaseAnnotationNameBuilder.Default"; //$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ForeignKeyInfo.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ForeignKeyInfo.java
new file mode 100644
index 0000000000..e9048090e9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ForeignKeyInfo.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import java.util.List;
+
+import org.eclipse.jpt.db.ForeignKey;
+
+/**
+ * Represents the metadata for a particular foreign key relationship
+ * in a relational database schema.
+ * <p/>
+ * The referrer column is one which actually contains a foreign
+ * key constraint, and is equivalent to the "foreign key" column.
+ * <p/>
+ * The referenced column is one which a referrer or foreign key
+ * column references, and is equivalent to the "primary key" column.
+ *
+ */
+public class ForeignKeyInfo
+{
+ private transient ForeignKey mForeignKey ;
+ private String mName;
+ private String mReferrerTableName;
+ private String mReferencedTableName;
+ private List<String> mReferrerColNames = new java.util.ArrayList<String>();
+ private List<String> mReferencedColNames = new java.util.ArrayList<String>();
+
+ /**
+ * @param fk The name of the constraint backing
+ * this foreign key metadata instance.
+ */
+ public ForeignKeyInfo(ForeignKey fk, String referrerTableName, String referencedTableName) {
+ mForeignKey = fk;
+ mName = fk.getName();
+ mReferrerTableName = referrerTableName;
+ mReferencedTableName = referencedTableName;
+ }
+ /**
+ * Obtain the constraint name for this foreign key specification.
+ * The name for a Foreign Key may, as per the JDBC specification,
+ * be <code>null</code> where the constraint is not named.
+ * In addition, it may be hardly recognizable to the user,
+ * particularly for DB/2 constraints.
+ *
+ * @return The name of the constraint backing
+ * this foreign key metadata instance.
+ */
+ public String getName()
+ {
+ return mName;
+ }
+
+ public ForeignKey getForeignKey(){
+ return mForeignKey;
+ }
+ /**
+ * Add another pair of foreign key mappings for this foreign key
+ * definition.
+ *
+ * @param referrerColumn The referrer column name for this mapping.
+ *
+ * @param referencedColumn The referenced column name for this mapping.
+ */
+ public void addColumnMapping(String referrerColName, String referencedColName) {
+ mReferrerColNames.add(referrerColName);
+ mReferencedColNames.add(referencedColName);
+ }
+ /**
+ * Returns the referrer table name of this foreign key
+ * relationship.
+ */
+ public String getReferrerTableName() {
+ return mReferrerTableName;
+ }
+ /**
+ * Returns the referrer column names for this
+ * foreign key.
+ * The size of this list is always the same as the size of
+ * the list retured from <code>getReferencedColumnNames</code>
+ */
+ public List<String> getReferrerColumnNames() {
+ return mReferrerColNames;
+ }
+ /**
+ * Returns the referenced table name of this foreign key
+ * relationship.
+ */
+ public String getReferencedTableName() {
+ return mReferencedTableName;
+ }
+ /**
+ * Returns the referenced column names for this
+ * foreign key.
+ * The size of this list is always the same as the size of
+ * the list retured from <code>getReferrerColumnNames</code>
+ */
+ public List<String> getReferencedColumnNames() {
+ return mReferencedColNames;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "name=" + mName
+ + ", referrerTable=" + mReferrerTableName
+ + ", referencedTable=" + mReferencedTableName
+ + ", referrerColumns=" + mReferrerColNames
+ + ", referencedColumns=" + mReferencedColNames
+ ;
+ }
+}
+
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenMessages.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenMessages.java
new file mode 100644
index 0000000000..25fc02e674
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenMessages.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali entity generation.
+ */
+class JptGenMessages {
+
+ public static String PackageGenerator_taskName;
+ public static String GenScope_taskName;
+ public static String EntityGenerator_taskName;
+ public static String Templates_notFound;
+ public static String Error_Generating_Entities;
+
+ private static final String BUNDLE_NAME = "jpt_gen"; //$NON-NLS-1$
+ private static final Class<?> BUNDLE_CLASS = JptGenMessages.class;
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+ }
+
+ private JptGenMessages() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenPlugin.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenPlugin.java
new file mode 100644
index 0000000000..aec0b82b88
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/JptGenPlugin.java
@@ -0,0 +1,24 @@
+package org.eclipse.jpt.gen.internal2;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.Bundle;
+
+public class JptGenPlugin {
+ public static final String PLUGIN_ID = "org.eclipse.jpt.gen";
+ public static void logException ( String msg, Throwable e ) {
+ Bundle bundle = Platform.getBundle(PLUGIN_ID);
+ ILog log = Platform.getLog(bundle);
+ log.log(new Status(IStatus.ERROR, PLUGIN_ID, msg, e ));
+ }
+
+ public static void logException( CoreException ce ) {
+ IStatus status = ce.getStatus();
+ Bundle bundle = Platform.getBundle(PLUGIN_ID);
+ ILog log = Platform.getLog(bundle);
+ log.log(new Status(IStatus.ERROR, PLUGIN_ID, status.getMessage(), ce));
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenColumn.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenColumn.java
new file mode 100644
index 0000000000..24d42111c3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenColumn.java
@@ -0,0 +1,329 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.gen.internal2.util.StringUtil;
+
+
+/**
+ * Represents the ORM generation properties for a database
+ * column.
+ *
+ * <p>This is designed to be created/changed by the generation wizard,
+ * and generated using Velocity templates.
+ * The modified properties (if any) are persisted/retrieved using
+ * <code>ORMGenCustomizer</code>.
+ *
+ */
+public class ORMGenColumn
+{
+ private Table mTable;
+ private Column mDbColumn;
+ private ORMGenCustomizer mCustomizer;
+ private static String JAVA_LANG_PACKAGE = "java.lang.";
+
+ public ORMGenColumn(Column dbColumn, ORMGenCustomizer customizer) {
+ super();
+
+ mDbColumn = dbColumn;
+ mCustomizer = customizer;
+ mTable = dbColumn.getTable() ;
+ }
+ public ORMGenCustomizer getCustomizer() {
+ return mCustomizer;
+ }
+
+ protected String customized(String propName) {
+ return getCustomizer().getProperty(propName, mTable.getName(), getName());
+ }
+ protected boolean customizedBoolean(String propName) {
+ return getCustomizer().getBooleanProperty(propName, mTable.getName(), getName());
+ }
+ protected void setCustomized(String propName, String value) {
+ if (value != null && value.length() == 0) {
+ value = null;
+ }
+ getCustomizer().setProperty(propName, value, mTable.getName(), getName());
+ }
+ protected void setCustomizedBoolean(String propName, boolean value, boolean defaultValue) {
+ if (defaultValue == value) {
+ setCustomized(propName, null); //remove the property
+ } else {
+ getCustomizer().setBooleanProperty(propName, value, mTable.getName(), getName());
+ }
+ }
+
+ /**
+ * Returns the column name.
+ */
+ public String getName() {
+ String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().
+ buildColumnAnnotationName(mDbColumn.getName(), mDbColumn);
+ return annotationName!=null ? annotationName : mDbColumn.getName();
+ }
+
+ public String getJoinColumnName(){
+ String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().
+ buildJoinColumnAnnotationName(mDbColumn);
+ return annotationName!=null ? annotationName : mDbColumn.getName();
+ }
+
+ public Column getDbColumn(){
+ return this.mDbColumn;
+ }
+
+ /**
+ * Returns the generated bean property name for the given column.
+ * Does not return null.
+ */
+ public String getPropertyName() {
+ String name = customized(PROPERTY_NAME);
+ if (name == null) {
+ name = StringUtil.columnNameToVarName(getName());
+ }
+ return name;
+ }
+ public void setPropertyName(String name) {
+ if (!StringUtil.equalObjects(name, getPropertyName())) {
+ setCustomized(PROPERTY_NAME, name);
+ }
+ }
+
+ /**
+ * Return true if the values of name element in the @Column is default
+ * so we can skip generating the annotation
+ *
+ * @return true
+ */
+ public boolean isDefault(){
+ return isDefaultname() && isUpdateable() && isInsertable();
+ }
+
+ /**
+ * Return true if the values of name element in the @Column is default
+ * so we can skip generating the annotation
+ *
+ * @return true
+ */
+ public boolean isDefaultname(){
+ String propName = getPropertyName();
+ String dbColumnName = getName();
+ return propName.equalsIgnoreCase( dbColumnName );
+ }
+
+
+ /**
+ * Returns the column type.
+ * Does not return null.
+ */
+ public String getPropertyType() {
+ String type = customized(PROPERTY_TYPE);
+ if (type == null) {
+ type = getCustomizer().getPropertyTypeFromColumn( this.mDbColumn );
+ }
+ if( type.startsWith(JAVA_LANG_PACKAGE) ){
+ type = type.substring( JAVA_LANG_PACKAGE.length() );
+ }
+ return type;
+ }
+ public void setPropertyType(String type) {
+ if (!StringUtil.equalObjects(type, getPropertyType())) {
+ setCustomized(PROPERTY_TYPE, type);
+ }
+ }
+ /**
+ * Returns true if the column type is numeric.
+ */
+ public boolean isNumeric() {
+ boolean ret = this.mDbColumn.isNumeric() ;
+ return ret;
+
+ }
+ /**
+ * Returns the mapping kind, one of {@link #PROPERTY_MAPPING_KIND}|{@link #ID_MAPPING_KIND}
+ * |{@link #VERSION_MAPPING_KIND}|{@link #TIMESTAMP_MAPPING_KIND}.
+ *
+ * This method does not return null (defaults to basic property type).
+ */
+ public String getMappingKind() {
+ String kind = customized(MAPPING_KIND);
+ if (kind == null) {
+ kind = getCustomizer().getBasicMappingKind();
+
+ if ( this.mDbColumn.isPartOfPrimaryKey()
+ && DTPUtil.getPrimaryKeyColumnNames( this.mDbColumn.getTable() ).size() == 1) {
+ kind = getCustomizer().getIdMappingKind();
+ }
+ }
+ return kind;
+ }
+ public void setMappingKind(String mappingKind) {
+ if (!StringUtil.equalObjects(mappingKind, getMappingKind())) {
+ setCustomized(MAPPING_KIND, mappingKind);
+ }
+ }
+ public boolean isNullable() {
+ return this.mDbColumn.isNullable();
+ }
+
+ public int getSize() {
+ if( this.mDbColumn.isNumeric()){
+ return mDbColumn.getPrecision();
+ }
+ return mDbColumn.getLength();
+ }
+
+ public int getDecimalDigits() {
+ if( this.mDbColumn.isNumeric() ){
+ return mDbColumn.getScale();
+ }
+ return -1;
+ }
+
+ public boolean isPrimaryKey(){
+ return this.mDbColumn.isPartOfPrimaryKey() ;
+ }
+ public boolean isForeignKey() {
+ return this.mDbColumn.isPartOfForeignKey() ;
+ }
+ public boolean isUnique() {
+ return this.mDbColumn.isPartOfUniqueConstraint() ;
+ }
+ public String getPropertyDescription() {
+ return customized(PROPERTY_DESC);
+ }
+
+ public boolean isDataTypeLOB(){
+ return this.mDbColumn.isLOB();
+ }
+
+ public boolean isNeedMapTemporalType(){
+ String propertyType = this.getPropertyType();
+ return ( propertyType.equals("java.util.Date") || propertyType.equals("java.util.Calendar") );
+ }
+
+ public String getTemporalType(){
+ String defaultType = getCustomizer().getPropertyTypeFromColumn( this.mDbColumn );
+ if( defaultType.equals("java.sql.Date")){
+ return "DATE";
+ }else if( defaultType.equals("java.sql.Time")){
+ return "TIME";
+ }else {
+ return "TIMESTAMP";
+ }
+ }
+
+ /**
+ * Returns the generated property getter scope, one of {@link #PUBLIC_SCOPE}|{@link #PROTECTED_SCOPE}
+ * |{@link #PRIVATE_SCOPE}.
+ * This method never returns null (defaults to public).
+ */
+ public String getPropertyGetScope() {
+ String scope = customized(PROPERTY_GET_SCOPE);
+ if (scope == null) {
+ scope = PUBLIC_SCOPE;
+ }
+ return scope;
+ }
+ public void setPropertyGetScope(String scope) {
+ if (!StringUtil.equalObjects(scope, getPropertyGetScope())) {
+ setCustomized(PROPERTY_GET_SCOPE, scope);
+ }
+ }
+ /**
+ * Returns the generated property setter scope, one of {@link #PUBLIC_SCOPE}|{@link #PROTECTED_SCOPE}
+ * |{@link #PRIVATE_SCOPE}.
+ * This method never returns null (defaults to public).
+ */
+ public String getPropertySetScope() {
+ String scope = customized(PROPERTY_SET_SCOPE);
+ if (scope == null) {
+ scope = PUBLIC_SCOPE;
+ }
+ return scope;
+ }
+ public void setPropertySetScope(String scope) {
+ if (!StringUtil.equalObjects(scope, getPropertySetScope())) {
+ setCustomized(PROPERTY_SET_SCOPE, scope);
+ }
+ }
+ /**
+ * Returns the generated field member scope, one of {@link #PUBLIC_SCOPE}|{@link #PROTECTED_SCOPE}
+ * |{@link #PRIVATE_SCOPE}.
+ * This method never returns null (defaults to private).
+ */
+ public String getFieldScope() {
+ String scope = customized(FIELD_SCOPE);
+ if (scope == null) {
+ scope = PRIVATE_SCOPE;
+ }
+ return scope;
+ }
+ /**
+ * Returns true if this column should be used in the
+ * <code>equals</code> method implementation.
+ */
+ public boolean isUseInEquals() {
+ return customizedBoolean(USE_IN_EQUALS) || isPrimaryKey();
+ }
+ public void setUseInEquals(boolean value) {
+ setCustomizedBoolean(USE_IN_EQUALS, value, false);
+ }
+ /**
+ * Returns true if this column should be used in the
+ * <code>toString</code> method implementation.
+ */
+ public boolean isUseInToString() {
+ return customizedBoolean(USE_IN_TO_STRING) || isPrimaryKey();
+ }
+ public void setUseInToString(boolean value) {
+ setCustomizedBoolean(USE_IN_TO_STRING, value, false);
+ }
+ public boolean isUpdateable() {
+ return !"false".equals(customized(UPDATEABLE)); //defaults to true
+ }
+ public void setUpdateable(boolean value) {
+ setCustomizedBoolean(UPDATEABLE, value, true);
+ }
+ public boolean isInsertable() {
+ return !"false".equals(customized(INSERTABLE)); //defaults to true
+ }
+ public void setInsertable(boolean value) {
+ setCustomizedBoolean(INSERTABLE, value, true);
+ }
+ public boolean isGenerated() {
+ return !"false".equals(customized(GENERATED)); //defaults to true
+ }
+ public void setGenerated(boolean value) {
+ setCustomizedBoolean(GENERATED, value, true);
+ }
+
+ /*get/set and field scopes*/
+ public static final String PUBLIC_SCOPE = "public";
+ public static final String PROTECTED_SCOPE = "protected";
+ public static final String PRIVATE_SCOPE = "private";
+
+ /*customization properties*/
+ private static final String PROPERTY_NAME = "propertyName";
+ protected static final String PROPERTY_TYPE = "propertyType";
+ protected static final String MAPPING_KIND = "mappingKind";
+ private static final String PROPERTY_DESC = "propertyDesc";
+ private static final String PROPERTY_GET_SCOPE = "propertyGetScope";
+ private static final String PROPERTY_SET_SCOPE = "propertySetScope";
+ private static final String FIELD_SCOPE = "fieldScope";
+ private static final String USE_IN_EQUALS = "useInEquals";
+ private static final String USE_IN_TO_STRING = "useInToString";
+ private static final String UPDATEABLE = "updateable";
+ private static final String INSERTABLE = "insertable";
+ private static final String GENERATED = "genProperty";
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenCustomizer.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenCustomizer.java
new file mode 100644
index 0000000000..32496eb8ac
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenCustomizer.java
@@ -0,0 +1,752 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.gen.internal2.util.FileUtil;
+import org.eclipse.jpt.gen.internal2.util.StringUtil;
+
+/**
+ * Contains the information used to customize the database schema to ORM entity
+ * generation.
+ *
+ * <p>The customization settings are mainly exposed in the form of
+ * properties. There are no assumptions in this class about the meaning of the
+ * property names. Properties can be associated to specific tables and table
+ * columns, or globally for any table and/or column.
+ *
+ * <p>Subclass can implement the sets of abstract methods to provide ORM vendor
+ * specific properties.
+ *
+ */
+public abstract class ORMGenCustomizer implements java.io.Serializable
+{
+ private final static long serialVersionUID = 1;
+
+ /**
+ * A value passed for the table name argument to get/setProperty
+ * indicating that the value applies to any table.
+ */
+ public static final String ANY_TABLE = "__anyTable__";
+ /*the string used in the property name in mProps to indicate
+ * a null table value.*/
+ private static final String NULL_TABLE = "";
+ /*the string used in the property name in mProps to indicate
+ * a null column value.*/
+ private static final String NULL_COLUMN = "";
+
+ /*This version number is written in the header of the customization stream
+ * and read at de-serialization time, if it is different then the file is invalidated.
+ */
+ private static final int FILE_VERSION = 2;
+
+ private static final String UPDATE_CONFIG_FILE = "updateConfigFile";
+
+ private transient Schema mSchema;
+ private transient File mFile;
+
+ private List<String> mTableNames;
+ /*key: table name, value: ORMGenTable object.*/
+ private transient Map<String , ORMGenTable> mTables;
+ /*the <code>Association</code> objects sorted by their "from"
+ * table name. Includes all association derived from foreign keys
+ * in user selected tables. Since some of the foreign keys may point to table
+ * user does not select, this list may be different from mValidAssociations
+ **/
+ private List<Association> mAssociations;
+ /*
+ * List of valid associations within the user selected tables
+ * */
+ private transient List<Association> mValidAssociations;
+ private transient boolean mInvalidForeignAssociations;
+
+ /*the property name is in the form $tableName.$columnName.$propertyName.
+ * Where tableName could be NULL_TABLE or ANY_TABLE
+ * and columnName could be NULL_COLUMN*/
+ private Map<String, String> mProps = new java.util.HashMap<String, String>();
+
+ private transient DatabaseAnnotationNameBuilder databaseAnnotationNameBuilder = DatabaseAnnotationNameBuilder.Default.INSTANCE;
+
+ //-----------------------------------------
+ //---- abstract methods
+ //-----------------------------------------
+ /**
+ * Returns all the primary key generator schemes.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract List<String> getAllIdGenerators();
+ /**
+ * Returns the string representing the developer-assigned id generator.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String getNoIdGenerator();
+ /**
+ * Returns the string representing the identity id generator.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String getIdentityIdGenerator();
+ /**
+ * Returns the strings representing the sequence generators.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract Set<String> getSequenceIdGenerators();
+ /**
+ * Returns a property type from the given database column.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String getPropertyTypeFromColumn(Column column) ;
+ /**
+ * Returns all the strings representing property types.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String[] getAllPropertyTypes();
+ /**
+ * Returns all the strings representing property mapping kinds.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String[] getAllMappingKinds();
+ /**
+ * Returns the basic (default) property mapping kind.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String getBasicMappingKind();
+ /**
+ * Returns the id (primary key) property mapping kind.
+ * This can return any strings as far as the Velocity template
+ * processor understand them.
+ */
+ public abstract String getIdMappingKind();
+ /**
+ * Interacts with the user to edit the cascade of the given
+ * role.
+ * This method should also call <code>AssociationRole.setCascade</code>.
+ *
+ * @return false if the user interaction is cancelled.
+ */
+ public abstract boolean editCascade(AssociationRole role);
+
+ //-----------------------------------------
+ //-----------------------------------------
+
+ /**
+ * @param file The file that contains the customization settings.
+ * The file is created if necessary when the <code>save</code>
+ * method is called.
+ */
+ public void init( File file, Schema schema) {
+ this.mSchema = schema;
+ mFile = file;
+
+ if (!file.exists()) {
+ /*A hack to set the default to eager so thet app does not throw at runtime for new apps
+ * (in case a lazy strategy is not developed yet). This is done instead of in ORMGenTable.getDefaultFetch
+ * for backward compatibility.*/
+ setProperty(ORMGenTable.DEFAULT_FETCH, ORMGenTable.EAGER_FETCH, ORMGenCustomizer.ANY_TABLE, null);
+ return;
+ }
+ InputStream istream = null;
+ ObjectInputStream ois = null;
+ try
+ {
+ //read it in a file first to speedup deserialization
+ byte[] bytes = FileUtil.readFile(file);
+ istream = new ByteArrayInputStream(bytes);
+ ois = new ObjectInputStream(istream);
+
+ FileHeader header = (FileHeader)ois.readObject();
+ if (header.mVersion == FILE_VERSION) {
+ ORMGenCustomizer customizer = (ORMGenCustomizer)ois.readObject();
+ restore(customizer);
+ }
+ } catch (Exception ex) {
+ System.out.println("***ORMGenCustomizer.load failed "+file+": " + ex);
+ }
+ finally
+ {
+ if (ois != null)
+ {
+ try
+ {
+ ois.close();
+ } catch (IOException e) {
+ }
+ }
+
+ if (istream != null)
+ {
+ try
+ {
+ istream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ public void setSchema(Schema schema){
+ this.mSchema = schema;
+ }
+
+ public Schema getSchema(){
+ return mSchema;
+ }
+
+ /**
+ * Empty constructor needed by the deserialization.
+ */
+ public ORMGenCustomizer() {
+ super();
+ }
+
+ /**
+ * Saves the customization file.
+ * The file is created if necessary.
+ */
+ public void save() throws IOException {
+ //System.out.println("---ORMGenCustomizer.save: " + mFile);
+ if (!mFile.exists() && !mFile.createNewFile()) {
+ return;
+ }
+ java.io.FileOutputStream fos = null;
+ java.io.ObjectOutputStream oos = null;
+ boolean deleteIt = true;
+ try {
+ fos = new java.io.FileOutputStream(mFile);
+ oos = new java.io.ObjectOutputStream(fos);
+ FileHeader header = new FileHeader();
+ oos.writeObject(header);
+ oos.writeObject(this);
+ deleteIt = false;
+ } catch (Exception ex) {
+ //deleteIt is true, so the cache is not saved.
+ CoreException ce = new CoreException(new Status(IStatus.ERROR, JptGenPlugin.PLUGIN_ID,
+ "Unable to save the ORMGenCustomizer file: "+mFile,ex));
+ JptGenPlugin.logException( ce );
+ } finally {
+ try {
+ if (oos!=null) oos.close();
+ if (fos!=null) fos.close();
+ if (deleteIt) {
+ mFile.delete();
+ }
+ } catch (java.io.IOException ex2) {}
+ }
+ }
+
+ public DatabaseAnnotationNameBuilder getDatabaseAnnotationNameBuilder() {
+ return this.databaseAnnotationNameBuilder;
+ }
+ public void setDatabaseAnnotationNameBuilder(DatabaseAnnotationNameBuilder databaseAnnotationNameBuilder) {
+ if (databaseAnnotationNameBuilder == null) {
+ throw new NullPointerException("database annotation name builder is required"); //$NON-NLS-1$
+ }
+ this.databaseAnnotationNameBuilder = databaseAnnotationNameBuilder;
+ }
+
+ /**
+ * Returns a property value.
+ */
+ public String getProperty(String propertyName, String tableName, String colName) {
+ String key = getPropKey(propertyName, tableName, colName);
+ String value = (String)mProps.get(key);
+ /*if the key does not exist and it is a table property then
+ * get the default table property.*/
+ if (value == null && tableName != null && colName == null && !tableName.equals(ANY_TABLE)) {
+ value = getProperty(propertyName, ANY_TABLE, colName);
+ }
+ return value;
+ }
+ /**
+ * Changes a property value.
+ *
+ * @param value The new value, could be null.
+ */
+ public void setProperty(String propertyName, String value, String tableName, String colName) {
+ String key = getPropKey(propertyName, tableName, colName);
+ if (value != null) {
+ mProps.put(key, value);
+ } else {
+ mProps.remove(key);
+ }
+ }
+ /**
+ * Same as {@link #getProperty(String, String, String)} but
+ * converts the value to boolean.
+ */
+ public boolean getBooleanProperty(String propertyName, String tableName, String colName) {
+ String value = getProperty(propertyName, tableName, colName);
+ return "true".equals(value);
+ }
+ /**
+ * Changes a table boolean property value.
+ */
+ public void setBooleanProperty(String propertyName, boolean value, String tableName, String colName) {
+ setProperty(propertyName, value ? "true" : "false", tableName, colName);
+ }
+ /**
+ * Returns the names of the tables to generate.
+ */
+ @SuppressWarnings("unchecked")
+ public List<String> getTableNames() {
+ return mTableNames != null ? mTableNames : java.util.Collections.EMPTY_LIST;
+ }
+ /**
+ * Called when the table user selection is changed in the
+ * generation wizard.
+ */
+ public void setTableNames(List<String> tableNames) {
+ mTableNames = tableNames;
+ mTables = null;
+ mValidAssociations = null; //recompute
+ mInvalidForeignAssociations = true; //make sure foreign associations from newly added tables are computed.
+ }
+ /**
+ * Returns the table names to be generated.
+ * This might be different from <code>getTableNames</code> if there
+ * are many-to-many join tables and are not contributing
+ * in any other associations.
+ */
+ public List<String> getGenTableNames() {
+ List<String> names = getTableNames();
+ List<String> result = new java.util.ArrayList<String>(names.size());
+
+ /*filter out join tables*/
+ List<Association> associations = getAssociations();
+ for (Iterator<String> tableNamesIter = names.iterator(); tableNamesIter.hasNext(); ) {
+ String tableName = (String)tableNamesIter.next();
+ boolean isValid = true;
+
+ for (Iterator<Association> assocIter = associations.iterator(); assocIter.hasNext(); ) {
+ Association association = (Association)assocIter.next();
+ if (!association.isGenerated()) {
+ continue;
+ }
+ if (tableName.equals(association.getReferrerTableName())
+ || tableName.equals(association.getReferencedTableName())) {
+ isValid = true;
+ break;
+ }
+ if (tableName.equals(association.getJoinTableName())) {
+ isValid = false;
+ }
+ }
+ if (isValid) {
+ result.add(tableName);
+ }
+ }
+ return result;
+ }
+ /**
+ * Returns an <code>ORMGenTable</code> object given its name, or
+ * null if none.
+ */
+ public ORMGenTable getTable(String tableName) {
+ if (mTables == null) {
+ mTables = new java.util.HashMap<String, ORMGenTable>(mTableNames.size());
+ }
+
+ if(mTableNames!=null && mSchema!=null){
+ for (Iterator<String> iter = mTableNames.iterator(); iter.hasNext(); ) {
+ String name = (String)iter.next();
+ Table dbTable = mSchema.getTableNamed( name );
+ if (dbTable != null) {
+ mTables.put(name, createGenTable(dbTable));
+ }
+ }
+ }
+ return (ORMGenTable)mTables.get(tableName);
+ }
+ /**
+ * Returns the <code>Association</code> objects sorted by their "from"
+ * table name.
+ */
+ public List<Association> getAssociations(){
+ return getAssociations(true/*validOnly*/);
+ }
+ /**
+ * Adds the given association.
+ */
+ public void addAssociation(Association association) {
+ getAssociations(false/*validOnly*/).add(association);
+ if (mValidAssociations != null) {
+ mValidAssociations.add(association);
+ }
+
+ }
+ /**
+ * Deletes the given association.
+ */
+ public void deleteAssociation(Association association) {
+ boolean removed = getAssociations(false/*validOnly*/).remove(association);
+ assert(removed);
+
+ if (mValidAssociations != null) {
+ removed = mValidAssociations.remove(association);
+ assert(removed);
+ }
+ }
+ /**
+ * Returns true if an association similar to the given association
+ * already exists.
+ * This is decided based only on the association tables and columns.
+ */
+ public boolean similarAssociationExists(Association association) {
+ try {
+ for (Iterator<Association> iter = getAssociations(false/*validOnly*/).iterator(); iter.hasNext(); ) {
+ Association association2 = (Association)iter.next();
+ if (!association.getReferrerTableName().equals(association2.getReferrerTableName())
+ || !association.getReferencedTableName().equals(association2.getReferencedTableName())
+ || !StringUtil.equalObjects(association.getJoinTableName(), association2.getJoinTableName())
+ || !association.getReferrerColumnNames().equals(association2.getReferrerColumnNames())
+ || !association.getReferencedColumnNames().equals(association2.getReferencedColumnNames())
+ ) {
+ continue;
+ }
+ /*the 2 association have the same referrer, referenced and join table*/
+ if (association.getJoinTableName() == null) {
+ return true;
+ }
+ if (association.getReferrerJoinColumnNames().equals(association2.getReferrerJoinColumnNames())
+ && association.getReferencedJoinColumnNames().equals(association2.getReferencedJoinColumnNames())) {
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return false;
+ }
+ /**
+ * Creates the <code>ORMGenTable</code> instance.
+ */
+ public ORMGenTable createGenTable(Table dbTable) {
+ return new ORMGenTable(dbTable, this);
+ }
+ /**
+ * Creates the <code>ORMGenColumn</code> instance.
+ */
+ protected ORMGenColumn createGenColumn(Column dbCol) {
+ return new ORMGenColumn(dbCol, this);
+ }
+ /**
+ * Returns true of the underlying persistence specs require the "many" side
+ * of an association to be the owner (like EJB3).
+ */
+ protected boolean manySideIsAssociationOwner() {
+ return false;
+ }
+ public boolean isUpdateConfigFile() {
+ return !"false".equals(getProperty(UPDATE_CONFIG_FILE, null, null)); //defaults to true
+ }
+ public void setUpdateConfigFile(boolean value) {
+ if (value) { //default is true
+ setProperty(UPDATE_CONFIG_FILE, null, null, null); //remove it
+ } else {
+ setBooleanProperty(UPDATE_CONFIG_FILE, value, null, null);
+ }
+ }
+
+ //-----------------------------------------
+ //---- Velocity templates methods
+ //-----------------------------------------
+ /**
+ * Returns a getter method name given a property name.
+ */
+ public String propertyGetter(String propertyName) {
+ return "get"+StringUtil.initUpper(propertyName);
+ }
+ /**
+ * Returns a setter method name given a property name.
+ */
+ public String propertySetter(String propertyName) {
+ return "set"+StringUtil.initUpper(propertyName);
+ }
+ public String quote(String s) {
+ return StringUtil.quote(s, '"');
+ }
+ public String quote(boolean b) {
+ return quote(String.valueOf(b));
+ }
+ public String quote(int i) {
+ return quote(String.valueOf(i));
+ }
+ /**
+ * Appends an annotation member name and value to an existing annotation.
+ *
+ * @param s The annotation members string.
+ *
+ * @param memberValue The member value, if null or empty strings then
+ * nothing is appened.
+ *
+ * @param whether to double quote the member value.
+ */
+ public String appendAnnotation(String s, String memberName, String memberValue, boolean quote) {
+ if (memberValue == null || memberValue.length() == 0) {
+ return s;
+ }
+ StringBuffer buffer = new StringBuffer(s);
+ if (buffer.length() != 0) {
+ buffer.append(", ");
+ }
+ buffer.append(memberName);
+ buffer.append('=');
+ if (quote) {
+ buffer.append('"');
+ }
+ buffer.append(memberValue);
+ if (quote) {
+ buffer.append('"');
+ }
+ return buffer.toString();
+ }
+ public boolean isJDK1_5() {
+ return true;
+ }
+
+ //-----------------------------------------
+ //---- private methods
+ //-----------------------------------------
+ /**
+ * Restores the customization settings from the given
+ * (persisted) customizer.
+ */
+ private void restore(ORMGenCustomizer customizer) {
+ mTableNames = customizer.mTableNames;
+ mAssociations = customizer.mAssociations;
+ mProps = customizer.mProps;
+ if( mSchema == null )
+ return;
+
+ /*remove invalid table names*/
+ for (int i = mTableNames.size()-1; i >= 0; --i) {
+ String tableName = (String)mTableNames.get(i);
+ if (mSchema.getTableNamed( tableName) == null) {
+ mTableNames.remove(i);
+ }
+ }
+ if( mAssociations!=null ){
+ /*restore the associations*/
+ for (Iterator<Association> iter = mAssociations.iterator(); iter.hasNext(); ) {
+ Association association = (Association)iter.next();
+ association.restore(this);
+ }
+ /*add the foreign keys associations just in case the tables changed since
+ * the last time the state was persisted. Pass checkExisting true so that the
+ * associations restored above are not overwritten.*/
+ addForeignKeyAssociations(true/*checkExisting*/);
+ }
+ }
+ /**
+ * Returns the key in mProps corresponding to the specified
+ * propertyName, table and column.
+ */
+ private String getPropKey(String propertyName, String tableName, String colName) {
+ if (tableName == null) {
+ tableName = NULL_TABLE;
+ }
+ if (colName == null) {
+ colName = NULL_COLUMN;
+ }
+ return tableName + '.' + colName + '.' + propertyName;
+ }
+ /**
+ * Returns the associations that are valid for the
+ * current tables.
+ */
+ private List<Association> getAssociations(boolean validOnly){
+ if (mAssociations == null) {
+ mAssociations = new java.util.ArrayList<Association>();
+
+ addForeignKeyAssociations(false/*checkExisting*/);
+ } else if (mInvalidForeignAssociations) {
+ mInvalidForeignAssociations = false;
+
+ addForeignKeyAssociations(true/*checkExisting*/);
+ }
+ List<Association> associations;
+ if (validOnly) {
+ if (mValidAssociations == null) {
+ /*filter out the invalid associations*/
+ mValidAssociations = new ArrayList<Association>(mAssociations.size());
+ for (int i = 0, n = mAssociations.size(); i < n; ++i) {
+ Association association = (Association)mAssociations.get(i);
+ if (association.isValid()) {
+ mValidAssociations.add(association);
+ }
+ }
+ }
+ associations = mValidAssociations;
+ } else {
+ associations = mAssociations;
+ }
+ return associations;
+ }
+ private void addForeignKeyAssociations(boolean checkExisting) {
+ List<String> tableNames = getTableNames();
+ for (Iterator<String> iter = tableNames.iterator(); iter.hasNext(); ) {
+ ORMGenTable table = getTable((String)iter.next());
+ addForeignKeyAssociations(table, checkExisting);
+ }
+ }
+ private void addForeignKeyAssociations(ORMGenTable table, boolean checkExisting) {
+ if(table==null)
+ return;
+
+
+ List<ForeignKeyInfo> fKeys = null;
+
+ try{
+ fKeys = DTPUtil.getForeignKeys(table.getDbTable());
+ }catch(Exception ise){
+ //workaround Dali bug for now
+ return;
+ }
+
+ if( fKeys.size()==0 )
+ return;
+
+ List<Association> addedAssociations = new java.util.ArrayList<Association>();
+ for (Iterator<ForeignKeyInfo> iter = fKeys.iterator(); iter.hasNext(); ) {
+ ForeignKeyInfo fki = (ForeignKeyInfo)iter.next();
+ ORMGenTable referencedTable = getTable(fki.getReferencedTableName());
+ if (referencedTable == null) {
+ continue;
+ }
+ Association association = new Association(this, table.getName(), fki.getReferrerColumnNames()
+ , referencedTable.getName(), fki.getReferencedColumnNames());
+ association.computeCardinality();
+ //Defer the check of similarAssociationExists after computeManyToMany()
+ //otherwise the MTM association will not computed correctly in some cases.
+ //if (checkExisting && similarAssociationExists(association)) {
+ // continue;
+ //}
+ addedAssociations.add(association);
+ }
+
+ Association m2m = computeManyToMany(table, addedAssociations);
+ if (m2m != null) {
+ /*do not generate the 2 many-to-one*/
+ for (int i = 0; i < addedAssociations.size(); ++i) {
+ Association association = (Association)addedAssociations.get(i);
+ association.setGenerated(false);
+ }
+ addedAssociations.add(0, m2m);
+ }
+ //remove the association if already existing
+ Iterator<Association> it = addedAssociations.iterator();
+ while( it.hasNext() ){
+ Association newAssociation = it.next();
+ for( Association association : mAssociations ){
+ if( newAssociation.equals( association )){
+ //If the association is existing, don't add.
+ //only copy the generated flag
+ association.setGenerated( newAssociation.isGenerated() );
+ it.remove();
+ }
+ }
+ }
+ mAssociations.addAll(addedAssociations);
+ }
+ private Association computeManyToMany(ORMGenTable table, List<Association> addedAssociations) {
+ /*many-to-many associations if:
+ * -addedAssociations contains 2 many-to-one associations to 2 different tables t1 and t2.
+ * -<code>table</code> contains only the primary key columns.
+ * -the primary key of <code>table</code> is the concatenation of its foreign
+ * keys to t1 and t2.*/
+
+ if (addedAssociations.size() != 2) {
+ return null;
+ }
+
+ //Assume MTM table should have only two columns that are foreign keys
+ if( table.getColumns().size() != 2 ){
+ return null;
+ }
+
+ Association assoc1 = (Association)addedAssociations.get(0);
+ Association assoc2 = (Association)addedAssociations.get(1);
+ if (assoc1.getCardinality() != Association.MANY_TO_ONE
+ || assoc2.getCardinality() != Association.MANY_TO_ONE) {
+ return null;
+ }
+ ORMGenTable t1 = assoc1.getReferencedTable();
+ ORMGenTable t2 = assoc2.getReferencedTable();
+
+//Commented out because the assumption is too restrictive:
+//this check will prevent generating table MTM to itself
+// if (t1.getName().equals(t2.getName()) ||
+// t1.getName().equals(table.getName()) || t2.getName().equals(table.getName())) {
+ if( t1.getName().equals(table.getName()) || t2.getName().equals(table.getName()) ) {
+ return null;
+ }
+
+//Commented out because the assumption is too restrictive:
+//this check will prevent generating MTM mapping table not having
+//primary key defined
+// List pkNames = DTPUtil.getPrimaryKeyColumnNames(table.getDbTable());
+// if (pkNames.size() != table.getColumnNames().size()) {
+// return null;
+// }
+// List fkNames = new java.util.ArrayList(assoc1.getReferrerColumnNames()); //clone because we modify by addAll below
+// fkNames.addAll(assoc2.getReferrerColumnNames());
+// if (!CollectionUtil.equalsIgnoreOrder(pkNames, fkNames)) {
+// return null;
+// }
+ Association m2m = new Association(this, t1.getName()/*referrerTableName*/, assoc1.getReferencedColumnNames()/*referrerColNames*/
+ , t2.getName()/*referencedTableName*/, assoc2.getReferencedColumnNames()/*referencedColNames*/
+ , table.getName(), assoc1.getReferrerColumnNames()/*referrerJoinColNames*/, assoc2.getReferrerColumnNames()/*referencedJoinColNames*/);
+ m2m.setCustom(false);
+ return m2m;
+ }
+
+ //---------------------------------------------------
+ //---- FileHeader class -----------------------------
+ //---------------------------------------------------
+ /**
+ * The header of the customization file.
+ */
+ private static class FileHeader implements java.io.Serializable
+ {
+ private static final long serialVersionUID = 1L;
+ /**
+ * Should be argument-less because it is used in
+ * the de-serialization process.
+ */
+ public FileHeader() {
+ mVersion = FILE_VERSION;
+ }
+ int mVersion;
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenTable.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenTable.java
new file mode 100644
index 0000000000..11ab29a29a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/ORMGenTable.java
@@ -0,0 +1,828 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.gen.internal2.util.StringUtil;
+import org.eclipse.jpt.utility.JavaType;
+
+/**
+ * Represents the ORM generation properties for a database
+ * table.
+ *
+ * <p>This is designed to be created/changed by the generation wizard,
+ * and generated using Velocity templates.
+ * The modified properties (if any) are persisted/retrieved using
+ * <code>ORMGenCustomizer</code>.
+ *
+ */
+public class ORMGenTable
+{
+ private ORMGenCustomizer mCustomizer;
+ private List<ORMGenColumn> mColumns;
+ private Table mDbTable;
+
+ /**
+ * @param table The database table or null if this table is used
+ * to get/set the default table properties (properties that apply to all tables unless overriden).
+ */
+ public ORMGenTable(Table table, ORMGenCustomizer customizer) {
+ super();
+
+ mDbTable = table;
+ mCustomizer = customizer;
+ }
+ public ORMGenCustomizer getCustomizer() {
+ return mCustomizer;
+ }
+ /**
+ * Returns true if this table is is used to get/set the default
+ * table properties.
+ */
+ public boolean isDefaultsTable() {
+ return mDbTable == null;
+ }
+
+ protected String customized(String propName) {
+ return getCustomizer().getProperty(propName, getName(), null);
+ }
+ protected boolean customizedBoolean(String propName) {
+ return getCustomizer().getBooleanProperty(propName, getName(), null);
+ }
+ protected void setCustomized(String propName, String value) {
+ if (value != null && value.length() == 0) {
+ value = null;
+ }
+ getCustomizer().setProperty(propName, value, getName(), null);
+ }
+ protected void setCustomizedBoolean(String propName, boolean value, boolean defaultValue) {
+ if (defaultValue == value) {
+ setCustomized(propName, null); //remove the property
+ } else {
+ getCustomizer().setBooleanProperty(propName, value, getName(), null);
+ }
+ }
+ public Table getDbTable() {
+ return mDbTable;
+ }
+ /**
+ * Returns the table name.
+ */
+ public String getName() {
+ if( mDbTable == null )
+ return ORMGenCustomizer.ANY_TABLE;
+ String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().
+ buildTableAnnotationName(mDbTable.getName(), mDbTable);
+ return annotationName != null ? annotationName : mDbTable.getName();
+ }
+
+ public String getJoinTableAnnotationName(){
+ if( mDbTable == null )
+ return ORMGenCustomizer.ANY_TABLE;
+ String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().
+ buildJoinTableAnnotationName( mDbTable);
+ return annotationName != null ? annotationName : mDbTable.getName();
+ }
+
+ /**
+ * Returns the database schema containing the table.
+ */
+ public String getSchema() {
+ if( DTPUtil.isDefaultSchema( mDbTable ))
+ return "";
+ String schemaName = mDbTable.getSchema().getName();
+
+ return schemaName;
+ }
+ /**
+ * Sets the package for the generated class (empty string for the default package)
+ */
+ public void setPackage(String srcFolder, String pkg) {
+ setCustomized(SRC_FOLDER, srcFolder);
+
+ getCustomizer().setProperty(PACKAGE, pkg, getName(), null); //not calling setCustomized so that empty strings do not get nulled out.
+ }
+ /**
+ * Returns the Java package (empty string for the default package).
+ */
+ public String getPackage() {
+ return customized(PACKAGE);
+ }
+
+ /**
+ * Returns the generated Java class name (not qualified).
+ */
+ public String getClassName() {
+ String name = customized(CLASS_NAME);
+ if (name == null) {
+ name = StringUtil.tableNameToVarName(getName());
+ name = StringUtil.initUpper(name);
+ name = StringUtil.singularise(name);
+ }
+ return name;
+ }
+ public void setClassName(String className) {
+ /*if the class name is the same as the (possibly computed) class name
+ * then nothing to do*/
+ if (!StringUtil.equalObjects(className, getClassName())) {
+ setCustomized(CLASS_NAME, className);
+ }
+ }
+ /**
+ * Returns a name suitable to be used as a variable or class name.
+ * This is computed based on the table name.
+ *
+ * @param singular Whether the name should be singular or plural.
+ */
+ public String getVarName(boolean singular) {
+ String name = StringUtil.tableNameToVarName(getName());
+ if (singular) {
+ name = StringUtil.singularise(name);
+ } else {
+ name = StringUtil.pluralise(name);
+ }
+ return name;
+ }
+ /**
+ * Returns the fully qualified generated Java class name.
+ */
+ public String getQualifiedClassName() {
+ return qualify(getClassName());
+ }
+ /**
+ * Returns the composite key Java class name (not qualified).
+ */
+ public String getCompositeKeyClassName() {
+ String name = customized(COMPOSITE_KEY_CLASS_NAME);
+ if (name == null) {
+ name = getClassName() + "PK";
+ }
+ return name;
+ }
+ /**
+ * Returns the fully qualified composite key Java class name.
+ */
+ public String getQualifiedCompositeKeyClassName() {
+ return qualify(getCompositeKeyClassName());
+ }
+ /**
+ * Returns the composite key property name.
+ */
+ public String getCompositeKeyPropertyName() {
+ return "compId";
+ }
+ /**
+ * Returns the <code>ORMGenColumn</code> objects to be
+ * generated for this table.
+ */
+ public List<ORMGenColumn> getColumns() {
+ if (mColumns == null) {
+ mColumns = new ArrayList<ORMGenColumn>();
+ Iterator<Column> cols = mDbTable.columns();
+ while (cols.hasNext() ) {
+ Column c = cols.next();
+ ORMGenColumn genColumn = getCustomizer().createGenColumn( c );
+ mColumns.add( genColumn );
+ }
+ }
+ return mColumns;
+ }
+ public List<String> getColumnNames() {
+ Iterator<Column> cols = mDbTable.columns();
+ List<String> ret = new ArrayList<String>();
+ while (cols.hasNext() ) {
+ Column c = cols.next();
+ ret.add(c.getName());
+ }
+ return ret;
+ }
+ /**
+ * Returns the <code>ORMGenColumn</code> objects representing
+ * the table's primary key.
+ */
+ public List<ORMGenColumn> getPrimaryKeyColumns() {
+ List<Column> dbCols = DTPUtil.getPrimaryKeyColumns( mDbTable);
+ List<ORMGenColumn> ret = new ArrayList<ORMGenColumn>();
+ for(Column dbCol : dbCols ){
+ ret.add(new ORMGenColumn(dbCol, this.mCustomizer));
+ }
+ return ret;
+ }
+ /**
+ * Returns the primary key column or null if there is
+ * no or many primary key columns.
+ */
+ public ORMGenColumn getPrimaryKeyColumn() {
+ ORMGenColumn pkCol = null;
+ List<ORMGenColumn> pkColumns = getPrimaryKeyColumns();
+ if (pkColumns.size() == 1) {
+ //Column dbCol = (Column)pkColumns.get(0);
+ pkCol = pkColumns.get(0); //(ORMGenColumn) mCustomizer.createGenColumn(dbCol);
+ } else {
+ /*if no pk column then look for the first column with id
+ * mapping kind. This is so that the wizard can be used with tables
+ * not having primary keys. */
+ List<ORMGenColumn> columns = getColumns();
+ for (int i = 0, n = columns.size(); i < n; ++i) {
+ ORMGenColumn column = (ORMGenColumn)columns.get(i);
+ if (column.getMappingKind().equals(mCustomizer.getIdMappingKind())) {
+ pkCol = column;
+ break;
+ }
+ }
+ }
+ return pkCol;
+ }
+ /**
+ * Returns true if there is more than 1 pk column.
+ */
+ public boolean isCompositeKey() {
+ return DTPUtil.getPrimaryKeyColumnNames( mDbTable ).size() > 1;
+ }
+ /**
+ * Returns the <code>ORMGenColumn</code> objects for the
+ * the columns that are not part of any association.
+ *
+ * @param genOnly Whether to include only the columns marked for generation.
+ *
+ * @param includePk Whether to include the primary kley column(s).
+ *
+ * @param includeInherited Whether to include the columns associated
+ * with Java properties that exist in the super class (if any).
+ */
+ public List<ORMGenColumn> getSimpleColumns(boolean genOnly, boolean includePk, boolean includeInherited){
+ List<ORMGenColumn> result = new java.util.ArrayList<ORMGenColumn>();
+
+ List<ORMGenColumn> columns = getColumns();
+ List<AssociationRole> roles = getAssociationRoles();
+ for (int i = 0, n = columns.size(); i < n; ++i) {
+ ORMGenColumn column = (ORMGenColumn)columns.get(i);
+ if (genOnly && !column.isGenerated()) {
+ continue;
+ }
+ if (column.isPrimaryKey()) {
+ if (!includePk || isCompositeKey()) {
+ continue;
+ }
+ } else if (isColumnInAsscociation(column, roles)) {
+ continue;
+ }
+
+ result.add(column);
+ }
+ return result;
+
+ }
+ public List<ORMGenColumn> getSimpleColumns() {
+ return getSimpleColumns(true/*genOnly*/, true/*includePk*/, true/*includeInherited*/);
+ }
+ /**
+ * Returns false if the given column should be generated with
+ * false updatable/insertable.
+ * This is the case when the column is mapped more than once, this
+ * usually happen with columns in composite keys and many-to-one
+ * associations.
+ *
+ * <br>Note that for Hibernate the column param is null because
+ * the insert/update attributes are specified for the many-to-one tag itself
+ * instead of the nested column tags (bogus obviously).
+ */
+ public boolean isColumnUpdateInsert(AssociationRole role, ORMGenColumn column) {
+ if (column == null) {
+ for (Iterator<ORMGenColumn> iter = role.getReferrerColumns().iterator(); iter.hasNext(); ) {
+ ORMGenColumn c = (ORMGenColumn)iter.next();
+ if (!isColumnUpdateInsert(role, c)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (column.isPrimaryKey()) {
+ return false;
+ }
+ /*should look if there are multiple associations using the same column
+ * and return false, but this is probably an unusual case.*/
+
+ return true;
+ }
+ /**
+ * Returns the <code>ORMGenColumn</code> objects corresponding
+ * to the given column names.
+ */
+ public List<ORMGenColumn> getColumnsByNames(List<String> names){
+ List<ORMGenColumn> result = new java.util.ArrayList<ORMGenColumn>();
+ for( String name : names ){
+ ORMGenColumn column = getColumnByName(name);
+ assert(column != null);
+ if (column != null) {
+ result.add(column);
+ }
+ }
+ return result;
+ }
+ /**
+ * Returns the columns having the given name, or null if none.
+ */
+ public ORMGenColumn getColumnByName(String name) {
+ List<ORMGenColumn> columns = getColumns();
+ for (int i = 0, n = columns.size(); i < n; ++i) {
+ ORMGenColumn column = (ORMGenColumn)columns.get(i);
+ if (column.getName().equals(name)) {
+ return column;
+ }
+ }
+ return null;
+ }
+ /**
+ * Returns the <code>AssociationRole</code> objects for this table.
+ * Only the association marked for generation are returned.
+ */
+ public List<AssociationRole> getAssociationRoles(){
+ /*this is not cached intentionally because invalidating the
+ * cache with wizard changes is kinda tricky.*/
+ List<AssociationRole> associationRoles = new ArrayList<AssociationRole>();
+
+ String name = getName();
+ List<Association> associations = mCustomizer.getAssociations();
+ for (Iterator<Association> iter = associations.iterator(); iter.hasNext(); ) {
+ Association association = (Association)iter.next();
+ if (!association.isGenerated()) {
+ continue;
+ }
+ /*check both referrer *and* referenced because an association could be
+ * from-to the same table (employee/manager)*/
+ if (association.getReferrerTable().getName().equals(name)) {
+ AssociationRole role = association.getReferrerRole();
+ if (role != null) {
+ associationRoles.add(role);
+ }
+ }
+ if (association.getReferencedTable().getName().equals(name)) {
+ AssociationRole role = association.getReferencedRole();
+ if (role != null) {
+ associationRoles.add(role);
+ }
+ }
+ }
+ return associationRoles;
+ }
+ public String getClassDescription() {
+ return customized(CLASS_DESC);
+ }
+ /**
+ * Returns the generated class scope, one of {@link #PUBLIC_SCOPE}|{@link #PROTECTED_SCOPE}
+ * |{@link #PRIVATE_SCOPE}.
+ * This method never returns null (defaults to public).
+ */
+ public String getClassScope() {
+ String scope = customized(CLASS_SCOPE);
+ if (scope == null) {
+ scope = PUBLIC_SCOPE;
+ }
+ return scope;
+ }
+ public String getExtends() {
+ return customized(EXTENDS);
+ }
+ public void setExtends(String baseClass) {
+ setCustomized(EXTENDS, baseClass);
+ }
+ public List<String> getImplements() {
+ String str = customized(IMPLEMENTS);
+ List<String> result = StringUtil.strToList(str, ',', true/*trim*/);
+ if (result == null) {
+ result = Collections.emptyList();
+ }
+ return result;
+ }
+ public void setImplements(List<String> interfaces) {
+ setCustomized(IMPLEMENTS, StringUtil.listToStr(interfaces, ','));
+ }
+ /**
+ * Returns the string that should be generated in the Java class
+ * for extends and implements.
+ */
+ public String generateExtendsImplements() {
+ StringBuffer buffer = new StringBuffer();
+
+ String extendsClass = getExtends();
+ if (extendsClass != null && !extendsClass.equals("java.lang.Object") && !extendsClass.equals("Object")) {
+ buffer.append("extends " + simplifyClassName(extendsClass));
+ }
+
+ buffer.append(" implements Serializable"); //assuming that the Java file template imports the java.io.Serializable
+
+ for (Iterator<String> iter = getImplements().iterator(); iter.hasNext(); ) {
+ buffer.append(", " + simplifyClassName((String)iter.next()));
+ }
+
+ return buffer.toString();
+ }
+ private String simplifyClassName(String fullClassName) {
+ final String JAVA_LANG = "java.lang.";
+ if (fullClassName.startsWith(JAVA_LANG)) {
+ return fullClassName.substring(JAVA_LANG.length());
+ }
+ String pkg = StringUtil.getPackageName(fullClassName);
+ if (pkg != null && StringUtil.equalObjects(pkg, getPackage())) {
+ return StringUtil.getClassName(fullClassName);
+ }
+ return fullClassName;
+ }
+ /**
+ * Returns the id generator scheme (assigned, sequence, etc).
+ * Does not return null, defaults to "assigned" or "identity" depending on whether
+ * the table has an identity column.
+ */
+ public String getIdGenerator() {
+ String generator = customized(ID_GENERATOR);
+ String noneGenerator = getCustomizer().getNoIdGenerator();
+ if (!isDefaultsTable()) {
+ /*This is done mainly because there might be cases where some tables have autoinctement pk
+ * and others are assigned. In this case this makes it so that it is possible to have
+ * a "none" default value that is interpreted depending on the case. */
+ if (generator == null || generator.equals(noneGenerator)) {
+ ORMGenColumn pkColumn = getPrimaryKeyColumn();
+ if (pkColumn != null && DTPUtil.isAutoIncrement( pkColumn.getDbColumn() )) {
+ generator = getCustomizer().getIdentityIdGenerator();
+ }
+ }
+ }
+ if (generator == null) {
+ generator = noneGenerator;
+ }
+ return generator;
+ }
+ /**
+ * Changes the id generator scheme (assigned, sequence, etc).
+ */
+ public void setIdGenerator(String scheme) {
+ setCustomized(ID_GENERATOR, scheme);
+ }
+ /**
+ * Returns the sequence name for the given table, or null if none (makes
+ * sense only when the scheme is native, sequence, ..).
+ */
+ public String getSequence() {
+ return customized(SEQUENCE);
+ }
+ public void setSeqence(String name) {
+ setCustomized(SEQUENCE, name);
+ }
+ /**
+ * Returns the sequence name after replacing the ${table} and ${pk}
+ * by their values, or null if none.
+ */
+ public String getFormattedSequence() {
+ String sequence = getSequence();
+ if (sequence != null) {
+ /*resolve the ${table} and ${pk} patterns*/
+ sequence = StringUtil.strReplace(sequence, TABLE_SEQ_PATTERN, getName());
+
+ if (sequence.indexOf(PK_SEQ_PATTERN) >= 0) {
+ List<String> pkNames = DTPUtil.getPrimaryKeyColumnNames( getDbTable() );
+ String pkName = null;
+ if (pkNames.size()>0 ) {
+ pkName = (String)pkNames.get(0);
+ }
+ sequence = StringUtil.strReplace(sequence, PK_SEQ_PATTERN, pkName);
+ }
+ }
+ return sequence!=null?sequence.toUpperCase():"";
+ }
+ public boolean isImplementEquals() {
+ return !"true".equals(customized(IMPLEMENT_EQUALS)); //defaults to false
+ }
+ public void setImplementEquals(boolean value) {
+ setCustomizedBoolean(IMPLEMENT_EQUALS, value, true);
+ }
+
+ /**
+ * Returns true if there is any column participating in equals/hashcode.
+ */
+ public boolean hasColumnsInEquals() {
+ List<ORMGenColumn> columns = getSimpleColumns();
+ for (int i = 0, n = columns.size(); i < n; ++i) {
+ ORMGenColumn column = (ORMGenColumn)columns.get(i);
+ if (column.isUseInEquals()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@link #GENERATE_DDL_ANNOTATION} indicating whether
+ * the optional DDL parameters like length, nullable, unqiue, etc should be generated
+ * in @Column annotation.
+ * defaults to false.
+ */
+ public boolean isGenerateDDLAnnotations() {
+ return "true".equals(customized(GENERATE_DDL_ANNOTATION)); //defaults to false
+ }
+
+ public void setGenerateDDLAnnotations(boolean generate) {
+ setCustomizedBoolean(GENERATE_DDL_ANNOTATION, generate, false);
+ }
+
+ /**
+ * Returns one of {@link #PROPERTY_ACCESS}|{@link #FIELD_ACCESS} indicating how
+ * the entity properties are mapped.
+ * Does not return null (defaults to {@link #FIELD_ACCESS}).
+ */
+ public String getAccess() {
+ String name = customized(ACCESS);
+ if (name == null) {
+ name = FIELD_ACCESS;
+ }
+ return name;
+ }
+ public void setAccess(String access) {
+ assert(access == null || access.equals(PROPERTY_ACCESS) || access.equals(FIELD_ACCESS));
+ if (!StringUtil.equalObjects(access, getAccess())) {
+ setCustomized(ACCESS, access);
+ }
+ }
+ /**
+ * Returns one of {@link #LAZY_FETCH}|{@link #EAGER_FETCH} indicating how
+ * the table associations are feched.
+ * Returns null if the provider defaults should be used.
+ */
+ public String getDefaultFetch() {
+ return customized(DEFAULT_FETCH);
+ }
+ public void setDefaultFetch(String fetch) {
+ assert(fetch == null || fetch.equals(LAZY_FETCH) || fetch.equals(EAGER_FETCH));
+ setCustomized(DEFAULT_FETCH, fetch);
+ }
+ public String[] getSupportedCollectionTypes() {
+ return new String[] {SET_COLLECTION_TYPE, LIST_COLLECTION_TYPE};
+ }
+ /**
+ * Returns one of {@link #LIST_COLLECTION_TYPE}|{@link #SET_COLLECTION_TYPE} indicating
+ * the Java type (full class name) used for properties of collection types.
+ * This does not return null (defaults to list).
+ */
+ public String getDefaultCollectionType() {
+ String cType = customized(DEFAULT_COLLECTION_TYPE);
+ if (cType == null) {
+ cType = SET_COLLECTION_TYPE;
+ }
+ return cType;
+ }
+ public void setDefaultCollectionType(String cType) {
+ assert(cType.equals(LIST_COLLECTION_TYPE) || cType.equals(SET_COLLECTION_TYPE));
+ setCustomized(DEFAULT_COLLECTION_TYPE, cType);
+ }
+ /**
+ * Returns true if the primary key is compound and any of its
+ * columns should be included in the <code>equals</code> method
+ * implementation.
+ */
+ public boolean isCompoundKeyUseInEquals() {
+ if (isCompositeKey()) {
+ for (Iterator<ORMGenColumn> iter = getPrimaryKeyColumns().iterator(); iter.hasNext();) {
+ ORMGenColumn column = (ORMGenColumn) iter.next();
+ if (column.isUseInEquals()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ public boolean isRoleUseInEquals(AssociationRole role) {
+ for (Iterator<ORMGenColumn> iter = role.getReferrerColumns().iterator(); iter.hasNext();) {
+ ORMGenColumn column = (ORMGenColumn) iter.next();
+ if (column.isUseInEquals()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Return true if the values of name element in the @Table is default
+ * so we can skip generating the annotation
+ *
+ * @return true
+ */
+ public boolean isDefaultname(){
+ String className = this.getClassName();
+ String tableName = this.getDbTable().getName();
+ return className.equalsIgnoreCase( tableName) ;
+ }
+
+ /**
+ * Qualifies a class name if there is a package.
+ */
+ private String qualify(String className) {
+ String pkg = getPackage();
+ if (pkg != null && pkg.length() != 0) {
+ className = pkg + '.' + className;
+ }
+ return className;
+ }
+ /**
+ * Returns true if the given column is part of any association.
+ */
+ private boolean isColumnInAsscociation(ORMGenColumn column, List<AssociationRole> roles) {
+ for (int i = 0, n = roles.size(); i < n; ++i) {
+ AssociationRole role = (AssociationRole)roles.get(i);
+ List<ORMGenColumn> cols = role.getReferrerColumns();
+ for( ORMGenColumn col : cols ){
+ if (col.getName().equals( column.getName() )) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Print the clause to be used in the generated equals() method
+ * @return String
+ */
+ public String getPrimaryKeyEqualsClause() {
+ StringBuilder buf = new StringBuilder();
+ Iterator<ORMGenColumn> columns = this.getPrimaryKeyColumns().iterator();
+ while (columns.hasNext()) {
+ this.printPrimaryKeyEqualsClauseOn(columns.next(), buf);
+ if (columns.hasNext()) {
+ buf.append("\n");
+ buf.append("\t\t\t");
+ buf.append("&& ");
+ }
+ }
+ buf.append(";");
+ return buf.toString();
+ }
+
+ private void printPrimaryKeyEqualsClauseOn(ORMGenColumn column, StringBuilder buf) {
+ String fieldName = column.getPropertyName();
+ JavaType javaType = column.getDbColumn().getPrimaryKeyJavaType();
+ if (javaType.isPrimitive()) {
+ this.printPrimitiveEqualsClauseOn(fieldName, buf);
+ } else {
+ this.printReferenceEqualsClauseOn(fieldName, buf);
+ }
+ }
+
+ private void printPrimitiveEqualsClauseOn(String fieldName, StringBuilder buf) {
+ buf.append("(this.");
+ buf.append(fieldName);
+ buf.append(" == castOther.");
+ buf.append(fieldName);
+ buf.append(')');
+ }
+
+ private void printReferenceEqualsClauseOn(String fieldName, StringBuilder buf) {
+ buf.append("this.");
+ buf.append(fieldName);
+ buf.append(".equals(castOther.");
+ buf.append(fieldName);
+ buf.append(')');
+ }
+
+ /**
+ * Print the clause to be used in the generated hasCode() method
+ * @return String
+ */
+ public String getPrimaryKeyHashCodeClause() {
+ StringBuilder buf = new StringBuilder();
+ Iterator<ORMGenColumn> columns = this.getPrimaryKeyColumns().iterator();
+ while (columns.hasNext()) {
+ buf.append("hash = hash * prime + ");
+ this.printPrimaryKeyHashCodeClauseOn(columns.next(), buf);
+ buf.append(';');
+ buf.append('\n');
+ buf.append("\t\t");
+ }
+ return buf.toString();
+ }
+
+ private void printPrimaryKeyHashCodeClauseOn(ORMGenColumn column, StringBuilder buf) {
+ String fieldName = column.getPropertyName();
+ JavaType javaType = column.getDbColumn().getPrimaryKeyJavaType();
+ if (javaType.isPrimitive()) {
+ this.printPrimitiveHashCodeClauseOn(javaType.getElementTypeName(), fieldName, buf);
+ } else {
+ this.printReferenceHashCodeClauseOn(fieldName, buf);
+ }
+ }
+
+ private void printPrimitiveHashCodeClauseOn(String primitiveName, String fieldName, StringBuilder buf) {
+ if (primitiveName.equals("int")) {
+ // this.value
+ buf.append("this.");
+ buf.append(fieldName);
+ } else if (primitiveName.equals("short") || primitiveName.equals("byte") || primitiveName.equals("char")) { // explicit cast
+ // ((int) this.value)
+ buf.append("((int) this.");
+ buf.append(fieldName);
+ buf.append(')');
+ } else if (primitiveName.equals("long")) { // cribbed from Long#hashCode()
+ // ((int) (this.value ^ (this.value >>> 32)))
+ buf.append("((int) (this.");
+ buf.append(fieldName);
+ buf.append(" ^ (this.");
+ buf.append(fieldName);
+ buf.append(" >>> 32)))");
+ } else if (primitiveName.equals("float")) { // cribbed from Float#hashCode()
+ // java.lang.Float.floatToIntBits(this.value)
+ buf.append("java.lang.Float");
+ buf.append(".floatToIntBits(this.");
+ buf.append(fieldName);
+ buf.append(')');
+ } else if (primitiveName.equals("double")) { // cribbed from Double#hashCode()
+ // ((int) (java.lang.Double.doubleToLongBits(this.value) ^ (java.lang.Double.doubleToLongBits(this.value) >>> 32)))
+ buf.append("((int) (");
+ buf.append("java.lang.Double");
+ buf.append(".doubleToLongBits(this.");
+ buf.append(fieldName);
+ buf.append(") ^ (");
+ buf.append("java.lang.Double");
+ buf.append(".doubleToLongBits(this.");
+ buf.append(fieldName);
+ buf.append(") >>> 32)))");
+ } else if (primitiveName.equals("boolean")) {
+ // (this.value ? 1 : 0)
+ buf.append("(this.");
+ buf.append(fieldName);
+ buf.append(" ? 1 : 0)");
+ } else {
+ throw new IllegalArgumentException(primitiveName);
+ }
+ }
+
+ private void printReferenceHashCodeClauseOn(String fieldName, StringBuilder buf) {
+ buf.append("this.");
+ buf.append(fieldName);
+ buf.append(".hashCode()");
+ }
+
+ public String toString(){
+ return "name="+ this.getName() + "; columns=" + Arrays.toString( this.getColumnNames().toArray()) ;
+ }
+
+ /*class scopes*/
+ public static final String PUBLIC_SCOPE = "public";
+ public static final String PROTECTED_SCOPE = "protected";
+ public static final String PRIVATE_SCOPE = "private";
+
+ /*access constants. Note that these strings are used in the ui*/
+ public static final String PROPERTY_ACCESS = "property";
+ public static final String FIELD_ACCESS = "field";
+
+ /*default fech constants. Note that these strings are used in the gen velocity templates.*/
+ public static final String LAZY_FETCH = "lazy";
+ public static final String EAGER_FETCH = "eager";
+
+ /*default collection type constants. Note that these strings are used in the gen velocity templates.*/
+ public static final String LIST_COLLECTION_TYPE = "java.util.List";
+ public static final String SET_COLLECTION_TYPE = "java.util.Set";
+
+ /**
+ * The pattern replaced by the table name in the id generator
+ * sequence name param.
+ */
+ public static final String TABLE_SEQ_PATTERN = "$table";
+ /**
+ * The pattern replaced by the primary key in the id generator
+ * sequence name param.
+ */
+ public static final String PK_SEQ_PATTERN = "$pk";
+
+ /*customization properties*/
+ private static final String PACKAGE = "package";
+ private static final String SRC_FOLDER = "srcFolder";
+ private static final String CLASS_NAME = "className";
+ private static final String CLASS_DESC = "classDesc";
+ private static final String CLASS_SCOPE = "classScope";
+ private static final String EXTENDS = "extends";
+ private static final String IMPLEMENTS = "implements";
+ private static final String ID_GENERATOR = "idGenerator";
+ private static final String SEQUENCE = "sequence";
+ private static final String COMPOSITE_KEY_CLASS_NAME = "compositeKeyClassName";
+ private static final String IMPLEMENT_EQUALS = "implementEquals";
+ private static final String GENERATE_DDL_ANNOTATION = "generateDDLAnnotations";
+ private static final String ACCESS = "access";
+ static final String DEFAULT_FETCH = "defaultFetch";
+ private static final String DEFAULT_COLLECTION_TYPE = "defaultCollectionType";
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/OverwriteConfirmer.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/OverwriteConfirmer.java
new file mode 100644
index 0000000000..105174c4d7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/OverwriteConfirmer.java
@@ -0,0 +1,50 @@
+package org.eclipse.jpt.gen.internal2;
+
+public interface OverwriteConfirmer {
+ /**
+ * Return whether the entity generator should overwrite the specified
+ * file.
+ */
+ boolean overwrite(String className);
+
+
+ final class Always implements OverwriteConfirmer {
+ public static final OverwriteConfirmer INSTANCE = new Always();
+ public static OverwriteConfirmer instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Always() {
+ super();
+ }
+ // everything will be overwritten
+ public boolean overwrite(String arg0) {
+ return true;
+ }
+ @Override
+ public String toString() {
+ return "OverwriteConfirmer.Always"; //$NON-NLS-1$
+ }
+ }
+
+
+ final class Never implements OverwriteConfirmer {
+ public static final OverwriteConfirmer INSTANCE = new Never();
+ public static OverwriteConfirmer instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Never() {
+ super();
+ }
+ // nothing will be overwritten
+ public boolean overwrite(String arg0) {
+ return false;
+ }
+ @Override
+ public String toString() {
+ return "OverwriteConfirmer.Never"; //$NON-NLS-1$
+ }
+ }
+
+} \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/PackageGenerator2.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/PackageGenerator2.java
new file mode 100644
index 0000000000..3b85b09fd0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/PackageGenerator2.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.gen.internal2;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jpt.gen.internal2.util.CompilationUnitModifier;
+import org.eclipse.jpt.gen.internal2.util.FileUtil;
+import org.eclipse.jpt.gen.internal2.util.UrlUtil;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+
+/**
+ * This generator will generate a package of entities for a set of tables.
+ */
+public class PackageGenerator2 {
+
+ private IJavaProject javaProject;
+ private ORMGenCustomizer customizer ;
+
+ /**
+ * @param customizer
+ * @param synchronizePersistenceXml
+ * @param copyJdbcDrive
+ * @throws Exception
+ */
+ static public void generate(IJavaProject jpaProject, ORMGenCustomizer customizer, IProgressMonitor monitor ) throws CoreException {
+ PackageGenerator2 generator = new PackageGenerator2();
+ generator.setProject(jpaProject);
+ generator.setCustomizer(customizer);
+
+ try {
+ generator.doGenerate( monitor);
+ } catch (Exception e) {
+ throw new CoreException(new Status(IStatus.ERROR, JptGenPlugin.PLUGIN_ID, JptGenMessages.Error_Generating_Entities, e));
+ }
+ }
+
+ private Object getCustomizer() {
+ return this.customizer;
+ }
+
+ private void setCustomizer(ORMGenCustomizer customizer2) {
+ this.customizer = customizer2;
+ }
+
+ private void setProject(IJavaProject proj ){
+ this.javaProject = proj;
+ }
+
+ protected void doGenerate( IProgressMonitor monitor ) throws Exception {
+ generateInternal( monitor );
+ }
+
+ protected void generateInternal( IProgressMonitor progress) throws Exception {
+ File templDir = prepareTemplatesFolder();
+
+ List<String> genClasses = new java.util.ArrayList<String>();
+ List<String> tableNames = customizer.getGenTableNames();
+
+ /* .java per table, persistence.xml, refresh package folder */
+ String taskName = NLS.bind(JptGenMessages.EntityGenerator_taskName, "Total "+ tableNames.size() + 2);//$NON-NLS-1$
+ progress.beginTask(taskName, tableNames.size() + 2);
+
+
+ for (Iterator<String> iter = tableNames.iterator(); iter.hasNext();) {
+ String tableName = (String) iter.next();
+ ORMGenTable table = (ORMGenTable) customizer.getTable(tableName);
+
+ generateClass(table, templDir.getAbsolutePath(), progress);
+ progress.worked(1);
+
+ genClasses.add(table.getQualifiedClassName());
+ /*
+ * add the composite key class to persistence.xml because some
+ * JPA provider(e.g. Kodo) requires it. Hibernate doesn't seem to care).
+ */
+ if (table.isCompositeKey()) {
+ genClasses.add(table.getQualifiedCompositeKeyClassName());
+ }
+ }
+ progress.done();
+ }
+
+ private File prepareTemplatesFolder() throws IOException, Exception,
+ CoreException {
+ //Prepare the Velocity template folder:
+ //If the plug-in is packaged as a JAR, we need extract the template
+ //folder into the plug-in state location. This is required by Velocity
+ //since we use included templates.
+ Bundle bundle = Platform.getBundle(JptGenPlugin.PLUGIN_ID);
+ String templatesPath = "templates/entities/"; //$NON-NLS-1$
+ Path path = new Path( templatesPath);
+ URL url = FileLocator.find(bundle, path, null);
+ if ( url ==null ) {
+ throw new CoreException(new Status(IStatus.ERROR, JptGenPlugin.PLUGIN_ID, JptGenMessages.Templates_notFound + " "+ JptGenPlugin.PLUGIN_ID + "/" + templatesPath) );//$NON-NLS-1$
+ }
+ URL templUrl = FileLocator.resolve(url);
+
+ //Have this check so that the code would work in both PDE and JARed plug-in at runtime
+ File templDir = null;
+ if( UrlUtil.isJarUrl(templUrl) ){
+ templDir = FileUtil.extractFilesFromBundle( templUrl, bundle, templatesPath );
+ }else{
+ templDir = UrlUtil.getUrlFile(templUrl);
+ }
+
+
+ if (templDir==null || !templDir.exists()) {
+ throw new CoreException(new Status(IStatus.ERROR, JptGenPlugin.PLUGIN_ID, JptGenMessages.Templates_notFound + " "+ JptGenPlugin.PLUGIN_ID ) );//$NON-NLS-1$
+ }
+ return templDir;
+ }
+
+ /**
+ * Saves/Creates the .java file corresponding to a database table
+ * with the given content.
+ *
+ * @param templDir The velocity template file directory. It is assumed
+ * that this directory contains the 2 files <em>main.java.vm</em>
+ * and <em>pk.java.vm</em>
+ * @param progress
+ */
+ protected void generateClass(ORMGenTable table, String templateDirPath, IProgressMonitor monitor) throws Exception {
+
+ String subTaskName = NLS.bind(JptGenMessages.EntityGenerator_taskName, table.getName());
+ SubMonitor sm = SubMonitor.convert(monitor, subTaskName, 100);
+
+ try{
+ IFolder javaPackageFolder = getJavaPackageFolder(table, monitor);
+ IFile javaFile = javaPackageFolder.getFile( table.getClassName() + ".java"); //$NON-NLS-1$
+
+ Properties vep = new Properties();
+ vep.setProperty("file.resource.loader.path", templateDirPath); //$NON-NLS-1$
+ VelocityEngine ve = new VelocityEngine();
+ ve.init(vep);
+ sm.worked(20);
+
+ generateJavaFile(table, javaFile, ve, "main.java.vm", true/*isDomainClass*/, monitor); //$NON-NLS-1$
+ sm.worked(80);
+
+ if (table.isCompositeKey()) {
+ IFile compositeKeyFile = javaPackageFolder.getFile( table.getCompositeKeyClassName()+".java"); //$NON-NLS-1$
+ generateJavaFile(table, compositeKeyFile, ve, "pk.java.vm", false/*isDomainClass*/, monitor ); //$NON-NLS-1$
+ }
+
+ javaFile.refreshLocal(1, new NullProgressMonitor());
+
+ } catch(Throwable e){
+ CoreException ce = new CoreException(new Status(IStatus.ERROR, JptGenPlugin.PLUGIN_ID, JptGenMessages.Templates_notFound + "" + JptGenPlugin.PLUGIN_ID , e) );//$NON-NLS-1$
+ JptGenPlugin.logException( ce );
+ }
+ sm.setWorkRemaining(0);
+ }
+
+ private void generateJavaFile(ORMGenTable table, IFile javaFile, VelocityEngine ve
+ , String templateName, boolean isDomainClass, IProgressMonitor monitor) throws Exception {
+ VelocityContext context = new VelocityContext();
+ context.put("table", table); //$NON-NLS-1$
+ context.put("customizer", getCustomizer()); //$NON-NLS-1$
+
+ StringWriter w = new StringWriter();
+ ve.mergeTemplate(templateName, context, w);
+
+ String fileContent = w.toString();
+ if (javaFile.exists()) {
+ if (isDomainClass) {
+ updateExistingDomainClass(table.getQualifiedClassName(), javaFile, fileContent);
+ } else {
+ javaFile.setContents(new ByteArrayInputStream(fileContent.getBytes()), true, true, monitor );
+ }
+ } else {
+ createFile(javaFile, new ByteArrayInputStream(fileContent.getBytes()));
+ }
+ }
+
+
+ /**
+ * Updates the (existing) Java file corresponding to the given class.
+ *
+ * @param className The qualified class name.
+ *
+ * @param javaFile The existing Java file of the class to update.
+ *
+ * @param fileContent The new file content.
+ */
+ protected void updateExistingDomainClass(String className, IFile javaFile, String fileContent) throws Exception {
+ /*use CompilationUnitModifier instead of calling WideEnv.getEnv().setFileContent
+ * so that if the unit is up to date if it is used before file change
+ * notifications are delivered (see EJB3ImportSchemaWizard.updateExistingDomainClass for example)*/
+ IJavaProject project = javaProject.getJavaProject();
+ CompilationUnitModifier modifier = new CompilationUnitModifier(project, className);
+ modifier.setJavaSource(fileContent);
+ modifier.save();
+ }
+
+ public void createFile(IFile file, java.io.InputStream contents) throws CoreException {
+ file.create(contents, false, null/*monitor*/);
+ }
+
+ public IFolder getJavaPackageFolder(ORMGenTable table, IProgressMonitor monitor) throws CoreException {
+ IPackageFragmentRoot root = getDefaultJavaSrouceLocation ( javaProject ) ;
+ String packageName = table.getPackage();
+ if( packageName==null ) packageName ="";
+ IPackageFragment packageFragment = root.getPackageFragment(packageName);
+ if( !packageFragment.exists()){
+ root.createPackageFragment(packageName, true, monitor);
+ }
+ return (IFolder)packageFragment.getResource();
+ }
+
+ private IPackageFragmentRoot getDefaultJavaSrouceLocation(IJavaProject jproject){
+ if (jproject != null) {
+ try {
+ if (jproject.exists()) {
+ IPackageFragmentRoot[] roots = jproject.getPackageFragmentRoots();
+ for (int i= 0; i < roots.length; i++) {
+ if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
+ return roots[i] ;
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ JptGenPlugin.logException(e);
+ }
+ }
+ return null;
+ }
+
+
+ // ********** annotation name builder **********
+
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/TagNames.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/TagNames.java
new file mode 100644
index 0000000000..92a60fed77
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/TagNames.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2;
+
+/**
+ * TODO: merge with JPA class ?
+ * The JPA mapping tag and attribute names.
+ *
+ */
+public class TagNames
+{
+ public static final String BASIC_TAG = "basic";
+ public static final String CASCADE_TAG = "cascade";
+ public static final String COLUMN_TAG = "column";
+ public static final String EMBEDDED_TAG = "embedded";
+ public static final String EMBEDDED_ID_TAG = "embedded-id";
+ public static final String GENERATED_VALUE_TAG = "generated-value";
+ public static final String ID_TAG = "id";
+ public static final String ID_CLASS_TAG = "id";
+ public static final String JOIN_COLUMN_TAG = "join-column";
+ public static final String INVERSE_JOIN_COLUMN_TAG = "inverse-join-column";
+ public static final String LOB_TAG = "lob";
+ public static final String MANY_TO_MANY_TAG = "many-to-many";
+ public static final String MANY_TO_ONE_TAG = "many-to-one";
+ public static final String MAPPED_BY_TAG = "mapped-by";
+ public static final String ONE_TO_MANY_TAG = "one-to-many";
+ public static final String ONE_TO_ONE_TAG = "one-to-one";
+ public static final String PK_JOIN_COLUMN_TAG = "primary-key-join-column";
+ public static final String TABLE_TAG = "table";
+ public static final String VERSION_TAG = "version";
+ public static final String JOIN_TABLE_TAG = "join-table";
+
+ /*cascade tags*/
+ public static final String ALL_CASCADE = "all";
+ public static final String PERSIST_CASCADE = "persist";
+ public static final String MERGE_CASCADE = "merge";
+ public static final String REMOVE_CASCADE = "remove";
+ public static final String REFRESH_CASCADE = "refresh";
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/CompilationUnitModifier.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/CompilationUnitModifier.java
new file mode 100644
index 0000000000..a238b7910e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/CompilationUnitModifier.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2.util;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jface.text.Document;
+import org.eclipse.text.edits.TextEdit;
+
+
+/**
+ * Performs the grunt work needed for modifying a compilation
+ * unit and performs the modified compilation unit save.
+ *
+ * The typical usage is as follows:
+ * <ol><li>Create an instance.
+ *
+ * <li>Modify the compilation unit using AST operations performed
+ * on the node returned by {@link #getCompilationUnitNode()}.
+ * Alternatively you can call <code>setJavaSource</code> to change the entire source code.
+ *
+ * <li>Call the {@link #save()} method.
+ *
+ */
+public class CompilationUnitModifier
+{
+ private IJavaProject mProject;
+ private ICompilationUnit mCompilationUnit;
+ private CompilationUnit mCompilationUnitNode;
+ private Document mDocument;
+
+ public CompilationUnitModifier(IJavaProject project, String className) throws Exception {
+ super();
+
+ mProject = project;
+
+ IType type = project.findType(className);
+ if (type == null) {
+ throw new Exception("The class " + className + " does not exist.");
+ }
+ mCompilationUnit = type.getCompilationUnit();
+ if (mCompilationUnit == null) {
+ throw new Exception("The source code for " + className + " does not exist.");
+ }
+ }
+ public CompilationUnitModifier(IJavaProject project, ICompilationUnit cu) throws Exception {
+ super();
+
+ mProject = project;
+ mCompilationUnit = cu;
+ }
+ public CompilationUnitModifier(IJavaProject project, ICompilationUnit cu, CompilationUnit cuNode) throws Exception {
+ super();
+
+ mProject = project;
+ mCompilationUnit = cu;
+ mCompilationUnitNode = cuNode;
+
+ getCompilationUnitNode(); //to create mDocument (the caller in this case does not have to call getCompilationUnitNode)
+ }
+ public ICompilationUnit getCompilationUnit() {
+ return mCompilationUnit;
+ }
+ /**
+ * Returns the compilation unit node that should be used for
+ * tyhe modification AST operations.
+ */
+ public CompilationUnit getCompilationUnitNode() {
+ if (mCompilationUnitNode == null) {
+ ASTParser c = ASTParser.newParser(AST.JLS3);
+ c.setSource(mCompilationUnit);
+ c.setResolveBindings(true);
+ mCompilationUnitNode = (CompilationUnit)c.createAST(null);
+ }
+ if (mDocument == null) {
+ try {
+ mDocument = new Document(mCompilationUnit.getBuffer().getContents());
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+
+ mCompilationUnitNode.recordModifications();
+ }
+
+ return mCompilationUnitNode;
+ }
+ /**
+ * Changes the entire Java source code of the compilation unit.
+ */
+ public void setJavaSource(String newSource) {
+ try {
+ mCompilationUnit.getBuffer().setContents(newSource);
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * Saves the compilation unit modifications.
+ */
+ public void save() throws Exception {
+ if (mCompilationUnitNode != null) {
+ assert(mDocument != null); //see getCompilationUnitNode
+
+ //computation of the text edits
+ TextEdit edits = mCompilationUnitNode.rewrite(mDocument, mProject.getOptions(true));
+ //computation of the new source code
+ edits.apply(mDocument);
+ String newSource = mDocument.get();
+ // update of the compilation unit
+ mCompilationUnit.getBuffer().setContents(newSource);
+ }
+
+ if (mCompilationUnit.isWorkingCopy()) {
+ mCompilationUnit.commitWorkingCopy(true/*force*/, null/*monitor*/);
+ } else {
+ mCompilationUnit.save(null/*monitor*/, true/*force*/);
+ }
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/DTPUtil.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/DTPUtil.java
new file mode 100644
index 0000000000..dcf3ef9b1a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/DTPUtil.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.db.ForeignKey.ColumnPair;
+import org.eclipse.jpt.gen.internal2.ForeignKeyInfo;
+
+/**
+ * Collection of utility methods to access DTP and other jpt.db APIs
+ *
+ */
+public class DTPUtil {
+
+ /**
+ * Return list of the pk names
+ * @param dbTable
+ * @return
+ */
+ public static List<String> getPrimaryKeyColumnNames(Table dbTable ) {
+ Iterator<Column> pkColumns = dbTable.primaryKeyColumns();
+ ArrayList<String> ret = new ArrayList<String>();
+ while( pkColumns.hasNext() ){
+ ret.add( pkColumns.next().getName() );
+ }
+ return ret;
+ }
+
+ /**
+ *
+ * @param dbTable
+ * @return
+ */
+ public static List<Column> getPrimaryKeyColumns(Table dbTable ) {
+ Iterator<Column> pkColumns = dbTable.primaryKeyColumns();
+ ArrayList<Column> ret = new ArrayList<Column>();
+ while( pkColumns.hasNext() ){
+ ret.add( pkColumns.next() );
+ }
+ return ret;
+ }
+
+ public static boolean isAutoIncrement(Column c){
+ //@ TODO
+ //Blocked by DTP bug
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=250023
+ //The Dali bug is
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=249658
+ //
+ return false;
+ }
+
+ /**
+ * Return list of fk
+ * @param dbTable
+ * @return
+ */
+ public static List<ForeignKeyInfo> getForeignKeys(Table dbTable) {
+ List<ForeignKeyInfo> ret = new ArrayList<ForeignKeyInfo>();
+ if(dbTable!=null){
+ Iterator<ForeignKey> fks = dbTable.foreignKeys();
+ while( fks.hasNext() ){
+ ForeignKey fk = fks.next();
+ ColumnPair columnPair = fk.getColumnPair();
+
+ String tableName = dbTable.getName();
+ String referencedTableName = "";
+ Table referencedTable = fk.getReferencedTable();
+ referencedTableName = referencedTable.getName();
+ ForeignKeyInfo fkInfo = new ForeignKeyInfo(fk, tableName, referencedTableName );
+ String baseColName = columnPair.getBaseColumn().getName();
+ String referencedColName = columnPair.getReferencedColumn().getName();
+ fkInfo.addColumnMapping( baseColName, referencedColName );
+ ret.add( fkInfo );
+ }
+ }
+ return ret;
+ }
+
+ public static String getJavaType(Schema schema, Column dbColumn) {
+ if( isPrimaryKey(dbColumn) )
+ return dbColumn.getPrimaryKeyJavaTypeDeclaration();
+ return dbColumn.getJavaTypeDeclaration();
+ }
+
+ public static boolean isPrimaryKey(Column dbColumn){
+ Table dbTable = dbColumn.getTable();
+ Iterator<Column> pkColumns = dbTable.primaryKeyColumns();
+ while( pkColumns.hasNext() ){
+ if( pkColumns.next().equals( dbColumn )){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isDefaultSchema(Table dbTable){
+ String schemaName = dbTable.getSchema().getName();
+ Schema defaultSchema = dbTable.getSchema().getConnectionProfile().getDatabase().getDefaultSchema();
+ return defaultSchema.getName() == schemaName;
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/FileUtil.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/FileUtil.java
new file mode 100644
index 0000000000..1235d6adf5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/FileUtil.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.osgi.framework.Bundle;
+
+/**
+ * Collections of utility methods handling files.
+ *
+ */
+public class FileUtil
+{
+
+ private static String DELETE_FOLDER_ERR = "The directory %s could not be deleted.";
+ private static String DELETE_FILE_ERR = "The file %s could not be deleted.";
+ private static String FILE_READONLY_ERR = "The file %s could not be modified because write access is denied.\nPlease make sure that the file is not marked as readonly in the file system.";
+
+ public static void deleteFolder(File folder)
+ throws IOException
+ {
+ File[] files = folder.listFiles();
+ //empty the folder first (java.io.file.delete requires it empty)
+ if (files != null) {
+ for (int i = 0; i < files.length; ++i) {
+ File f = files[i];
+ if (f.isDirectory())
+ deleteFolder(f);
+ else
+ deletePath(f);
+ }
+ }
+ deletePath(folder);
+ }
+
+ public static void deletePath(File f)
+ throws IOException
+ {
+ if (!f.delete()) {
+ String msgId = f.isDirectory() ? DELETE_FOLDER_ERR : DELETE_FILE_ERR;
+ throw new IOException( String.format(msgId,f.getPath()));
+ }
+ }
+
+ public static byte[] readFile(File src)
+ throws IOException
+ {
+ java.io.FileInputStream fin = new java.io.FileInputStream(src);
+ try {
+ long fileLen = src.length();
+ if (fileLen > Integer.MAX_VALUE)
+ throw new IOException("file length too big to be read by FileUtil.readFile: " + fileLen);
+
+ byte[] bytes = new byte[(int)fileLen];
+ fin.read(bytes);
+ return bytes;
+ }
+ finally {
+ fin.close();
+ }
+ }
+
+ public static void writeFile(File dest, byte[] bytes)
+ throws IOException
+ {
+ if (dest.exists() && !dest.canWrite())
+ throw new IOException( FILE_READONLY_ERR ); //throw with a clear error because otherwise FileOutputStream throws FileNotFoundException!
+ java.io.FileOutputStream fout = new java.io.FileOutputStream(dest.getPath(), false/*append*/);
+ try {
+ fout.write(bytes);
+ }
+ finally {
+ fout.flush();
+ fout.close();
+ }
+ }
+
+ /**
+ * Returns the url for a file.
+ * This basically the same as file.toUrl() but without the non-sense exception.
+ */
+ public static URL getFileUrl(File file) {
+ try {
+ return file.toURI().toURL();
+ } catch (MalformedURLException e) {
+ return null; //should not happen as file.toURL() does not really throw an exception
+ }
+ }
+
+ public static void setFileContent(File file, java.io.InputStream contents) throws java.io.IOException {
+ Path path = new Path(file.getAbsolutePath());
+ try {
+ IFile iFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
+ if (iFile == null) {
+ throw new IOException("The path " + file + " does not seem to be a valid file path.");
+ }
+ iFile.setContents(contents, true/*force*/, true/*keepHistory*/, null/*monitor*/);
+ } catch (CoreException ex) {
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Extract the contents of a Jar archive to the specified destination.
+ */
+ public static void unjar(InputStream in, File dest) throws IOException {
+ if (!dest.exists()) {
+ dest.mkdirs();
+ }
+ if (!dest.isDirectory()) {
+ throw new IOException("Destination must be a directory.");//$NON-NLS-1$
+ }
+ JarInputStream jin = new JarInputStream(in);
+ byte[] buffer = new byte[1024];
+
+ ZipEntry entry = jin.getNextEntry();
+ while (entry != null) {
+ String fileName = entry.getName();
+ if (fileName.charAt(fileName.length() - 1) == '/') {
+ fileName = fileName.substring(0, fileName.length() - 1);
+ }
+ if (fileName.charAt(0) == '/') {
+ fileName = fileName.substring(1);
+ }
+ if (File.separatorChar != '/') {
+ fileName = fileName.replace('/', File.separatorChar);
+ }
+ File file = new File(dest, fileName);
+ if (entry.isDirectory()) {
+ // make sure the directory exists
+ file.mkdirs();
+ jin.closeEntry();
+ } else {
+ // make sure the directory exists
+ File parent = file.getParentFile();
+ if (parent != null && !parent.exists()) {
+ parent.mkdirs();
+ }
+
+ // dump the file
+ OutputStream out = new FileOutputStream(file);
+ int len = 0;
+ while ((len = jin.read(buffer, 0, buffer.length)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ out.flush();
+ out.close();
+ jin.closeEntry();
+ file.setLastModified(entry.getTime());
+ }
+ entry = jin.getNextEntry();
+ }
+ /* Explicitly write out the META-INF/MANIFEST.MF so that any headers such
+ as the Class-Path are seen for the unpackaged jar
+ */
+ Manifest mf = jin.getManifest();
+ if (mf != null) {
+ File file = new File(dest, "META-INF/MANIFEST.MF");//$NON-NLS-1$
+ File parent = file.getParentFile();
+ if (parent.exists() == false) {
+ parent.mkdirs();
+ }
+ OutputStream out = new FileOutputStream(file);
+ mf.write(out);
+ out.flush();
+ out.close();
+ }
+ jin.close();
+ }
+
+ //Used to Unzip the a specific folder packed inside a plug-in bundle to the plug-in state location
+ public static File extractFilesFromBundle( URL url, Bundle bundle, String path ) throws Exception {
+ URL jarUrl = UrlUtil.getJarFileUrl(url);
+ File jarFile = new File(jarUrl.getFile() );
+ Location configLocation = Platform.getConfigurationLocation();
+ String pluginId = bundle.getSymbolicName();
+ File configFolder = new File( configLocation.getURL().getFile(), pluginId);
+ File templDir = new File( configFolder, path );
+ if( !templDir.exists() ){
+ FileUtil.unjar( new FileInputStream( jarFile ), configFolder );
+ //Delete un-related files and folders
+ File[] files = configFolder.listFiles();
+ for( File f : files ){
+ if( f.isFile() )
+ f.delete();
+ else if( templDir.getPath().indexOf( f.getPath() ) !=0 ){
+ FileUtil.deleteFolder(f);
+ }
+ }
+ }
+ return templDir ;
+ }
+}
+
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/StringUtil.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/StringUtil.java
new file mode 100644
index 0000000000..45efe138a2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/StringUtil.java
@@ -0,0 +1,648 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.gen.internal2.util;
+
+import java.beans.Introspector;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class StringUtil
+{
+ /**
+ * Pads a string by adding a sequence of an arbitrary character at the beginning.
+ * @param padChar The character to be used for padding.
+ * @param len The desired length after padding.
+ * @return The padded string. For example if <code>str</code> is "f4e" and <code>padChar</code> is '0'
+ * and <code>len</code> is 6 then this method returns "000f4e"
+ */
+ public static String padLeft(String str, char padChar, int len) {
+ if(str == null) {
+ return null;
+ }
+ int strLen = str.length();
+ if (strLen < len) {
+ StringBuffer buffer = new StringBuffer(len);
+ int count = len-strLen;
+ for (int i = 0; i < count; ++i)
+ buffer.append(padChar);
+ buffer.append(str);
+ str = buffer.toString();
+ }
+ return str;
+ }
+ /**
+ * Inserts a given character at the beginning and at the end of the specified string.
+ * For example if the string is <tt>extreme</tt> and the char is <tt>'</tt> then
+ * the returned string is <tt>'exterme'</tt>.
+ */
+ public static String quote(String str, char c) {
+ assert(str != null);
+ StringBuffer buffer = new StringBuffer(str.length()+2);
+ buffer.append(c);
+ buffer.append(str);
+ buffer.append(c);
+ return buffer.toString();
+ }
+ public static String doubleQuote(String str) {
+ return quote(str, '"');
+ }
+ /**
+ * Removes the first and last single or double quotes (if they exist).
+ */
+ public static String unquote(String quoted) {
+ if (quoted != null && quoted.length() >= 2){
+ int len = quoted.length();
+ char firstChar = quoted.charAt(0);
+ char lastChar = quoted.charAt(len-1);
+ if (firstChar == lastChar && (firstChar == '\'' || firstChar == '"')) {
+ return quoted.substring(1, len-1);
+ }
+ }
+ return quoted;
+ }
+ /**
+ * Truncates a string and adds "..." in the result string.
+ * If the string length is less or equal to the max len then
+ * the original string is returned.
+ */
+ public static String truncate(String s, int maxLen) {
+ if (s == null) {
+ return null;
+ }
+ int len = s.length();
+ if (len > maxLen) {
+ int segmentLen = maxLen/2;
+ s = s.substring(0, segmentLen) + "..." + s.substring(len-segmentLen);
+ }
+ return s;
+ }
+ /**
+ * Returns a string containing the same character repeated.
+ */
+ public static String repeat(char c, int count) {
+ StringBuffer buffer = new StringBuffer(count);
+ for (int i = 0; i < count; ++i) {
+ buffer.append(c);
+ }
+ return buffer.toString();
+ }
+ /**
+ * Returns the given string unless it is emtpty where it returns null.
+ */
+ public static String nullIfEmpty(String s) {
+ if (s != null && s.length() == 0) {
+ s = null;
+ }
+ return s;
+ }
+ /**
+ * Returns a string containing the same characters as the argument string
+ * except that the control characters are replaced by the their hex code.
+ * For example if the string is "ab\nc" the returned string is "ab{0xA}c".
+ */
+ public static String getVisibleString(String s) {
+ if (s == null)
+ return null;
+ int len = s.length();
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < len; ++i) {
+ char c = s.charAt(i);
+ if (c <= 0x1F || (c == 0x20 && (i == 0 || i == len-1))) {
+ buffer.append("(0x" + Integer.toHexString((int)c).toUpperCase() + ")");
+ }
+ else buffer.append(c);
+ }
+ return buffer.toString();
+ }
+ /**
+ * Replaces a portion of string.
+ * @param str The original string.
+ * @param offset The offset in the original string where the replace starts
+ * @param len The replace length the original string
+ * @param replaceStr The replacement string
+ */
+ public static String strReplace(String str, int offset, int len, String replaceStr) {
+ StringBuffer buffer = new StringBuffer(str.length()-len+replaceStr.length());
+ buffer.append(str.substring(0, offset));
+ buffer.append(replaceStr);
+ buffer.append(str.substring(offset+len));
+
+ return buffer.toString();
+ }
+ public static String strReplace(String str, String pattern, String replaceStr)
+ {
+ if(str == null) {
+ return null;
+ }
+ if(pattern == null || pattern.equals("")) {
+ return str;
+ }
+ int index = str.indexOf(pattern);
+ if (index < 0)
+ return str;
+
+ if (replaceStr == null)
+ replaceStr = "";
+ return str.substring(0, index) + replaceStr + str.substring(index + pattern.length());
+ }
+ public static String strReplaceAll(String str, String pattern, String replaceStr)
+ {
+ if(str == null) {
+ return null;
+ }
+ if (replaceStr == null)
+ replaceStr = "";
+ if(pattern == null || pattern.equals("")) {
+ return str;
+ }
+ int index = str.indexOf(pattern);
+ while (index >= 0) {
+ str = str.substring(0, index) + replaceStr + str.substring(index + pattern.length());
+ index = str.indexOf(pattern, index+replaceStr.length());
+ }
+ return str;
+ }
+ public static String strInsert(String str, int index, String insertStr)
+ {
+ return str.substring(0, index)
+ + insertStr
+ + str.substring(index);
+ }
+ /**
+ * Tokenize the specified string into a <code>List</code> of
+ * words.
+ * If the string specified is <code>null</code> or empty, this
+ * method will return <code>null</code>.
+ *
+ * @param s The string to tokenize into a <code>List</code>.
+ * @param sep The separator character to use to split
+ * the string.
+ * @param trim If <code>true</code>, run <code>trim</code> on
+ * each element in the result <code>List</code>.
+ *
+ * @return A <code>List</code> containing all tokenized words
+ * in the parameter string.
+ * Each element is of type <code>String</code>.
+ */
+ public static List<String> strToList(String s, char sep, boolean trim)
+ {
+ //ex: if sep is ';' then s should be someting like "Red;Black"
+ if (s == null || s.length() == 0)
+ return null;
+
+ ArrayList<String> result = new ArrayList<String>();
+
+ char delimiters[] = {sep};
+ java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(s, new String(delimiters), true/*returnDelimiters*/);
+ String lastTok=null;
+ while (tokenizer.hasMoreTokens()) {
+ String tok = tokenizer.nextToken();
+ if (tok.length()==1 && tok.charAt(0)==sep){//delimiter
+ if (tok.equals(lastTok)||lastTok==null/*first element is empty*/)
+ result.add("");
+ }
+ else{
+ if (trim)
+ tok = tok.trim();
+ result.add(tok);
+ }
+ lastTok=tok;
+ }
+ if(lastTok.length()==1 && lastTok.charAt(0)==sep)//last element is empty
+ result.add("");
+ result.trimToSize();
+ return result;
+ }
+ public static List<String> strToList(String s, char sep)
+ {
+ return strToList(s, sep, false/*trim*/);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static String listToStr(Collection a, char sep)
+ {
+ return listToStr(a, String.valueOf(sep));
+ }
+
+ public static String listToStr(Collection<Object> a, String sep) {
+ //reverse of strToList
+ if (a == null)
+ return null;
+ int count = a.size();
+ if (count == 0)
+ return null;
+
+ StringBuffer buffer = null;
+ for (Iterator<Object> iter = a.iterator(); iter.hasNext(); )
+ {
+ Object obj = iter.next();
+ if (obj == null)
+ continue;
+
+ if (buffer == null)
+ buffer = new StringBuffer();
+ else
+ buffer.append(sep);
+ if (obj instanceof String)
+ buffer.append((String)obj);
+ else
+ buffer.append(obj);
+ }
+ return (buffer != null) ? buffer.toString() : null;
+ }
+ /**
+ * Convert the text of a String into a Map of Strings, where each
+ * key and value in the Map is of type String.
+ *
+ * @param s The string to be converted to a Map.
+ * @param sep1 The separator between keys and their
+ * values.
+ * @param sep2 The separator between key-value pairs.
+ *
+ * @return The string converted to a Map.
+ */
+ public static java.util.Map<String, String> strToMap(String s, char sep1, char sep2)
+ {
+ return strToMap(s, sep1, sep2, false/*lowercaseKeys*/);
+ }
+ /**
+ * Convert the text of a String into a Map of Strings, where each
+ * key and value in the Map is of type String.
+ * This form also allows you to specify that all keys will be
+ * converted to lower-case before adding to the Map.
+ *
+ * @param s The string to be converted to a Map.
+ * @param sep1 The separator between keys and their
+ * values.
+ * @param sep2 The separator between key-value pairs.
+ * @param lowercaseKeys
+ * Whether to convert keys to lower case
+ * before adding to the Map.
+ *
+ * @return The string converted to a Map.
+ */
+ public static java.util.Map<String, String> strToMap(String s, char sep1, char sep2, boolean lowercaseKeys)
+ {
+ //ex: if sep1 is ':' and sep2 is ',' then s should be something like "color:Red,size:XL"
+
+ if (s == null || s.length() == 0) {
+ return Collections.emptyMap();
+ }
+
+ java.util.List<String> a = strToList(s, sep2);
+ if (a == null) {
+ return Collections.emptyMap();
+ }
+
+ java.util.HashMap<String, String> hm = new java.util.HashMap<String, String>();
+ int count = a.size();
+ for (int i = 0; i < count; ++i)
+ {
+ String s2 = (String)a.get(i); //ex: color:Red
+ int pos = s2.indexOf(sep1);
+ if (pos >= 0)
+ {
+ String name = s2.substring(0, pos);
+ String val = s2.substring(pos+1);
+ if (lowercaseKeys)
+ name = name.toLowerCase();
+ hm.put(name, val);
+ }
+ }
+ return hm;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static String mapToStr(java.util.Map hm, char sep1, char sep2)
+ //reverse of strToMap
+ {
+ if (hm == null || hm.isEmpty())
+ return null;
+
+ StringBuffer buffer = new StringBuffer();
+ java.util.Iterator<java.util.Map.Entry> iter = hm.entrySet().iterator();
+ while (iter.hasNext()) {
+ java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
+ buffer.append(entry.getKey());
+ buffer.append(sep1);
+ buffer.append(entry.getValue());
+ if (iter.hasNext()) {
+ buffer.append(sep2);
+ }
+ }
+ return buffer.toString();
+ }
+ /**
+ * Perform a <em>case insensitive</em> comparison between
+ * the string representations of two objects.
+ *
+ * @param obj1 The first object to compare.
+ * @param obj2 The second object to compare.
+ *
+ * @return <code>true</code> if both objects have the
+ * same case-insensitive string representation.
+ */
+ public static boolean compareAsStrings(Object obj1, Object obj2)
+ {
+ if (obj1 == null || obj2 == null)
+ return obj1 == obj2;
+
+ String s1, s2;
+ if (obj1 instanceof String) {
+ s1 = (String)obj1;
+ } else {
+ s1 = obj1.toString();
+ }
+ if (obj2 instanceof String) {
+ s2 = (String)obj2;
+ }
+ else {
+ s2 = obj2.toString();
+ }
+
+ return s1.equalsIgnoreCase(s2);
+ }
+ /**
+ * Tests whether a string starts with any of a list of strings.
+ */
+ public static boolean startsWithAny(String s, List<String> prefixes) {
+ int count = prefixes.size();
+ for (int i = 0; i < count; ++i) {
+ if (s.startsWith((String)prefixes.get(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ /**
+ * Returns the argument string with the first char upper-case.
+ */
+ public static String initUpper(String str) {
+ if (str == null || str.length() == 0) {
+ return str;
+ }
+ return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+ }
+ /**
+ * Returns the argument string with the first char lower-case.
+ */
+ public static String initLower(String str) {
+ if (str == null || str.length() == 0) {
+ return str;
+ }
+ return Character.toLowerCase(str.charAt(0)) + str.substring(1);
+ }
+ /**
+ * Tests whether all characters in the given string are upper
+ * case.
+ */
+ public static boolean isUpperCase(String s) {
+ return s.toUpperCase().equals(s);
+ }
+ /**
+ * Returns the first non-white char index starting from the
+ * specified index.
+ */
+ public static int skipWhiteSpaces(String str, int index) {
+ int len = str.length();
+ while (index < len) {
+ if (!Character.isWhitespace(str.charAt(index))) {
+ break;
+ }
+ ++index;
+ }
+ return index;
+ }
+ /**
+ * Collapses consecutive white spaces into one space.
+ */
+ public static String collapseWhiteSpaces(String str){
+ String result=null;
+ if (str!=null){
+ StringBuffer buffer=new StringBuffer();
+ boolean isInWhiteSpace=false;
+ for (int i=0;i<str.length();i++){
+ char c=str.charAt(i);
+ if (Character.isWhitespace(c)){
+ isInWhiteSpace=true;
+ }
+ else {
+ if (isInWhiteSpace)
+ buffer.append(" ");
+ isInWhiteSpace=false;
+ buffer.append(c);
+ }
+ }
+ result=buffer.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Utility methods used to convert DB object names to
+ * appropriate Java type and field name
+ */
+ public static String pluralise(String name) {
+ String result = name;
+ if (name.length() == 1) {
+ result += 's';
+ } else if (!seemsPluralised(name)) {
+ String lower = name.toLowerCase();
+ if (!lower.endsWith("data")) { //orderData --> orderDatas is dumb
+ char secondLast = lower.charAt(name.length() - 2);
+ if (!isVowel(secondLast) && lower.endsWith("y")) {
+ // city, body etc --> cities, bodies
+ result = name.substring(0, name.length() - 1) + "ies";
+ } else if (lower.endsWith("ch") || lower.endsWith("s")) {
+ // switch --> switches or bus --> buses
+ result = name + "es";
+ } else {
+ result = name + "s";
+ }
+ }
+ }
+ return result;
+ }
+
+ public static String singularise(String name) {
+ String result = name;
+ if (seemsPluralised(name)) {
+ String lower = name.toLowerCase();
+ if (lower.endsWith("ies")) {
+ // cities --> city
+ result = name.substring(0, name.length() - 3) + "y";
+ } else if (lower.endsWith("ches") || lower.endsWith("ses")) {
+ // switches --> switch or buses --> bus
+ result = name.substring(0, name.length() - 2);
+ } else if (lower.endsWith("s")) {
+ // customers --> customer
+ result = name.substring(0, name.length() - 1);
+ }
+ }
+ return result;
+ }
+ private final static boolean isVowel(char c) {
+ boolean vowel = false;
+ vowel |= c == 'a';
+ vowel |= c == 'e';
+ vowel |= c == 'i';
+ vowel |= c == 'o';
+ vowel |= c == 'u';
+ vowel |= c == 'y';
+ return vowel;
+ }
+ private static boolean seemsPluralised(String name) {
+ name = name.toLowerCase();
+ boolean pluralised = false;
+ pluralised |= name.endsWith("es");
+ pluralised |= name.endsWith("s");
+ pluralised &= !(name.endsWith("ss") || name.endsWith("us"));
+ return pluralised;
+ }
+
+ /**
+ * Returns the package name of a class name.
+ * For example if given <code>oracle.util.ObjectUtil</code> it would return
+ * <code>oracle.util</code>. If the class is not in a package then null is returned.
+ */
+ public static String getPackageName(String className) {
+ if(className == null) {
+ return null;
+ }
+ int lastDotIndex = className.lastIndexOf('.');
+ if (lastDotIndex < 0)
+ return null;
+ return className.substring(0, lastDotIndex);
+ }
+ /**
+ * Returns the class name given a full class name.
+ * For example if given <code>oracle.util.ObjectUtil</code> it would return
+ * <code>ObjectUtil</code>
+ */
+ public static String getClassName(String fullClassName) {
+ if(fullClassName == null) {
+ return null;
+ }
+ int lastDotIndex = fullClassName.lastIndexOf('.');
+ if (lastDotIndex < 0)
+ return fullClassName;
+ return fullClassName.substring(lastDotIndex+1);
+ }
+
+
+ /**
+ * Converts a database column name to a Java variable name (<em>first letter
+ * not capitalized</em>).
+ */
+ public static String columnNameToVarName(String columnName) {
+ return dbNameToVarName(columnName);
+ }
+ /**
+ * Converts a database table name to a Java variable name (<em>first letter
+ * not capitalized</em>).
+ */
+ public static String tableNameToVarName(String tableName) {
+ return dbNameToVarName(tableName);
+ }
+ /**
+ * Converts a database name (table or column) to a java name (<em>first letter
+ * not capitalized</em>). employee_name or employee-name -> employeeName
+ */
+ private static String dbNameToVarName(String s) {
+ if ("".equals(s)) {
+ return s;
+ }
+ StringBuffer result = new StringBuffer();
+
+ boolean capitalize = true;
+ boolean lastCapital = false;
+ boolean lastDecapitalized = false;
+ String p = null;
+ for (int i = 0; i < s.length(); i++) {
+ String c = s.substring(i, i + 1);
+ if ("_".equals(c) || " ".equals(c)) {
+ capitalize = true;
+ continue;
+ }
+
+ if (c.toUpperCase().equals(c)) {
+ if (lastDecapitalized && !lastCapital) {
+ capitalize = true;
+ }
+ lastCapital = true;
+ } else {
+ lastCapital = false;
+ }
+
+ if (capitalize) {
+ if (p == null || !p.equals("_")) {
+ result.append(c.toUpperCase());
+ capitalize = false;
+ p = c;
+ } else {
+ result.append(c.toLowerCase());
+ capitalize = false;
+ p = c;
+ }
+ } else {
+ result.append(c.toLowerCase());
+ lastDecapitalized = true;
+ p = c;
+ }
+
+ }
+ /*this was using StringUtil.initLower. Changed to Introspector.decapitalize so that
+ * it returns the correct bean property name when called from columnNameToVarName.
+ * This is necessary because otherwise URL would be uRL which would cause
+ * an "The property uRL is undefined for the type xx" error because
+ * Introspector.getBeanInfo (used by JavaTypeIntrospector) returns
+ * the property name as URL.*/
+ String resultStr = Introspector.decapitalize(result.toString());
+ if (resultStr.equals("class")) {
+ // "class" is illegal becauseOf Object.getClass() clash
+ resultStr = "clazz";
+ }
+ return resultStr;
+ }
+
+ /**
+ * Compare two objects. If both String, ignore case
+ * @param o1
+ * @param o2
+ * @param ignoreCaseIfStr
+ * @return
+ */
+ public static boolean equalObjects(Object o1, Object o2, boolean ignoreCaseIfStr)
+ {
+ if (o1 == o2) {
+ return true;
+ }
+ boolean result;
+ if (o1 == null || o2 == null) {
+ return false; //we already checked o1 == o2 above
+ }
+ if (ignoreCaseIfStr && o1 instanceof String && o2 instanceof String)
+ result = ((String)o1).equalsIgnoreCase((String)o2);
+ else
+ result = o1.equals(o2);
+
+ return result;
+ }
+
+ public static boolean equalObjects(Object o1, Object o2)
+ {
+ return equalObjects(o1, o2, false/*ignoreCaseIfStr*/);
+ }
+
+}
+
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/UrlUtil.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/UrlUtil.java
new file mode 100644
index 0000000000..f6b5276726
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal2/util/UrlUtil.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.gen.internal2.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Bundle;
+
+/**
+ * Collections of utility methods handling URLs.
+ *
+ */
+public class UrlUtil
+{
+ /**
+ * The <code>file</code> string indicating a url file protocol.
+ */
+ public static final String FILE_PROTOCOL = "file";
+ /**
+ * The <code>file</code> string indicating a url http protocol.
+ */
+ public static final String HTTP_PROTOCOL = "http";
+ /**
+ * The <code>file</code> string indicating a url http protocol.
+ */
+ public static final String HTTPS_PROTOCOL = "https";
+ /**
+ * The <code>file</code> string indicating a url file protocol.
+ */
+ public static final String JAR_PROTOCOL = "jar";
+
+
+ /**
+ * Returns true if the specified url is to a file, i.e its protocol is <code>file</code>.
+ */
+ public static boolean isFileUrl(URL url) {
+ return url != null && FILE_PROTOCOL.equals(url.getProtocol());
+ }
+ /**
+ * Returns true if the specified url is to a jar, i.e its protocol is <code>jar</code>.
+ * For example <code>jar:file:/C:/testapps/example/WEB-INF/lib/struts.jar!/META-INF/tlds/struts-bean.tld</code>.
+ */
+ public static boolean isJarUrl(URL url) {
+ return url != null && JAR_PROTOCOL.equals(url.getProtocol());
+ }
+ /**
+ * Returns true if the specified url protocol is http.
+ */
+ public static boolean isHttpUrl(URL url) {
+ String protocol = url.getProtocol();
+ return url != null && (HTTP_PROTOCOL.equals(protocol) || HTTPS_PROTOCOL.equals(protocol));
+ }
+ /**
+ * Returns the <code>File</code> corresponding to a url, or null if the url
+ * protocol is not file.
+ */
+ public static java.io.File getUrlFile(URL url) {
+ if (isFileUrl(url) && !isJarUrl( url ) ){
+ File ret = new java.io.File(url.getFile());
+ return ret ;
+ }
+ return null;
+ }
+
+
+ /**
+ * Returns the url to a jar file given a url to a file inside
+ * the jar.
+ * For example if given
+ * <code>jar:file:/C:/testapps/example/WEB-INF/lib/struts.jar!/META-INF/tlds/struts-bean.tld</code>
+ * this method returns <code>file:/C:/testapps/example/WEB-INF/lib/struts.jar</code>.
+ *
+ * <p>Returns null if the given url is not recognized as a url to a file
+ * inside a jar.
+ */
+ public static URL getJarFileUrl(URL url) {
+ if (!isJarUrl(url)) {
+ return null;
+ }
+ String file = url.getFile(); //file:/C:/testapps/example/WEB-INF/lib/struts.jar!/META-INF/tlds/struts-bean.tld
+ int index = file.indexOf('!');
+ if (index < 0) {
+ return null;
+ }
+ String jarFileUrlStr = file.substring(0, index);
+ try {
+ return new URL(jarFileUrlStr);
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ public static boolean isRemote(String url){
+ return url.startsWith("http:")||url.startsWith("https:")||url.startsWith("www.");
+ }
+
+ public static File getTemplateFolder(String plugId , String strPath ){
+ Bundle bundle = Platform.getBundle( plugId );
+ Path path = new Path( strPath );
+ URL url = FileLocator.find(bundle, path, null);
+ try {
+ URL templUrl;
+ templUrl = FileLocator.resolve(url);
+ File templDir = UrlUtil.getUrlFile(templUrl);
+ return templDir ;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/column.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/column.vm
new file mode 100644
index 0000000000..8bb49108b2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/column.vm
@@ -0,0 +1,52 @@
+##included template. Generates the @Column annotation.
+##Assumes that the context has a "column" and a "table" object
+##generate annotation only the parameters for the column NOT default
+##and the generateDLLAnnotation property is not set on the table
+###------------------------------------------------
+#macro( append $members $parameters )
+#if( $members == "")
+#set( $members = $parameters )
+#else
+#set( $members = "$members, $parameters" )
+#end
+#end
+###------------------------------------------------
+#if ( $column.dataTypeLOB)
+ @Lob()
+#end
+#if ( $column.needMapTemporalType)
+ @Temporal( TemporalType.$column.temporalType)
+#end
+#set ($members = "")
+#if ( !$column.default || $table.generateDDLAnnotations )
+#set ($members = "name=$customizer.quote($column.name)")
+#if (!$column.insertable)
+#set ($members = "$members, insertable=false")
+#end
+#if (!$column.updateable)
+#set ($members = "$members, updatable=false")
+#end
+#end
+#if( $table.generateDDLAnnotations )
+#if ($column.unique)
+#append($members "unique=true")
+#end
+#if (!$column.nullable)
+#append($members "nullable=false")
+#end
+#if ($column.size > 0)
+#if ($column.numeric)
+#append($members "precision=$column.size")
+#if ($column.decimalDigits != 0 && $column.decimalDigits != -1)
+#append($members "scale=$column.decimalDigits")
+#end
+#else
+#if ( !$column.dataTypeLOB)
+#append($members "length=$column.size")
+#end
+#end
+#end
+#end
+#if( $members !="" )
+ @Column($members)
+#end
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/join.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/join.vm
new file mode 100644
index 0000000000..ece3ff4c3f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/join.vm
@@ -0,0 +1,61 @@
+##included template. Generates the @JoinTable, @JoinColumn or @JoinColumns annotation.
+##Assumes that the context has a "role" object representing the generated AssociationRole
+##
+##macro joinColumn uses $column, $referencedColumn
+#macro (joinColumn $column $referencedColumn)
+#set ($members = "name=$customizer.quote($column.joinColumnName)")
+#if( !$referencedColumn.primaryKey )
+#set ($members = "$members, referencedColumnName=$customizer.quote($referencedColumn.name)")
+#end
+#if( $table.generateDDLAnnotations )
+#if ($column.unique && !$column.primaryKey)
+#set ($members = "$members, unique=true")
+#end
+#if (!$column.nullable)
+#set ($members = "$members, nullable=false")
+#end
+#end
+#if (!$role.association.joinTable && !$role.referrerTable.isColumnUpdateInsert($role, $column))
+#set ($members = "$members, insertable=false, updatable=false")
+#end
+@JoinColumn($members)#end
+##
+##
+##
+#if ($role.association.joinTable)
+#set ($joinTable = $role.association.joinTable)
+ @JoinTable(
+ name="${joinTable.joinTableAnnotationName}"
+#if ($joinTable.schema!="")
+ , schema="${joinTable.schema}"
+#end
+ , joinColumns={
+#foreach ($column in $role.referrerColumns)
+#set ($referencedColumn = $role.getReferencedColumn(${column.name}))
+##$referencedColumn is the column in the join table
+ #joinColumn($referencedColumn $column),
+#end
+ }
+ , inverseJoinColumns={
+#foreach ($column in $role.referencedColumns)
+#set ($referencedColumn = $role.getReferrerColumn(${column.name}))
+##$referencedColumn is the column in the join table
+ #joinColumn($referencedColumn $column),
+#end
+ }
+ )
+#else
+#if ($role.referrerColumns.size() == 1)
+#set ($column = $role.referrerColumns.get(0))
+#set ($referencedColumn = $role.getReferencedColumn(${column.name}))
+ #joinColumn($column $referencedColumn)
+
+#else
+ @JoinColumns({
+#foreach ($column in $role.referrerColumns)
+#set ($referencedColumn = $role.getReferencedColumn(${column.name}))
+ #joinColumn($column $referencedColumn),
+#end
+ })
+#end
+#end \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/main.java.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/main.java.vm
new file mode 100644
index 0000000000..28c861c844
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/main.java.vm
@@ -0,0 +1,129 @@
+#if ($table.package != "")
+package ${table.package};
+#end
+import java.io.Serializable;
+import javax.persistence.*;
+
+/**
+ * The persistent class for the ${table.name} database table.
+ *
+ */
+@Entity
+@Table(name="${table.name}")
+public class ${table.className} ${table.generateExtendsImplements()} {
+ private static final long serialVersionUID = 1L;
+#####
+##### fields
+#####
+#if ($table.compositeKey)
+#if ($table.access == "field")
+
+ @EmbeddedId
+#end
+ private ${table.compositeKeyClassName} ${table.compositeKeyPropertyName};
+#end
+#foreach ($column in $table.getSimpleColumns(true, true, false))
+#if ($table.access == "field")
+
+#parse("mappingKind.vm")
+#parse("column.vm")
+#end
+ ${column.fieldScope} ${column.propertyType} ${column.propertyName};
+#end
+#foreach ($role in $table.associationRoles)
+#####
+##### field annotations
+#####
+#if ($table.access == "field")
+
+ //${role.description}
+#if ($role.cardinality == "many-to-one")
+#parse("manyToOne.vm")
+#elseif ($role.cardinality == "many-to-many")
+#parse("manyToMany.vm")
+#elseif ($role.cardinality == "one-to-many")
+#parse("oneToMany.vm")
+#elseif ($role.cardinality == "one-to-one")
+#parse("oneToOne.vm")
+#end
+#end
+#####
+##### field declaration
+#####
+#if ($role.cardinality == "many-to-one" || $role.cardinality == "one-to-one")
+#set ($propertyType = ${role.referencedTable.className})
+#elseif ($role.cardinality == "many-to-many" || $role.cardinality == "one-to-many")
+#set ($propertyType = "${role.referencedTable.defaultCollectionType}<${role.referencedTable.className}>")
+#end
+ private $propertyType $role.propertyName;
+#end
+
+ public ${table.className}() {
+ }
+#####
+##### simple properties getters and setters
+#####
+#if ($table.compositeKey)
+#if ($table.access == "property")
+
+ @EmbeddedId
+#end
+ public $table.compositeKeyClassName $customizer.propertyGetter($table.compositeKeyPropertyName)() {
+ return this.${table.compositeKeyPropertyName};
+ }
+
+ public void $customizer.propertySetter($table.compositeKeyPropertyName)($table.compositeKeyClassName $table.compositeKeyPropertyName) {
+ this.${table.compositeKeyPropertyName} = ${table.compositeKeyPropertyName};
+ }
+
+#end
+#foreach ($column in $table.getSimpleColumns(true, true, false))
+#if ($table.access == "property")
+
+#parse("mappingKind.vm")
+#parse("column.vm")
+#end
+ $column.propertyGetScope $column.propertyType $customizer.propertyGetter($column.propertyName)() {
+ return this.${column.propertyName};
+ }
+
+ $column.propertySetScope void $customizer.propertySetter($column.propertyName)($column.propertyType $column.propertyName) {
+ this.${column.propertyName} = ${column.propertyName};
+ }
+
+#end
+#####
+##### associations getters and setters
+#####
+#foreach ($role in $table.associationRoles)
+#if ($table.access == "property")
+
+ //${role.description}
+#if ($role.cardinality == "many-to-one")
+#parse("manyToOne.vm")
+#elseif ($role.cardinality == "many-to-many")
+#parse("manyToMany.vm")
+#elseif ($role.cardinality == "one-to-many")
+#parse("oneToMany.vm")
+#elseif ($role.cardinality == "one-to-one")
+#parse("oneToOne.vm")
+#end
+#end
+##
+#if ($role.cardinality == "many-to-one" || $role.cardinality == "one-to-one")
+#set ($propertyType = $role.referencedTable.className)
+#elseif ($role.cardinality == "many-to-many" || $role.cardinality == "one-to-many")
+#set ($propertyType = "${role.referencedTable.defaultCollectionType}<${role.referencedTable.className}>")
+#end
+ public $propertyType $customizer.propertyGetter($role.propertyName)() {
+ return this.${role.propertyName};
+ }
+
+ public void ${customizer.propertySetter($role.propertyName)}($propertyType $role.propertyName) {
+ this.${role.propertyName} = $role.propertyName;
+ }
+
+##
+#end
+##
+} \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToMany.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToMany.vm
new file mode 100644
index 0000000000..fe3bfedd8b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToMany.vm
@@ -0,0 +1,14 @@
+##included template. Generates the @ManyToMany annotation.
+##Assumes that the context has a "role" object representing the generated AssociationRole
+##
+#if ($role.association.bidirectional && !$role.isReferrerRole())##the owning side (either side for many-to-many)
+#set ($members = $customizer.appendAnnotation("", "mappedBy", $role.oppositeRole.propertyName, true))
+#set ($members = $customizer.appendAnnotation($members, "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @ManyToMany($members)
+#else
+#set ($members = $customizer.appendAnnotation("", "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @ManyToMany($members)
+#parse("join.vm")
+#end \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToOne.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToOne.vm
new file mode 100644
index 0000000000..8253462972
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/manyToOne.vm
@@ -0,0 +1,7 @@
+##included template. Generates the @ManyToOne annotation.
+##Assumes that the context has a "role" object representing the generated AssociationRole
+##
+#set ($members = $customizer.appendAnnotation("", "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @ManyToOne($members)
+#parse("join.vm") \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/mappingKind.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/mappingKind.vm
new file mode 100644
index 0000000000..4bc95386e3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/mappingKind.vm
@@ -0,0 +1,30 @@
+##included template. Generates the @Basic, @Id, @Version annotations.
+##Assumes that the context has a "column" object
+##
+#set ($mappingKind = $column.mappingKind)
+#if ($mappingKind == "id")
+ @Id
+#set ($idGenerator = $table.idGenerator)
+#if ($idGenerator == "auto")
+#set ($generationType = "GenerationType.AUTO")
+#elseif ($idGenerator == "identity")
+#set ($generationType = "GenerationType.IDENTITY")
+#elseif ($idGenerator == "sequence")
+#set ($generationType = "GenerationType.SEQUENCE")
+#elseif ($idGenerator == "table")
+#set ($generationType = "GenerationType.TABLE")
+#else
+#set ($generationType = "")
+#end
+#if ($idGenerator == "sequence" || ($idGenerator == "auto" && $table.sequence))
+#set ($generatorName = "${table.name.toUpperCase()}_${column.propertyName.toUpperCase()}_GENERATOR")
+ @SequenceGenerator(name="$generatorName", sequenceName="$table.formattedSequence")
+ @GeneratedValue(strategy=$generationType, generator="$generatorName")
+#elseif ($generationType != "")
+ @GeneratedValue(strategy=$generationType)
+#end
+#elseif ($mappingKind == "version")
+ @Version()
+#else
+##DEFAULT is @Basic(), no need to generate
+#end \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToMany.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToMany.vm
new file mode 100644
index 0000000000..bb89d5b885
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToMany.vm
@@ -0,0 +1,14 @@
+##included template. Generates the @OneToMany annotation.
+##Assumes that the context has a "role" object representing the generated AssociationRole
+##
+#if ($role.association.bidirectional)
+#set ($members = $customizer.appendAnnotation("", "mappedBy", $role.oppositeRole.propertyName, true))
+#set ($members = $customizer.appendAnnotation($members, "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @OneToMany($members)
+#else
+#set ($members = $customizer.appendAnnotation("", "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @OneToMany($members)
+#parse("join.vm")
+#end \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToOne.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToOne.vm
new file mode 100644
index 0000000000..862c967802
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/oneToOne.vm
@@ -0,0 +1,14 @@
+##included template. Generates the @OneToOne annotation.
+##Assumes that the context has a "role" object representing the generated AssociationRole
+##
+#if ($role.association.bidirectional && !$role.isReferrerRole())##the owning side (either side for one-to-one)
+#set ($members = $customizer.appendAnnotation("", "mappedBy", $role.oppositeRole.propertyName, true))
+#set ($members = $customizer.appendAnnotation($members, "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @OneToOne($members)
+#else
+#set ($members = $customizer.appendAnnotation("", "cascade", $customizer.genCascades($role), false))
+#set ($members = $customizer.appendAnnotation($members, "fetch", $customizer.genFetch($role.referrerTable), false))
+ @OneToOne($members)
+#parse("join.vm")
+#end \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/templates/entities/pk.java.vm b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/pk.java.vm
new file mode 100644
index 0000000000..780037e8a9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.gen/templates/entities/pk.java.vm
@@ -0,0 +1,65 @@
+#if ($table.package != "")
+package ${table.package};
+#end
+import java.io.Serializable;
+import javax.persistence.*;
+
+/**
+ * The primary key class for the ${table.name} database table.
+ *
+ */
+@Embeddable()
+public class ${table.compositeKeyClassName} implements Serializable {
+ //default serial version id, required for serializable classes.
+ private static final long serialVersionUID = 1L;
+#####
+##### fields
+#####
+#foreach ($column in $table.primaryKeyColumns)
+#if ($table.access == "field")
+
+#parse("column.vm")
+#end
+ ${column.fieldScope} ${column.propertyType} ${column.propertyName};
+#end
+
+ public ${table.compositeKeyClassName}() {
+ }
+#####
+##### simple properties getters and setters
+#####
+#foreach ($column in $table.primaryKeyColumns)
+#if ($table.access == "property")
+
+#parse("column.vm")
+#end
+ $column.propertyGetScope $column.propertyType $customizer.propertyGetter($column.propertyName)() {
+ return this.${column.propertyName};
+ }
+ $column.propertySetScope void $customizer.propertySetter($column.propertyName)($column.propertyType $column.propertyName) {
+ this.${column.propertyName} = ${column.propertyName};
+ }
+#end
+##
+## equals/hashCode
+
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof ${table.compositeKeyClassName})) {
+ return false;
+ }
+ ${table.compositeKeyClassName} castOther = (${table.compositeKeyClassName})other;
+ return
+ ${table.primaryKeyEqualsClause}
+
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int hash = 17;
+ ${table.primaryKeyHashCodeClause}
+ return hash;
+ }
+} \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
index fc2248781b..d1585a5ef4 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
+++ b/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
@@ -43,7 +43,8 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)",
org.eclipse.wst.common.project.facet.core;bundle-version="[1.3.0,2.0.0)",
org.eclipse.wst.common.project.facet.ui;bundle-version="[1.3.0,2.0.0)",
org.eclipse.wst.sse.ui;bundle-version="[1.1.0,1.2.0)",
- org.eclipse.wst.web.ui;bundle-version="[1.1.200,2.0.0)"
+ org.eclipse.wst.web.ui;bundle-version="[1.1.200,2.0.0)",
+ org.eclipse.gef;bundle-version="[3.5.0,4.0.0)"
Export-Package: org.eclipse.jpt.ui,
org.eclipse.jpt.ui.details,
org.eclipse.jpt.ui.internal;x-internal:=true,
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gif b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gif
new file mode 100644
index 0000000000..864034f74e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.png
new file mode 100644
index 0000000000..6bd3486b7a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.png
new file mode 100644
index 0000000000..1f64f24965
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.png
new file mode 100644
index 0000000000..8081fd9293
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.png
new file mode 100644
index 0000000000..3582d18d5b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.png
new file mode 100644
index 0000000000..afba8b4463
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.png
new file mode 100644
index 0000000000..49544f5703
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gif b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gif
new file mode 100644
index 0000000000..57a514d649
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.png
new file mode 100644
index 0000000000..306d6a1c5f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.png
new file mode 100644
index 0000000000..db729a3990
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.png
new file mode 100644
index 0000000000..8081fd9293
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.png
new file mode 100644
index 0000000000..f6e5281b70
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.png
new file mode 100644
index 0000000000..7c8b1ccf79
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.png
new file mode 100644
index 0000000000..df009468ab
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.png
new file mode 100644
index 0000000000..2d74ae4e01
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.png
new file mode 100644
index 0000000000..4eaff2beab
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.png
new file mode 100644
index 0000000000..a7b471c2d3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.png
new file mode 100644
index 0000000000..0751b3267c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.png
new file mode 100644
index 0000000000..5fb4dc2a2c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.png
new file mode 100644
index 0000000000..abfffe4bc7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.png
new file mode 100644
index 0000000000..caa828d3c0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.png
new file mode 100644
index 0000000000..bd7414470c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.png
new file mode 100644
index 0000000000..468a09b5de
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.png
new file mode 100644
index 0000000000..ee15ba107e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.png
new file mode 100644
index 0000000000..d84b339401
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.png
new file mode 100644
index 0000000000..fa25df32e8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.png
new file mode 100644
index 0000000000..a58c953f1a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.png
new file mode 100644
index 0000000000..585ed6a9e4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.png
new file mode 100644
index 0000000000..ccabb96f5c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.png
new file mode 100644
index 0000000000..c483a49336
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gif
new file mode 100644
index 0000000000..5f1551ba96
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gif
new file mode 100644
index 0000000000..4f385155d6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/file.png b/jpa/plugins/org.eclipse.jpt.ui/images/objects/file.png
new file mode 100644
index 0000000000..f5c1810a63
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/file.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.png b/jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.png
new file mode 100644
index 0000000000..9759da4e20
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gif
new file mode 100644
index 0000000000..562bd70b5c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gif
new file mode 100644
index 0000000000..7a1511dd8e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/package.png b/jpa/plugins/org.eclipse.jpt.ui/images/objects/package.png
new file mode 100644
index 0000000000..471cc4367d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/package.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gif
new file mode 100644
index 0000000000..a99388a9af
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gif
new file mode 100644
index 0000000000..e2ccabb383
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gif b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gif
new file mode 100644
index 0000000000..119dcccd5a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.png b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.png
new file mode 100644
index 0000000000..8c1e86c479
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.png b/jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.png
new file mode 100644
index 0000000000..eca4774fec
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/plugin.properties b/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
index 377baeecf2..18ce474a46 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
+++ b/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
@@ -33,6 +33,8 @@ newJpaEntityWizardName = Entity
newJpaEntityWizardDesc = Create a JPA Entity
newJpaMappingFileWizardName = Mapping File
newJpaMappingFileWizardDesc = Create a JPA Mapping File
+newJpaEntityFromTableWizardName = Entities From Tables
+newJpaEntityFromTableWizardDesc = Create JPA Entities from database tables
jpaStructureViewCommandCategory = JPA Structure View
addPersistentClass = Add Class ...
diff --git a/jpa/plugins/org.eclipse.jpt.ui/plugin.xml b/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
index 3d6f7ab3fd..597cb1bbb7 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
+++ b/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
@@ -541,6 +541,30 @@
-->
+ <commonWizard
+ menuGroupId="org.eclipse.jpt.ui"
+ type="new"
+ wizardId="org.eclipse.jpt.ui.wizard.newEntitiesFromTables">
+ <enablement>
+ <and>
+ <or>
+ <instanceof
+ value="org.eclipse.core.resources.IProject"/>
+ <instanceof
+ value="org.eclipse.jdt.core.IPackageFragment"/>
+ <instanceof
+ value="org.eclipse.jdt.core.IPackageFragmentRoot"/>
+ </or>
+ <adapt type="org.eclipse.core.resources.IResource">
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.wst.common.project.facet.core.projectFacet"
+ value="jpt.jpa" />
+ </adapt>
+ </and>
+ </enablement>
+ </commonWizard>
+
</navigatorContent>
</extension>
@@ -581,6 +605,16 @@
</wizard>
<wizard
+ category="org.eclipse.jpt"
+ class="org.eclipse.jpt.ui.internal.wizards.gen.GenerateEntitiesFromSchemaWizard"
+ icon="platform:/plugin/org.eclipse.jpt.ui/icons/full/etool16/new_entity_wiz.gif"
+ id="org.eclipse.jpt.ui.wizard.newEntitiesFromTables"
+ name="%newJpaEntityFromTableWizardName">
+ <description>%newJpaEntityFromTableWizardDesc</description>
+ <selection class="org.eclipse.core.resources.IResource"/>
+ </wizard>
+
+ <wizard
id="org.eclipse.jpt.ui.wizard.newMappingFile"
name="%newJpaMappingFileWizardName"
icon="icons/full/etool16/new_jpa_file_wiz.gif"
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties
new file mode 100644
index 0000000000..9b8c42a7da
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties
@@ -0,0 +1,128 @@
+###############################################################################
+# Copyright (c) 2006, 2008 Oracle. All rights reserved.
+# This program and the accompanying materials are made available under the terms of
+# the Eclipse Public License v1.0, which accompanies this distribution and is available at
+# http://www.eclipse.org/legal/epl-v10.html.
+#
+# Contributors:
+# Oracle - initial API and implementation
+###############################################################################
+
+cardinality=Car&dinality:
+property=P&roperty:
+cascade=&Cascade:
+databaseSettings=Database Settings
+connection=&Connection:
+schema=&Schema:
+schemaInfo=(Note: You must have an active connection to select schema.)
+addConnectionLink=Add connections...
+reconnectLink=Reconnect...
+connectLink=Connect
+connectingMessage=Connecting...
+manyToOne=&Many to one
+manyToMany=Man&y to many
+oneToMany=&One to many
+oneToOne=&One to one
+manyToOneDesc=Each %s has many %s.
+oneToOneDesc=There is one %s per %s.
+manyToManyDesc=Each %s has many %s, and each %s has many %s.
+
+add=&Add
+remove=&Remove
+browse=B&rowse...
+
+showInSchemaViewer=Show in Schema Viewer
+showInEntityEditor=Show in Entity Relationship Editor
+
+GenerateEntitiesWizard_generateEntities=Generate Custom Entities
+
+GenerateEntitiesWizard_selectJPAProject=JPA Project Selection
+GenerateEntitiesWizard_selectJPAProject_msg=Select a JPA project.
+GenerateEntitiesWizard_selectJPAProject_label=JPA projects in the workspace:
+
+GenerateEntitiesWizard_tableSelectPage_selectTable=Select Tables
+GenerateEntitiesWizard_tableSelectPage_chooseEntityTable=Select tables to generate entities from.
+GenerateEntitiesWizard_tableSelectPage_synchronizeClasses=Synchronize classes listed in persistence.xml
+GenerateEntitiesWizard_tableSelectPage_copyJdbcDrive = Add JDBC driver to project classpath
+GenerateEntitiesWizard_tableSelectPage_tables=&Tables:
+GenerateEntitiesWizard_tableSelectPage_tableColumn=Table
+
+GenerateEntitiesWizard_assocPage_title=Table Associations
+GenerateEntitiesWizard_assocPage_label=Table &associations
+GenerateEntitiesWizard_assocPage_desc=Edit a table association by selecting it and modifying the controls in the editing panel.
+GenerateEntitiesWizard_assocPage_newAssoc=New Association
+GenerateEntitiesWizard_assocPage_delAssoc=Delete Selected Association
+
+
+GenerateEntitiesWizard_defaultTablePage_title=Customize Default Entity Generation
+GenerateEntitiesWizard_defaultTablePage_tableMapping=Table Mapping
+GenerateEntitiesWizard_defaultTablePage_domainJavaClass=Domain Java Class
+
+GenerateEntitiesWizard_defaultTablePage_desc=Optionally customize aspects of entities that will be generated by default from database tables. A Java package should be specified.
+GenerateEntitiesWizard_defaultTablePage_access=Entity &access:
+GenerateEntitiesWizard_defaultTablePage_fetch=Associations &fetch:
+GenerateEntitiesWizard_defaultTablePage_collType=Collection properties &type:
+GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations = Always generate optional JPA annotations and DDL parameters
+GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc = Generate optional JPA annotations and DDL parameters like 'unique', 'nullable', 'length', 'precision' and 'scale', which are optional and only used by automatic table creation to specify table creation data.
+GenerateEntitiesWizard_defaultTablePage_keyGen=Key &generator:
+GenerateEntitiesWizard_defaultTablePage_sequence=Sequence &name:
+GenerateEntitiesWizard_defaultTablePage_sequenceNote=You can use the patterns %s and/or %s in the sequence name.\n\
+ These patterns will be replaced by the table name and the primary key \n\
+ column name when a table mapping is generated.
+GenerateEntitiesWizard_defaultTablePage_package=Java Package *:
+GenerateEntitiesWizard_defaultTablePage_baseClass=Base Class:
+GenerateEntitiesWizard_defaultTablePage_interfaces=Interfaces:
+GenerateEntitiesWizard_defaultTablePage_chooseInterfaces=Choose Class Interfaces
+
+GenerateEntitiesWizard_tablesAndColumnsPage_title=Customize Individual Entities
+GenerateEntitiesWizard_tablesAndColumnsPage_desc=Customize detail of individual entities by selecting the associated tables or columns and changing values in the editing panel.
+GenerateEntitiesWizard_tablesAndColumnsPage_labelTableAndColumns=&Tables and columns
+GenerateEntitiesWizard_tablesAndColumnsPage_tableMapping=Table Mapping
+GenerateEntitiesWizard_tablesAndColumnsPage_columnMapping=Column Mapping
+
+GenerateEntitiesWizard_tablePanel_className=&Class name:
+GenerateEntitiesWizard_tablePanel_implementEq=Implement equals/hashCode
+GenerateEntitiesWizard_colPanel_genProp=Generate this property
+GenerateEntitiesWizard_colPanel_colMapping=Column mapping
+GenerateEntitiesWizard_colPanel_propName=Property &name:
+GenerateEntitiesWizard_colPanel_propType=Mapping t&ype:
+GenerateEntitiesWizard_colPanel_mapKind=Mapping &kind:
+GenerateEntitiesWizard_colPanel_beanProp=Domain Java Class
+GenerateEntitiesWizard_colPanel_getterScope=Getter Scope:
+GenerateEntitiesWizard_colPanel_setterScope=Setter Scope:
+GenerateEntitiesWizard_colPanel_colUpdateable=Column is &updatable
+GenerateEntitiesWizard_colPanel_colInsertable=Column is &insertable
+GenerateEntitiesWizard_colPanel_useInToString=Use in toString
+GenerateEntitiesWizard_colPanel_useInEquals=Use in equals/hashCode
+
+GenerateEntitiesWizard_newAssoc_title=Create New Association
+GenerateEntitiesWizard_newAssoc_exists=A similar association between %s and %s already exists.
+
+GenerateEntitiesWizard_newAssoc_tablesPage_title=Association Tables
+GenerateEntitiesWizard_newAssoc_tablesPage_desc=Specify the association tables.
+GenerateEntitiesWizard_tablesSelPage_newConn=New...
+GenerateEntitiesWizard_newAssoc_tablesPage_assocKind=Association Kind
+GenerateEntitiesWizard_newAssoc_tablesPage_assocTables=Association &tables:
+GenerateEntitiesWizard_newAssoc_tablesPage_table1=Table &1:
+GenerateEntitiesWizard_newAssoc_tablesPage_table2=Table &2:
+GenerateEntitiesWizard_newAssoc_tablesPage_intermediateTable=Join Table:
+GenerateEntitiesWizard_newAssoc_tablesPage_simpleAssoc=&Simple association
+GenerateEntitiesWizard_newAssoc_tablesPage_m2mAssoc=&Many to many association
+
+GenerateEntitiesWizard_newAssoc_cardinalityPage_title=Association Cardinality
+GenerateEntitiesWizard_newAssoc_cardinalityPage_desc=Specify the association cardinality.
+
+GenerateEntitiesWizard_newAssoc_colsPage_title=Join Columns
+GenerateEntitiesWizard_newAssoc_colsPage_desc=Specify the join columns.
+GenerateEntitiesWizard_newAssoc_colsPage_label=Specify the join columns between the %s and %s tables:
+
+GenerateEntitiesWizard_assocEditor_entityRef=Generate a reference to %s in %s
+GenerateEntitiesWizard_assocEditor_setRef=Generate a reference to a collection of %s in %s
+GenerateEntitiesWizard_assocEditor_tableJoin=Table &join:
+GenerateEntitiesWizard_assocEditor_joinedWhen=The table rows are joined when:\n%s
+GenerateEntitiesWizard_assocEditor_genAssoc=Generate &this association
+GenerateEntitiesWizard_fileWillBeOverwritten = Note that the generated .java files will *overwrite* existing files with the same name.
+GenerateEntitiesWizard_doNotShowWarning = Don't show me this warning again
+
+GenerateEntitiesWizard_inconsistentConn=The selected connection url is different than the connection url specified in the "%s" file .
+
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/CommonImages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/CommonImages.java
new file mode 100644
index 0000000000..a0980ff0bd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/CommonImages.java
@@ -0,0 +1,101 @@
+package org.eclipse.jpt.ui;
+
+import static org.eclipse.jpt.ui.JptUiPlugin.PLUGIN_ID;
+import static org.eclipse.ui.plugin.AbstractUIPlugin.imageDescriptorFromPlugin;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+public final class CommonImages
+{
+ public static final ImageDescriptor DESC_OVERLAY_ERROR
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/overlays/error.gif" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_OVERLAY_WARNING
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/overlays/warning.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_ADD
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/add.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_EDIT
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/edit.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_DELETE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/delete.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_MOVE_UP
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/move-up.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_MOVE_DOWN
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/move-down.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_EXPAND_ALL
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/expand-all.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_COLLAPSE_ALL
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/collapse-all.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_RESTORE_DEFAULTS
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/restore-defaults.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_BROWSE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/browse.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_BROWSE_MINI
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/browse-mini.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_SELECT_ALL
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/select-all.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_BUTTON_DESELECT_ALL
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/deselect-all.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_OBJECT_FILE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/file.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_OBJECT_FOLDER
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/folder.png" ); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_OBJECT_PACKAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/package.png" ); //$NON-NLS-1$
+
+ private static Map<ImageDescriptor,Image> cache = new HashMap<ImageDescriptor,Image>();
+
+ public static ImageDescriptor ADD_CONNECTION_IMAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/add-connection.gif" ); //$NON-NLS-1$
+
+ public static ImageDescriptor RECONNECT_IMAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/buttons/reconnect.png" ); //$NON-NLS-1$
+
+ public static ImageDescriptor TABLE_IMAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/table.gif" ); //$NON-NLS-1$
+
+ public static ImageDescriptor TABLE_OBJ_IMAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/table_obj.gif" ); //$NON-NLS-1$
+
+ public static ImageDescriptor COLUMN_IMAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/column.gif" ); //$NON-NLS-1$
+
+ public static ImageDescriptor COLUMN_KEY_IMAGE
+ = imageDescriptorFromPlugin( PLUGIN_ID, "images/objects/columnKey.gif" ); //$NON-NLS-1$
+
+ public static Image createImage( final ImageDescriptor descriptor )
+ {
+ synchronized( cache )
+ {
+ Image image = cache.get( descriptor );
+
+ if( image == null )
+ {
+ image = descriptor.createImage();
+ cache.put( descriptor, image );
+ }
+
+ return image;
+ }
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/TestJunk.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/TestJunk.java
new file mode 100644
index 0000000000..301487752b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/TestJunk.java
@@ -0,0 +1,59 @@
+package org.eclipse.jpt.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.persistence.ClassRef;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.internal.context.GenericRootContextNode;
+
+public class TestJunk {
+
+// public static List<PersistentType> entities(JpaProject jpaProject) {
+// List<PersistentType> entities = new ArrayList<PersistentType>();
+// //this is a place where our provisional api needs to change, I
+// //had to cast to an internal class.
+//
+// //You'll want null checks in here in cases of persistence.xml
+// //file not being complete
+// //Also, we only support 1 persistenceUnit in the implementation,
+// //you should verify there is at least one
+// PersistenceUnit persistenceUnit =
+// rootContext.persistenceXml().getPersistence().persistenceUnits().next();
+//
+// for (Iterator<ClassRef> classRefs = persistenceUnit.classRefs();
+// classRefs.hasNext();) {
+// ClassRef classRef = classRefs.next();
+// if (classRef.getJavaPersistentType() != null) { //null if
+//// there is no java class with this name)
+// if (classRef.getJavaPersistentType().mappingKey() ==
+// MappingKeys.ENTITY_TYPE_MAPPING_KEY) {
+// entities.add(classRef.getJavaPersistentType());
+// }
+// }
+// }
+// //to get entities from orm.xml files
+//// for (Iterator<MappingFileRef> mappingFiles =
+//// persistenceUnit.mappingFileRefs(); mappingFiles.hasNext();) {
+//// MappingFileRef mappingFileRef = mappingFiles.next();
+//// //null checks needed here for OrmXml as well as EntityMappings
+//// EntityMappings entityMappings =
+//// mappingFileRef.getOrmXml().getEntityMappings();
+//// for (Iterator<OrmPersistentType> persistentTypes =
+//// entityMappings.ormPersistentTypes(); persistentTypes.hasNext();) {
+//// OrmPersistentType ormPersistentType =
+//// persistentTypes.next();
+//// if (ormPersistentType.mappingKey() ==
+//// MappingKeys.ENTITY_TYPE_MAPPING_KEY) {
+//// entities.add(ormPersistentType);
+//// }
+//// }
+//// }
+//
+// return entities;
+// }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java
index 20bd1c2bfe..4b024f655c 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java
@@ -284,7 +284,8 @@ public abstract class BaseJpaPlatformUi
// ********** entity generation **********
public void generateEntities(JpaProject project, IStructuredSelection selection) {
- EntitiesGenerator.generate(project, selection);
+ //EntitiesGenerator.generate(project, selection);
+ EntitiesGenerator2.generate(project, selection);
}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator2.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator2.java
new file mode 100644
index 0000000000..5eb9f0eddd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator2.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal.platform.base;
+
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.wizards.gen.GenerateEntitiesFromSchemaWizard;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * EntitiesGenerator
+ */
+public class EntitiesGenerator2 {
+ private JpaProject project;
+ private IStructuredSelection selection;
+
+ public static void generate(JpaProject project, IStructuredSelection selection) {
+ new EntitiesGenerator2(project, selection).generate();
+ }
+
+ private EntitiesGenerator2(JpaProject project, IStructuredSelection selection) {
+ super();
+ if (project == null) {
+ throw new NullPointerException();
+ }
+ this.project = project;
+ this.selection = selection;
+ }
+
+
+ // ********** generate **********
+
+ /**
+ * prompt the user with a wizard;
+ * schedule a job to generate the entities;
+ * optionally schedule a job to synchronize persistence.xml to
+ * run afterwards
+ */
+ protected void generate() {
+ GenerateEntitiesFromSchemaWizard wizard = new GenerateEntitiesFromSchemaWizard(this.project, this.selection);
+ WizardDialog dialog = new WizardDialog(this.getCurrentShell(), wizard);
+ dialog.create();
+ int returnCode = dialog.open();
+ if (returnCode != Window.OK) {
+ return;
+ }
+ //Entities generation happens in the GenerateEntitiesFromSchemaWizard.performFinish()
+ //method
+ }
+
+ private Shell getCurrentShell() {
+ return Display.getCurrent().getActiveShell();
+ }
+
+ // ********** overwrite confirmer **********
+
+ static class OverwriteConfirmer implements org.eclipse.jpt.gen.internal2.OverwriteConfirmer {
+ private Shell shell;
+ private boolean overwriteAll = false;
+ private boolean skipAll = false;
+
+ OverwriteConfirmer(Shell shell) {
+ super();
+ this.shell = shell;
+ }
+
+ public boolean overwrite(final String className) {
+ if (this.overwriteAll) {
+ return true;
+ }
+ if (this.skipAll) {
+ return false;
+ }
+ return this.promptUser(className);
+ }
+
+ private boolean promptUser(String className) {
+ final OverwriteConfirmerDialog dialog = new OverwriteConfirmerDialog(this.shell, className);
+ // get on the UI thread synchronously, need feedback before continuing
+ this.shell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ dialog.open();
+ }
+ });
+ if (dialog.getReturnCode() == Window.CANCEL) {
+ throw new OperationCanceledException();
+ }
+ if (dialog.yes()) {
+ return true;
+ }
+ if (dialog.yesToAll()) {
+ this.overwriteAll = true;
+ return true;
+ }
+ if (dialog.no()) {
+ return false;
+ }
+ if (dialog.noToAll()) {
+ this.skipAll = true;
+ return false;
+ }
+ throw new IllegalStateException();
+ }
+
+ }
+
+
+ // ********** overwrite dialog **********
+
+ static class OverwriteConfirmerDialog extends Dialog {
+ private final String className;
+ private boolean yes = false;
+ private boolean yesToAll = false;
+ private boolean no = false;
+ private boolean noToAll = false;
+
+ OverwriteConfirmerDialog(Shell parent, String className) {
+ super(parent);
+ this.className = className;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText(JptUiMessages.OverwriteConfirmerDialog_title);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+ GridLayout gridLayout = (GridLayout) composite.getLayout();
+ gridLayout.numColumns = 2;
+
+ Label text = new Label(composite, SWT.LEFT);
+ text.setText(NLS.bind(JptUiMessages.OverwriteConfirmerDialog_text, this.className));
+ text.setLayoutData(new GridData());
+
+ return composite;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ this.createButton(parent, IDialogConstants.YES_ID, IDialogConstants.YES_LABEL, false);
+ this.createButton(parent, IDialogConstants.YES_TO_ALL_ID, IDialogConstants.YES_TO_ALL_LABEL, false);
+ this.createButton(parent, IDialogConstants.NO_ID, IDialogConstants.NO_LABEL, true);
+ this.createButton(parent, IDialogConstants.NO_TO_ALL_ID, IDialogConstants.NO_TO_ALL_LABEL, false);
+ this.createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case IDialogConstants.YES_ID :
+ this.yesPressed();
+ break;
+ case IDialogConstants.YES_TO_ALL_ID :
+ this.yesToAllPressed();
+ break;
+ case IDialogConstants.NO_ID :
+ this.noPressed();
+ break;
+ case IDialogConstants.NO_TO_ALL_ID :
+ this.noToAllPressed();
+ break;
+ case IDialogConstants.CANCEL_ID :
+ this.cancelPressed();
+ break;
+ default :
+ break;
+ }
+ }
+
+ private void yesPressed() {
+ this.yes = true;
+ this.setReturnCode(OK);
+ this.close();
+ }
+
+ private void yesToAllPressed() {
+ this.yesToAll = true;
+ this.setReturnCode(OK);
+ this.close();
+ }
+
+ private void noPressed() {
+ this.no = true;
+ this.setReturnCode(OK);
+ this.close();
+ }
+
+ private void noToAllPressed() {
+ this.noToAll = true;
+ this.setReturnCode(OK);
+ this.close();
+ }
+
+ boolean yes() {
+ return this.yes;
+ }
+
+ boolean yesToAll() {
+ return this.yesToAll;
+ }
+
+ boolean no() {
+ return this.no;
+ }
+
+ boolean noToAll() {
+ return this.noToAll;
+ }
+ }
+
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java
new file mode 100644
index 0000000000..7c3ecba423
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import org.eclipse.draw2d.Button;
+import org.eclipse.draw2d.ChopboxAnchor;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.ConnectionEndpointLocator;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.PolygonDecoration;
+import org.eclipse.draw2d.PolylineConnection;
+import org.eclipse.draw2d.XYLayout;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+
+class AssociationFigure extends Button {
+
+ Color enabledColor = new Color( null, 14,66,115);
+ Color disabledLineColor = new Color( null, 192,215,231);
+ Color selectedColor = new Color( null, 232,232,232 );
+
+ Color selectedBorderColor = new Color( null, 14,66,115 );
+ LineBorder selectedBorder = new LineBorder( selectedBorderColor, 2 );
+ LineBorder unselectedBorder = new LineBorder( ColorConstants.lightGray, 1 );
+ Font descriptionFont = new Font(null, "Arial", 8, SWT.NONE);
+
+ /**
+ * The model behind the the view object
+ */
+ Association association;
+ TableFigure tableFig1;
+ TableFigure tableFig2;
+ PolylineConnection connection ;
+
+ PolygonDecoration referrerDecoration ;
+ PolygonDecoration referencedDecoration ;
+
+ Label referencedLabel ;
+ Label referrerLabel ;
+ Label descriptionLabel ;
+
+ AssociationFigure(Association association) {
+ this.association = association;
+
+ XYLayout contentsLayout = new XYLayout();
+ setLayoutManager(contentsLayout);
+ setBorder( unselectedBorder );
+
+ //Create the figures for referrer table and referenced table
+ tableFig1 = new TableFigure( association.getReferrerTable().getName() );
+ tableFig2 = new TableFigure( association.getReferencedTable().getName() );
+
+ contentsLayout.setConstraint(tableFig1, new Rectangle(10,10,150,20));
+ contentsLayout.setConstraint(tableFig2, new Rectangle(280, 10, 150, 20));
+
+ connection = drawConnection(tableFig1, tableFig2);
+
+ add(tableFig1);
+ add(tableFig2);
+ add(connection);
+
+
+ descriptionLabel = new Label("");
+ contentsLayout.setConstraint(descriptionLabel, new Rectangle(10,30,-1,-1));
+ descriptionLabel.setFont( descriptionFont );
+ add(descriptionLabel);
+
+ //set white background
+ this.setBackgroundColor(ColorConstants.white);
+
+ update();
+
+ }
+
+ private PolylineConnection drawConnection(TableFigure tableFig1,
+ TableFigure tableFig2) {
+ /* Creating the connection */
+ PolylineConnection connection = new PolylineConnection();
+ ChopboxAnchor sourceAnchor = new ChopboxAnchor(tableFig1);
+ ChopboxAnchor targetAnchor = new ChopboxAnchor(tableFig2);
+ connection.setSourceAnchor(sourceAnchor);
+ connection.setTargetAnchor(targetAnchor);
+
+ /* Creating the decoration */
+ referrerDecoration = new SmoothPolygonDecoration();
+ connection.setSourceDecoration(referrerDecoration);
+
+ referencedDecoration = new SmoothPolygonDecoration();
+ connection.setTargetDecoration(referencedDecoration);
+
+
+ /* Adding labels to the connection */
+ ConnectionEndpointLocator sourceEndpointLocator =
+ new ConnectionEndpointLocator(connection, false);
+ sourceEndpointLocator.setVDistance(-5);
+ referrerLabel = new Label("");
+ connection.add(referrerLabel, sourceEndpointLocator);
+
+ ConnectionEndpointLocator targetEndpointLocator =
+ new ConnectionEndpointLocator(connection, true);
+ targetEndpointLocator.setVDistance(-5);
+ referencedLabel = new Label("");
+ connection.add(referencedLabel, targetEndpointLocator);
+
+ ConnectionEndpointLocator relationshipLocator =
+ new ConnectionEndpointLocator(connection,true);
+ relationshipLocator.setUDistance(10);
+ relationshipLocator.setVDistance(-20);
+ Label relationshipLabel = new Label("contains");
+ connection.add(relationshipLabel,relationshipLocator);
+ return connection;
+ }
+
+ public Association getAssociation() {
+ return this.association;
+ }
+
+ public void setSelected ( boolean isSelected ){
+ this.setBackgroundColor( isSelected ? selectedColor : ColorConstants.white );
+ this.setBorder(isSelected? selectedBorder : unselectedBorder);
+ }
+
+ /**
+ * Update the view with the changes user made on the model
+ */
+ public void update(){
+ boolean isGenerated = association.isGenerated();
+
+ connection.setForegroundColor( isGenerated? enabledColor: disabledLineColor );
+
+ tableFig1.setEnabled(isGenerated);
+ tableFig2.setEnabled(isGenerated);
+ descriptionLabel.setForegroundColor(isGenerated? enabledColor: disabledLineColor);
+
+ //paintDirectionalityAndCardinality
+ String cardinalityStr;
+ String directionality = association.getDirectionality();
+ String cardinality = association.getCardinality();
+ //Draw referrerRole
+ if (cardinality.equals(Association.MANY_TO_ONE) || cardinality.equals(Association.MANY_TO_MANY)) {
+ cardinalityStr = "*";
+ } else {
+ cardinalityStr = "1";
+ }
+ if (directionality.equals(Association.BI_DI) || directionality.equals(Association.OPPOSITE_DI)) {
+ connection.setSourceDecoration(this.referrerDecoration);
+ }else{
+ connection.setSourceDecoration(null);
+ }
+
+ this.referrerLabel.setText( cardinalityStr );
+
+ //Draw referencedRole
+ if (cardinality.equals(Association.MANY_TO_ONE) || cardinality.equals(Association.ONE_TO_ONE)) {
+ cardinalityStr = "1";
+ } else {
+ cardinalityStr = "*";
+ }
+ if (directionality.equals(Association.BI_DI) || directionality.equals(Association.NORMAL_DI)) {
+ connection.setTargetDecoration(this.referencedDecoration);
+ }else{
+ connection.setTargetDecoration(null);
+ }
+ this.referencedLabel.setText(cardinalityStr);
+
+ String text = "";
+ String referrerTableName = association.getReferrerTableName();
+ String referencedTable = association.getReferencedTableName();
+ if( cardinality.equals(Association.MANY_TO_ONE ) ){
+ text = String.format( JptUiEntityGenMessages.manyToOneDesc, referencedTable , referrerTableName );
+ }else if( cardinality.equals(Association.ONE_TO_ONE ) ){
+ text = String.format( JptUiEntityGenMessages.oneToOneDesc, referrerTableName, referencedTable );
+ }else if( cardinality.equals(Association.MANY_TO_MANY) ){
+ text = String.format( JptUiEntityGenMessages.manyToManyDesc, referrerTableName, referencedTable, referencedTable, referrerTableName );
+ }
+
+ if( association.isCustom() ){
+ connection.setLineStyle( SWT.LINE_DOT);
+ }
+
+ this.descriptionLabel.setText(text);
+
+ }
+
+ public class SmoothPolygonDecoration extends PolygonDecoration
+ {
+ public SmoothPolygonDecoration()
+ {
+ super();
+ }
+
+ @Override
+ public void paintFigure(Graphics graphics)
+ {
+ int savedAntialias = graphics.getAntialias();
+ graphics.setAntialias(SWT.ON);
+ super.paintFigure(graphics);
+ graphics.setAntialias(savedAntialias);
+ }
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java
new file mode 100644
index 0000000000..e4d690d27f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.createButton;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.createLabel;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.createText;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+
+
+
+public class AssociationTablesPage extends NewAssociationWizardPage {
+
+ private Button simpleAssoBtn;
+ private Button mtmAssoBtn;
+ private Text table1TextField ;
+ private Text table2TextField ;
+ private Text joinTableTextField;
+ private Button joinTableBrowse;
+
+ public AssociationTablesPage(ORMGenCustomizer customizer) {
+ super(customizer, "AssociationTablesPage");
+ setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_title);
+ setDescription(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_desc);
+ }
+
+ public void createControl(Composite composite) {
+ initializeDialogUnits(composite);
+ Composite parent = new Composite(composite, SWT.NONE);
+ parent.setLayout(new GridLayout(1, true));
+
+ Group assocKindGroup = new Group(parent, SWT.NULL);
+ int nColumns= 3 ;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ assocKindGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ assocKindGroup.setLayout(layout);
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.DIALOG_GENERATE_ENTITIES);
+ assocKindGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_assocKind);
+
+ simpleAssoBtn = createButton(assocKindGroup, 3, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_simpleAssoc, SWT.RADIO);
+ mtmAssoBtn = createButton(assocKindGroup, 3, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_m2mAssoc, SWT.RADIO);
+
+
+ Group assocTablesGroup = new Group(parent, SWT.NULL);
+ nColumns= 3 ;
+ layout = new GridLayout();
+ layout.numColumns = nColumns;
+ assocTablesGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ assocTablesGroup.setLayout(layout);
+
+
+ assocTablesGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_assocTables );
+
+ createLabel(assocTablesGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_table1);
+ table1TextField = createText(assocTablesGroup, 1);
+
+ Button browser1 = createButton(assocTablesGroup, 1, "", SWT.NONE);
+ browser1.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_BROWSE ));
+
+ browser1.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ SelectTableDialog dlg = new SelectTableDialog( Display.getDefault().getActiveShell(), customizer.getTableNames() );
+ if( dlg.open() ==Dialog.OK ){
+ table1TextField.setText( dlg.getSelectedTable() );
+ getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_REFERRER_TABLE, table1TextField.getText());
+ getWizard().getContainer().updateButtons();
+ ((NewAssociationWizard)getWizard()).updateTableNames();
+ }
+ }
+ });
+
+ createLabel(assocTablesGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_table2);
+ table2TextField = createText(assocTablesGroup, 1);
+
+ Button browser2 = createButton(assocTablesGroup, 1, "", SWT.NONE);
+ browser2.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_BROWSE ));
+
+ browser2.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ SelectTableDialog dlg = new SelectTableDialog( Display.getDefault().getActiveShell(), customizer.getSchema() );
+ if( dlg.open() == Dialog.OK){
+ table2TextField.setText( dlg.getSelectedTable() );
+ getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_REFERENCED_TABLE, table2TextField.getText());
+ ((NewAssociationWizard)getWizard()).updateTableNames();
+ }
+ updatePageComplete();
+ }
+ });
+
+ createLabel(assocTablesGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_assocTables );
+ joinTableTextField = createText(assocTablesGroup, 1);
+ joinTableTextField.setEnabled(false);
+
+ joinTableBrowse = createButton(assocTablesGroup, 1, "", SWT.NONE);
+ joinTableBrowse.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_BROWSE ));
+ joinTableBrowse.setEnabled(false);
+
+ joinTableBrowse.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ SelectTableDialog dlg = new SelectTableDialog( Display.getDefault().getActiveShell(), customizer.getSchema() );
+ if( dlg.open() == Dialog.OK){
+ joinTableTextField.setText( dlg.getSelectedTable() );
+ getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_JOIN_TABLE, joinTableTextField.getText() );
+ ((NewAssociationWizard)getWizard()).updateTableNames();
+ getWizard().getContainer().updateButtons();
+ }
+ updatePageComplete();
+ }
+ });
+
+ setControl(parent);
+
+ simpleAssoBtn.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ joinTableTextField.setEnabled(false);
+ joinTableTextField.clearSelection();
+ joinTableTextField.setText("");
+ joinTableBrowse.setEnabled(false);
+ getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_ONE);
+ getWizardDataModel().remove( NewAssociationWizard.ASSOCIATION_JOIN_TABLE );
+ ((NewAssociationWizard)getWizard()).updateTableNames();
+ updatePageComplete();
+ }
+
+ });
+
+ mtmAssoBtn.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ joinTableTextField.setEnabled(true);
+ joinTableBrowse.setEnabled(true);
+ getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_MANY);
+ ((NewAssociationWizard)getWizard()).updateTableNames();
+ updatePageComplete();
+ }
+ });
+
+ this.setPageComplete( false);
+ table1TextField.setFocus();
+ }
+
+ public boolean canFlipToNextPage() {
+ return isPageComplete();
+ }
+
+ public void updatePageComplete() {
+ if( this.table1TextField.getText().length() <= 0){
+ setPageComplete(false);
+ return;
+ }
+ if( mtmAssoBtn.getSelection() ){
+ if( this.joinTableTextField.getText().length() <= 0 ){
+ setPageComplete(false);
+ return;
+ }
+ }
+ setPageComplete(true);
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java
new file mode 100644
index 0000000000..ca06c33c32
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.List;
+
+import org.eclipse.draw2d.ActionEvent;
+import org.eclipse.draw2d.ActionListener;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.ToolbarLayout;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A Draw2d figure representing list of associations between two database tables
+ *
+ */
+public class AssociationsListComposite extends FigureCanvas {
+
+ List<Association> associations;
+ AssociationToggleSelectionListener listener ;
+ TableAssociationsWizardPage tableAssociationsWizardPage; //the parent wizard page
+ AssociationFigure selectedAssociationFigure ;
+
+ public AssociationsListComposite(Composite parent, TableAssociationsWizardPage tableAssociationsWizardPage){
+ super(parent);
+ this.tableAssociationsWizardPage = tableAssociationsWizardPage;
+
+ setBounds(10, 10 , 500, 200);
+ setBackground( new Color(Display.getDefault(), 255,255,255));
+
+ Figure figure = new Figure();
+ figure.setLayoutManager(new ToolbarLayout());
+ figure.setBorder(new LineBorder(1));
+ this.listener = new AssociationToggleSelectionListener();
+
+ this.setContents(figure);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void updateAssociations(List<Association> associations){
+ Figure figure = (Figure)this.getContents();
+ List<AssociationFigure> associationFigures = (List<AssociationFigure>) figure.getChildren();
+ for(AssociationFigure assocFig : associationFigures){
+ assocFig.removeActionListener(listener);
+ }
+ figure.removeAll();
+ this.selectedAssociationFigure = null;
+
+ this.associations = associations;
+ if( associations != null ){
+ for( int i = 0; i <associations.size(); i ++ ){
+ Association association = associations.get(i);
+ //Hide the association from individual table to MTM tables
+ if( !association.isCustom() && !association.isGenerated()){
+ continue;
+ }
+ AssociationFigure assocFigure = new AssociationFigure(associations.get(i));
+ assocFigure.addActionListener( listener );
+ figure.add(assocFigure);
+ }
+ }
+ }
+
+ public Association getSelectedAssociation(){
+ return this.selectedAssociationFigure.getAssociation();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void updateSelectedAssociation(){
+ Figure figure = (Figure)this.getContents();
+ List<AssociationFigure> associationFigures = (List<AssociationFigure>) figure.getChildren();
+ for(AssociationFigure assocFig : associationFigures){
+ if( assocFig == this.selectedAssociationFigure){
+ assocFig.update();
+ }
+ }
+ }
+
+ /**
+ * Get the association just before the selected one in UI
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public Association getPreviousAssociation(){
+ Figure figure = (Figure)this.getContents();
+ List<AssociationFigure> associationFigures = (List<AssociationFigure>) figure.getChildren();
+ AssociationFigure ret = null;
+ for(AssociationFigure assocFig : associationFigures){
+ if( assocFig.isSelected() ){
+ break;
+ }
+ ret = assocFig;
+ }
+ return ret==null?null:ret.getAssociation();
+ }
+
+ class AssociationToggleSelectionListener implements ActionListener {
+ public void actionPerformed(ActionEvent event) {
+ AssociationFigure figure = (AssociationFigure )event.getSource() ;
+ figure.setSelected(true);
+ Association association = figure.getAssociation();
+ tableAssociationsWizardPage.updateAssociationEditPanel(association);
+ //un-select the previous selected
+ if( selectedAssociationFigure != null && selectedAssociationFigure!= figure ){
+ selectedAssociationFigure.setSelected( false );
+ }
+ //Highlight new selection
+ selectedAssociationFigure = figure;
+ selectedAssociationFigure.setSelected( true );
+
+ }
+
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java
new file mode 100644
index 0000000000..af682182b0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+
+public class CardinalityPage extends NewAssociationWizardPage {
+
+ private Label mtoDescLabel;
+ private Label otmDescLabel;
+ private Label otoDescLabel;
+ private Label mtmDescLabel;
+
+ private Button[] cardinalityButtons = new Button[4];
+
+ protected CardinalityPage(ORMGenCustomizer customizer) {
+ super( customizer , "CardinalityPage" );
+ setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_cardinalityPage_title);
+ setDescription( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_cardinalityPage_desc);
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+
+ Composite composite = new Composite(parent, SWT.NULL);
+ int nColumns= 1 ;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ composite.setLayout(layout);
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.DIALOG_GENERATE_ENTITIES);
+
+ CardinalitySelectionListener selectionListener = new CardinalitySelectionListener();
+ cardinalityButtons[0] = createRadioButton( composite, 1, JptUiEntityGenMessages.manyToOne);
+ cardinalityButtons[0].addSelectionListener( selectionListener );
+ //Default cardinality is MTO
+ cardinalityButtons[0].setSelection(true);
+ getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_ONE);
+
+ mtoDescLabel = createLabel(composite,1, JptUiEntityGenMessages.manyToOneDesc);
+
+ cardinalityButtons[1] = createRadioButton( composite, 1, JptUiEntityGenMessages.oneToMany);
+ cardinalityButtons[1].addSelectionListener( selectionListener );
+
+ otmDescLabel = createLabel(composite,1, JptUiEntityGenMessages.manyToOneDesc);
+
+ cardinalityButtons[2] = createRadioButton( composite, 1, JptUiEntityGenMessages.oneToOne);
+ cardinalityButtons[2].addSelectionListener( selectionListener );
+
+ otoDescLabel = createLabel(composite,1, JptUiEntityGenMessages.oneToOneDesc);
+
+ cardinalityButtons[3] = createRadioButton( composite, 1, JptUiEntityGenMessages.manyToMany);
+ mtmDescLabel= createLabel(composite,1, JptUiEntityGenMessages.manyToManyDesc);
+
+ setControl(composite);
+ this.setPageComplete( true );
+
+ cardinalityButtons[0].setFocus();
+
+ }
+
+ public void updateWithNewTables() {
+ String s1 = getReferrerTableName() ;
+ String s2 = getReferencedTableName() ;
+ String joinTableName = getJoinTableName();
+ if( s1 == null || s2 == null )
+ return ;
+
+ updateDescriptionText(s1, s2);
+ if( joinTableName == null ){
+ cardinalityButtons[0].setEnabled(true);
+ cardinalityButtons[1].setEnabled(true);
+ cardinalityButtons[2].setEnabled(true);
+ cardinalityButtons[3].setEnabled(false);
+ mtmDescLabel.setEnabled(false);
+ }else{
+ cardinalityButtons[0].setEnabled(false);
+ cardinalityButtons[1].setEnabled(false);
+ cardinalityButtons[2].setEnabled(false);
+ cardinalityButtons[3].setEnabled(true);
+ cardinalityButtons[3].setSelection(true);
+ mtmDescLabel.setEnabled(true);
+ }
+ ((Composite)this.getControl()).layout() ;
+ }
+
+ private void updateDescriptionText(String s1, String s2) {
+ //MTO
+ String msg = String.format(JptUiEntityGenMessages.manyToOneDesc, s2, s1);
+ mtoDescLabel.setText( msg );
+ //OTM
+ msg = String.format(JptUiEntityGenMessages.manyToOneDesc, s1, s2);
+ otmDescLabel.setText( msg );
+ msg = String.format(JptUiEntityGenMessages.oneToOneDesc, s1, s2);
+ otoDescLabel.setText( msg );
+ msg = String.format(JptUiEntityGenMessages.manyToManyDesc, s1, s2, s2, s1);
+ mtmDescLabel.setText( msg );
+ }
+
+ public boolean canFlipToNextPage() {
+ return false;
+ }
+
+ private Label createLabel(Composite container, int span, String text) {
+ Label label = new Label(container, SWT.NONE);
+ label.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ gd.horizontalIndent = 30;
+ label.setLayoutData(gd);
+ return label;
+ }
+
+
+ private Button createRadioButton(Composite container, int span, String text ) {
+ Button btn = new Button(container, SWT.RADIO );
+ btn.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ btn.setLayoutData(gd);
+ return btn;
+ }
+
+
+ private class CardinalitySelectionListener implements SelectionListener {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ if( e.getSource() == cardinalityButtons[0]){
+ getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_ONE);
+ }else if( e.getSource() == cardinalityButtons[1]){
+ getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.ONE_TO_MANY );
+ }else if( e.getSource() == cardinalityButtons[2]){
+ getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.ONE_TO_ONE);
+ }else{
+ getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_MANY);
+ }
+ CardinalityPage.this.setPageComplete(true);
+
+ }
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java
new file mode 100644
index 0000000000..e8e76c1373
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jpt.gen.internal2.AssociationRole;
+import org.eclipse.jpt.gen.internal2.util.StringUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Simple dialog allows user to set the cascade property of an associationRole.
+ * The value of cascade can be "all", or any combination of other selections.
+ *
+ */
+public class CascadeDialog extends TrayDialog {
+
+ private static String[] ALL_CASCADES = new String[] {TagNames.ALL_CASCADE, TagNames.PERSIST_CASCADE, TagNames.MERGE_CASCADE
+ , TagNames.REMOVE_CASCADE, TagNames.REFRESH_CASCADE};
+
+ private static String[] ALL_CASCADES_LABELS
+ = new String[] { "&all", //$NON-NLS-1$
+ "&persist", //$NON-NLS-1$
+ "&merge", //$NON-NLS-1$
+ "&remove", //$NON-NLS-1$
+ "r&efresh"}; //$NON-NLS-1$
+
+
+ private Button[] allButtons = new Button[ALL_CASCADES.length];
+
+ private AssociationRole associationRole;
+ private List<String> cascades;
+
+ protected CascadeDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ public static CascadeDialog create(AssociationRole role) {
+ CascadeDialog dlg = new CascadeDialog(Display.getDefault().getActiveShell() );
+ dlg.setAssociationRole(role);
+ return dlg;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(JptUiEntityGenMessages.selectCascadeDlgTitle);
+ }
+
+ private void setAssociationRole(AssociationRole role) {
+ this.associationRole = role;
+ List<String> list = StringUtil.strToList(associationRole.getCascade(), ',', true/*trim*/); //role.getCascade() contains the comma separed cascades (see below)
+ if (list == null) {
+ list = Collections.emptyList();
+ }
+ cascades = list;
+
+ }
+
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite container = (Composite) super.createDialogArea(parent);
+ createCascadeTypesGroup(container);
+ Dialog.applyDialogFont(container);
+ return container;
+ }
+
+ private void createCascadeTypesGroup(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setLayout(new GridLayout());
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.widthHint = 275;
+ group.setLayoutData(gd);
+ group.setText(JptUiEntityGenMessages.cascade);
+
+ for( int i=0; i< ALL_CASCADES.length; i ++ ){
+ Button checkbox = new Button(group, SWT.CHECK);
+ checkbox.setText( ALL_CASCADES_LABELS[i] );
+ checkbox.setSelection( isInList(ALL_CASCADES[i]) ); //$NON-NLS-1$
+ checkbox.setData(ALL_CASCADES[i]);
+ allButtons[i] = checkbox;
+ /*if <code>all</code> is selected then deselect all others*/
+ checkbox.addSelectionListener( new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ Button b = (Button)e.getSource();
+ if( b.getSelection() ){
+ if( b == allButtons[0] ){
+ for( Button btn : allButtons ){
+ if( btn != e.getSource() ) btn.setSelection(false);
+ }
+ }else{
+ allButtons[0].setSelection(false);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ protected void okPressed() {
+ StringBuilder builder = new StringBuilder();
+ for( Button b : allButtons ){
+ if( b.getSelection() ){
+ if( builder.length()>0 ){
+ builder.append( ',');
+ }
+ builder.append( b.getData() );
+ }
+ }
+ this.associationRole.setCascade( builder.toString() );
+ super.okPressed();
+ }
+
+ private boolean isInList(String cascade) {
+ for( String s : cascades ){
+ if( s.equals(cascade )){
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
+class TagNames
+{
+ public static final String BASIC_TAG = "basic";
+ public static final String CASCADE_TAG = "cascade";
+ public static final String COLUMN_TAG = "column";
+ public static final String EMBEDDED_TAG = "embedded";
+ public static final String EMBEDDED_ID_TAG = "embedded-id";
+ public static final String GENERATED_VALUE_TAG = "generated-value";
+ public static final String ID_TAG = "id";
+ public static final String ID_CLASS_TAG = "id";
+ public static final String JOIN_COLUMN_TAG = "join-column";
+ public static final String INVERSE_JOIN_COLUMN_TAG = "inverse-join-column";
+ public static final String LOB_TAG = "lob";
+ public static final String MANY_TO_MANY_TAG = "many-to-many";
+ public static final String MANY_TO_ONE_TAG = "many-to-one";
+ public static final String MAPPED_BY_TAG = "mapped-by";
+ public static final String ONE_TO_MANY_TAG = "one-to-many";
+ public static final String ONE_TO_ONE_TAG = "one-to-one";
+ public static final String PK_JOIN_COLUMN_TAG = "primary-key-join-column";
+ public static final String TABLE_TAG = "table";
+ public static final String VERSION_TAG = "version";
+ public static final String JOIN_TABLE_TAG = "join-table";
+
+ /*cascade tags*/
+ public static final String ALL_CASCADE = "all";
+ public static final String PERSIST_CASCADE = "persist";
+ public static final String MERGE_CASCADE = "merge";
+ public static final String REMOVE_CASCADE = "remove";
+ public static final String REFRESH_CASCADE = "refresh";
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java
new file mode 100644
index 0000000000..478449671c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.gen.internal2.ORMGenColumn;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * The panel used in the <code>TablesAndColumnsPage</code> wizard page
+ * to edit the column generation properties.
+ * An instance of this class is created by the <code>ORMGenWizard</code>
+ * implementation.
+
+ */
+public class ColumnGenPanel
+{
+ WizardPage wizardPage ;
+ Composite parent; //parent control with grid layout
+ int columns; //total columns in the parent composite
+
+ ORMGenCustomizer customizer;
+
+ private ORMGenColumn mColumn;
+ private boolean mPanelInited;
+ private boolean mIsUpdatingControls;
+
+ private Group columnMappingGroup;
+ private Button mGeneratedCheckbox;
+ private Text mPropNameField;
+ private Combo mMappingKindCombo;
+ private Combo mPropTypeCombo;
+ private Button mUpdateableCheckBox;
+ private Button mInsertableCheckBox;
+
+ private Group domainClassGroup ;
+ private ScopePanel mPropGetScopePanel;
+ private ScopePanel mPropSetScopePanel;
+
+ public ColumnGenPanel(Composite parent, int columns, ORMGenCustomizer customizer, WizardPage wizardPage ) {
+ this.wizardPage = wizardPage;
+ this.customizer = customizer;
+ this.parent =parent;
+ this.columns = columns;
+
+ initPanel();
+ }
+ /**
+ * Changes the table edited by the panel.
+ * This is supposed to update the panel editing controls
+ * using the column values.
+ */
+ public void setColumn(ORMGenColumn column) {
+ mColumn = column;
+
+ /*lazy init panel because it uses mColumn*/
+ if (!mPanelInited) {
+ initPanel();
+ mPanelInited = true;
+ }
+
+ updateControls();
+ }
+ private void updateControls() {
+ if (mIsUpdatingControls) {
+ return;
+ }
+
+ mIsUpdatingControls = true;
+ boolean isGenerated = mColumn.isGenerated();
+ mGeneratedCheckbox.setSelection( isGenerated);
+
+ enableControls(isGenerated);
+ try {
+ mPropNameField.setText(mColumn.getPropertyName());
+
+ mPropTypeCombo.setText( mColumn.getPropertyType());
+
+ mMappingKindCombo.setText( mColumn.getMappingKind());
+
+ mUpdateableCheckBox.setSelection( mColumn.isUpdateable());
+
+ mInsertableCheckBox.setSelection(mColumn.isInsertable());
+
+ mPropGetScopePanel.enableComponents(isGenerated);
+ mPropGetScopePanel.setScope(mColumn.getPropertyGetScope());
+
+ mPropSetScopePanel.enableComponents( isGenerated );
+ mPropSetScopePanel.setScope(mColumn.getPropertySetScope());
+ } catch (Exception e) {
+ JptUiPlugin.log(e);
+ }
+
+ mIsUpdatingControls = false;
+ }
+ private void enableControls(boolean isGenerated) {
+ Control[] controls = this.domainClassGroup.getChildren();
+ for( Control c: controls){
+ c.setEnabled( isGenerated );
+ }
+
+ controls = this.columnMappingGroup.getChildren();
+ for( Control c: controls){
+ c.setEnabled( isGenerated );
+ }
+ }
+ /**
+ * Initializes the panel by adding the editing controls.
+ * @param columns
+ * @param parent
+ */
+ protected void initPanel() {
+ createControls(parent, columns);
+ this.mPanelInited = true;
+ }
+
+ //-------------------------------------------
+ //----- ScopePanel class --------------------
+ //-------------------------------------------
+ /**
+ * A panel containing 3 radios (public, protected, private)
+ */
+ private class ScopePanel
+ {
+ private Button mPublicRadio;
+ private Button mProtectedRadio;
+ private Button mPrivateRadio;
+
+ public ScopePanel(Composite comp, SelectionListener listener) {
+ //super(3, 20/*hspacing*/, 0/*vspacing*/);
+
+ Composite radioGroup = new Composite( comp, SWT.NONE);
+ radioGroup.setLayout(new GridLayout(3, true));
+ GridData gd = new GridData();
+ gd.horizontalSpan = 3;
+ radioGroup.setLayoutData(gd);
+
+ /*string not localized intentionally, they are used as the actual
+ * scope value (see getText() usage)*/
+ mPublicRadio = new Button( radioGroup, SWT.RADIO );
+ mPublicRadio.setText( "public");
+ mPublicRadio.setLayoutData(new GridData());
+ mProtectedRadio = new Button( radioGroup, SWT.RADIO );
+ mProtectedRadio.setText("protected");
+ mProtectedRadio.setLayoutData(new GridData());
+ mPrivateRadio = new Button(radioGroup, SWT.RADIO );
+ mPrivateRadio.setText( "private");
+ mPrivateRadio.setLayoutData(new GridData());
+
+ mPublicRadio.addSelectionListener(listener);
+ mProtectedRadio.addSelectionListener(listener);
+ mPrivateRadio.addSelectionListener(listener);
+
+ }
+ public void enableComponents(boolean b) {
+ mPublicRadio.setEnabled(b);
+ mProtectedRadio.setEnabled(b);
+ mPrivateRadio.setEnabled(b);
+ }
+ /**
+ * Returns the currently selected scope.
+ */
+ public String getScope() {
+ Button radio = null;
+ if (mPublicRadio.getSelection()) {
+ radio = mPublicRadio;
+ } else if (mProtectedRadio.getSelection() ) {
+ radio = mProtectedRadio;
+ } else if (mPrivateRadio.getSelection() ) {
+ radio = mPrivateRadio;
+ }
+ return radio != null ? radio.getText() : null;
+ }
+ public void setScope(String scope) {
+ mPublicRadio.setSelection(false);
+ mProtectedRadio.setSelection(false);
+ mPrivateRadio.setSelection(false);
+ if( scope == null )
+ return;
+ if (scope.equals(ORMGenColumn.PUBLIC_SCOPE)) {
+ mPublicRadio.setSelection(true);
+ } else if (scope.equals(ORMGenColumn.PROTECTED_SCOPE)) {
+ mProtectedRadio.setSelection(true);
+ } else if (scope.equals(ORMGenColumn.PRIVATE_SCOPE)) {
+ mPrivateRadio.setSelection(true);
+ }
+ }
+ }
+
+ //-------------------------------------------
+ //----- private methods ---------------------
+ //-------------------------------------------
+ private void createControls(Composite composite, int columns) {
+ mGeneratedCheckbox = new Button(composite, SWT.CHECK);
+ mGeneratedCheckbox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_genProp);
+ mGeneratedCheckbox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!mIsUpdatingControls) {
+ mColumn.setGenerated(mGeneratedCheckbox.getSelection() );
+ updateControls();
+ }
+ }});
+ SWTUtil.fillColumns(mGeneratedCheckbox, columns);
+
+ columnMappingGroup = new Group( composite, SWT.NONE);
+ columnMappingGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_colMapping);
+ columnMappingGroup.setLayout(new GridLayout(columns, false));
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ layoutData.horizontalIndent = 20 ;
+ columnMappingGroup.setLayoutData(layoutData);
+
+ SWTUtil.createLabel(columnMappingGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_propName );
+ mPropNameField = new Text(columnMappingGroup, SWT.BORDER | SWT.SINGLE );
+ mPropNameField.addModifyListener(new ModifyListener(){
+ @SuppressWarnings("restriction")
+ public void modifyText(ModifyEvent e) {
+ if (!mIsUpdatingControls) {
+ String fldName = mPropNameField.getText();
+ IStatus status = JavaConventions.validateIdentifier( fldName,
+ CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3 );
+ if( !status.matches(IStatus.ERROR)){
+ mColumn.setPropertyName(fldName);
+ wizardPage.setErrorMessage(null);
+ }else{
+ wizardPage.setErrorMessage(status.getMessage());
+ }
+ }
+ }
+ });
+ SWTUtil.fillColumns(mPropNameField ,3);
+
+ SWTUtil.createLabel(columnMappingGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_propType );
+ mPropTypeCombo = new Combo(columnMappingGroup, SWT.SINGLE | SWT.READ_ONLY);
+ mPropTypeCombo.setItems( this.customizer.getAllPropertyTypes());
+ mPropTypeCombo.addModifyListener( new ModifyListener(){
+ public void modifyText(ModifyEvent e) {
+ if (!mIsUpdatingControls) {
+ mColumn.setPropertyType(mPropTypeCombo.getText());
+ }
+ }
+ });
+ SWTUtil.fillColumns(mPropTypeCombo,3);
+
+ SWTUtil.createLabel(columnMappingGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_mapKind );
+ mMappingKindCombo = new Combo(columnMappingGroup, SWT.SINGLE | SWT.READ_ONLY);
+ mMappingKindCombo.setItems( this.customizer.getAllMappingKinds());
+ mMappingKindCombo.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!mIsUpdatingControls) {
+ mColumn.setMappingKind((String)mMappingKindCombo.getText());
+ }
+
+ }});
+ SWTUtil.fillColumns(mMappingKindCombo ,3);
+
+ mUpdateableCheckBox = new Button(columnMappingGroup, SWT.CHECK);
+ mUpdateableCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_colUpdateable);
+ mUpdateableCheckBox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!mIsUpdatingControls) {
+ mColumn.setUpdateable(mUpdateableCheckBox.getSelection() );
+ }
+ }});
+ SWTUtil.fillColumns(mUpdateableCheckBox ,4);
+
+ mInsertableCheckBox = new Button(columnMappingGroup, SWT.CHECK);
+ mInsertableCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_colInsertable);
+ mInsertableCheckBox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!mIsUpdatingControls) {
+ mColumn.setInsertable(mInsertableCheckBox.getSelection());
+ }
+ }});
+ SWTUtil.fillColumns(mInsertableCheckBox ,4);
+
+ SWTUtil.createLabel(composite, 4,"");
+
+ createJavaBeanPropertyControls(composite, columns);
+ }
+
+ void createJavaBeanPropertyControls(Composite composite, int columns){
+ //Java class generation properties
+ domainClassGroup = new Group(composite, SWT.NONE);
+ domainClassGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_beanProp );
+ domainClassGroup.setLayout(new GridLayout(columns, false));
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ layoutData.horizontalIndent = 20;
+ domainClassGroup.setLayoutData(layoutData);
+
+ SWTUtil.createLabel(domainClassGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_getterScope );
+ mPropGetScopePanel = new ScopePanel(domainClassGroup, new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ if (!mIsUpdatingControls) {
+ if( ((Button)e.getSource()).getSelection() )
+ mColumn.setPropertyGetScope(mPropGetScopePanel.getScope());
+ }
+
+ }});
+
+ SWTUtil.createLabel(domainClassGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_setterScope );
+ mPropSetScopePanel = new ScopePanel(domainClassGroup, new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ if (!mIsUpdatingControls) {
+ if( ((Button)e.getSource()).getSelection() )
+ mColumn.setPropertySetScope(mPropSetScopePanel.getScope());
+ }
+ }});
+
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java
new file mode 100644
index 0000000000..3a52beeba1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java
@@ -0,0 +1,521 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.IWizardContainer;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.db.ConnectionAdapter;
+import org.eclipse.jpt.db.ConnectionListener;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.db.ui.internal.DTPUiTools;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * A composite used to connect to database, includes following UI controls:
+ * - connection combo-box
+ * - schema combo-box
+ * - add connection button
+ * - reconnect button
+ */
+public class DatabaseGroup
+{
+ private final JpaProject jpaProject;
+ private final Set<Listener> listeners = Collections.synchronizedSet(new HashSet<Listener>());
+
+ // these are kept in synch with the selection
+ private ConnectionProfile selectedConnectionProfile;
+ private Schema selectedSchema;
+
+ private final Combo connectionComboBox;
+
+ private final Combo schemaComboBox;
+
+ private final Button reconnectButton;
+
+ private final ConnectionListener connectionListener;
+
+ private IWizardContainer wizardContainer;
+
+ // ********** construction **********
+
+ DatabaseGroup(IWizardContainer wizardContainer, JpaProject jpaProject, Composite parent, int widthHint)
+ {
+ super();
+ this.wizardContainer = wizardContainer;
+ this.jpaProject = jpaProject;
+
+ // connection combo-box
+ this.buildLabel(parent, 1, JptUiEntityGenMessages.connection);
+ this.connectionComboBox = this.buildComboBox(parent, widthHint, this.buildConnectionComboBoxSelectionListener());
+
+ // add connection button
+ this.buildButton(parent, JptUiEntityGenMessages.addConnectionLink, CommonImages.createImage( CommonImages.ADD_CONNECTION_IMAGE ), this.buildAddConnectionLinkSelectionListener());
+
+ // A composite holds the reconnect button & text
+ this.buildLabel(parent, 1, "");
+ Composite comp = new Composite( parent , SWT.NONE );
+ GridData gd = new GridData();
+ gd.grabExcessHorizontalSpace = true ;
+ gd.horizontalSpan = 2;
+ comp.setLayoutData( gd );
+ GridLayout gl = new GridLayout(2, false);
+ // Make the reconnect button to be closer to the connection combo.
+ gl.marginTop = -5;
+ comp.setLayout(gl);
+ this.reconnectButton = this.buildButton(comp, JptUiEntityGenMessages.connectLink, CommonImages.createImage( CommonImages.RECONNECT_IMAGE ), this.buildReconnectLinkSelectionListener());
+ this.buildLabel(comp, 1, JptUiEntityGenMessages.schemaInfo);
+
+ // schema combo-box
+ this.buildLabel(parent, 1, JptUiEntityGenMessages.schema);
+ this.schemaComboBox = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+ GridData data = new GridData(SWT.BEGINNING, SWT.CENTER, true, false);
+ data.horizontalAlignment = SWT.FILL;
+ data.horizontalSpan = 1;
+ data.grabExcessHorizontalSpace = true ;
+ this.schemaComboBox.setLayoutData(data);
+ this.schemaComboBox.addSelectionListener(this.buildSchemaComboBoxSelectionListener());
+ // filler
+ new Label(parent, SWT.NULL);
+
+ this.connectionListener = this.buildConnectionListener();
+ }
+
+
+ public void init()
+ {
+ // initialize state, based on JPA project
+ this.selectedConnectionProfile = this.getJpaProjectConnectionProfile();
+ this.selectedSchema = this.getDefaultSchema();
+
+ if (this.selectedSchema != null) {
+ this.fireSchemaChanged(this.selectedSchema);
+ }
+ if (this.selectedConnectionProfile != null) {
+ this.selectedConnectionProfile.addConnectionListener(this.connectionListener);
+ this.fireConnectionProfileChanged(this.selectedConnectionProfile);
+ }
+
+ this.updateConnectionComboBox();
+ this.updateSchemaComboBox();
+ this.updateReconnectLink();
+
+ }
+ // ********** intra-wizard methods **********
+
+ ConnectionProfile getSelectedConnectionProfile() {
+ return this.selectedConnectionProfile;
+ }
+
+ Schema getSelectedSchema() {
+ return this.selectedSchema;
+ }
+
+ void dispose() {
+ if (this.selectedConnectionProfile != null) {
+ this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+ }
+ }
+
+
+ // ********** internal methods **********
+
+ /**
+ * this can return null;
+ * called at start-up and when the selected connection profile changes
+ */
+ private ConnectionProfile getJpaProjectConnectionProfile() {
+ return this.jpaProject.getConnectionProfile();
+ }
+
+ /**
+ * this can return null;
+ * called at start-up and when the selected connection profile changes
+ */
+ private Schema getDefaultSchema() {
+ try{
+ return (this.selectedConnectionProfile == this.getJpaProjectConnectionProfile()) ?
+ jpaProject.getDefaultDbSchema() : null;
+ }catch(Exception e ){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * the connection combo-box is updated at start-up and when the user
+ * adds a connection profile
+ */
+ private void updateConnectionComboBox() {
+ this.connectionComboBox.removeAll();
+ for (String cpName : this.buildSortedConnectionProfileNames()) {
+ this.connectionComboBox.add(cpName);
+ }
+ if (this.selectedConnectionProfile != null) {
+ this.connectionComboBox.select(this.connectionComboBox.indexOf(this.selectedConnectionProfile.getName()));
+ }
+ }
+
+ private SortedSet<String> buildSortedConnectionProfileNames() {
+ return CollectionTools.sortedSet(JptDbPlugin.instance().getConnectionProfileFactory().connectionProfileNames());
+ }
+
+ /**
+ * called at start-up and when the selected connection profile changes
+ */
+ private void updateReconnectLink() {
+ this.reconnectButton.setEnabled(this.reconnectLinkCanBeEnabled());
+ }
+
+ private boolean reconnectLinkCanBeEnabled() {
+ return (this.selectedConnectionProfile != null) && !(this.selectedConnectionProfile.isActive());
+ }
+
+ /**
+ * the schema combo-box is updated at start-up and
+ * when the selected connection profile changes
+ */
+ private void updateSchemaComboBox() {
+ this.schemaComboBox.removeAll();
+ for (Iterator<String> stream = this.getSchemata(); stream.hasNext(); ) {
+ this.schemaComboBox.add(stream.next());
+ }
+ // the current schema *should* be in the current connection profile
+ if (this.selectedSchema != null) {
+ this.schemaComboBox.select(this.schemaComboBox.indexOf(this.selectedSchema.getName()));
+ }
+ }
+
+ private Iterator<String> getSchemata() {
+ SchemaContainer sc = jpaProject.getDefaultDbSchemaContainer();
+ return (sc == null) ? EmptyIterator.<String>instance() : sc.sortedSchemaIdentifiers();
+ }
+
+ /**
+ * If the specified name matches the name of the JPA project's
+ * connection profile, return it; otherwise, build a new connection
+ * profile.
+ */
+ private ConnectionProfile checkJpaProjectConnectionProfile(String cpName) {
+ ConnectionProfile cp = this.getJpaProjectConnectionProfile();
+ if ((cp != null) && cp.getName().equals(cpName)) {
+ return cp;
+ }
+ return this.buildConnectionProfile(cpName);
+ }
+
+ private ConnectionProfile buildConnectionProfile(String name) {
+ return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(name);
+ }
+
+
+ // ********** listener callbacks **********
+
+ void selectedConnectionChanged() {
+ String text = this.connectionComboBox.getText();
+ if (text.length() == 0) {
+ if (this.selectedConnectionProfile == null) {
+ return; // no change
+ }
+ this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+ this.selectedConnectionProfile = null;
+ } else {
+ if (this.selectedConnectionProfile == null) {
+ this.selectedConnectionProfile = this.checkJpaProjectConnectionProfile(text);
+ } else {
+ if (text.equals(this.selectedConnectionProfile.getName())) {
+ return; // no change
+ }
+ this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+ this.selectedConnectionProfile = this.checkJpaProjectConnectionProfile(text);
+ }
+ this.selectedConnectionProfile.addConnectionListener(this.connectionListener);
+ }
+ this.fireConnectionProfileChanged(this.selectedConnectionProfile);
+ this.connectionChanged();
+ }
+
+ void selectedSchemaChanged() {
+ Schema old = this.selectedSchema;
+ this.selectedSchema = this.selectedConnectionProfile.getDatabase().getSchemaForIdentifier(this.schemaComboBox.getText());
+ if (this.selectedSchema != old) {
+ fireSchemaChanged(this.selectedSchema);
+ }
+ }
+
+ /**
+ * Open the DTP New Connection Profile wizard.
+ * If the user creates a new connection profile, start using it and
+ * connect it
+ */
+ void addConnection() {
+ String addedProfileName = DTPUiTools.createNewConnectionProfile();
+ if (addedProfileName == null) {
+ return; // user pressed "Cancel"
+ }
+ if (this.selectedConnectionProfile != null) {
+ this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+ }
+ this.selectedConnectionProfile = this.buildConnectionProfile(addedProfileName);
+ this.selectedConnectionProfile.addConnectionListener(this.connectionListener);
+ this.updateConnectionComboBox();
+ this.selectedConnectionProfile.connect();
+ this.updateSchemaComboBox();
+ // everything else should be synchronized when we get the resulting open event
+ this.fireConnectionProfileChanged(this.selectedConnectionProfile);
+ }
+
+ void reconnect() {
+ try {
+ wizardContainer.run(true, true, new IRunnableWithProgress(){
+ public void run( final IProgressMonitor monitor )
+ throws InvocationTargetException, InterruptedException
+ {
+ monitor.beginTask("Connecting to database", 10);
+ final boolean[] isConnected= new boolean[1];
+ isConnected[0]=false;
+ Thread t= new Thread(){
+ public void run() {
+ selectedConnectionProfile.connect();
+ isConnected[0]=true;
+ }
+ };
+ t.start();
+ while( !isConnected[0]){
+ Thread.sleep(1000);
+ monitor.worked(1);
+ }
+ // everything should be synchronized when we get the resulting open event
+ monitor.done();
+ }
+ });
+ } catch (Exception e) {
+ JptUiPlugin.log(e);
+ }
+ }
+
+ /**
+ * called when
+ * - the user selects a new connection
+ * - the connection was opened
+ * - the connection was closed (never happens?)
+ * we need to update the schema stuff and the reconnect link
+ */
+ void connectionChanged() {
+ Schema old = this.selectedSchema;
+ this.selectedSchema = this.getDefaultSchema();
+ if (this.selectedSchema != old) {
+ this.fireSchemaChanged(this.selectedSchema);
+ }
+ this.updateSchemaComboBox();
+ this.updateReconnectLink();
+ }
+
+
+ // ********** listeners **********
+
+ private SelectionListener buildConnectionComboBoxSelectionListener() {
+ return new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent event) {
+ // nothing special for "default" (double-click?)
+ this.widgetSelected(event);
+ }
+ public void widgetSelected(SelectionEvent event) {
+ DatabaseGroup.this.selectedConnectionChanged();
+ }
+ @Override
+ public String toString() {
+ return "DatabaseConnectionWizardPage connection combo-box selection listener"; //$NON-NLS-1$
+ }
+ };
+ }
+
+ private SelectionListener buildSchemaComboBoxSelectionListener() {
+ return new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent event) {
+ // nothing special for "default" (double-click?)
+ this.widgetSelected(event);
+ }
+ public void widgetSelected(SelectionEvent event) {
+ DatabaseGroup.this.selectedSchemaChanged();
+ }
+ @Override
+ public String toString() {
+ return "DatabaseConnectionWizardPage schema combo-box selection listener"; //$NON-NLS-1$
+ }
+ };
+ }
+
+ private SelectionListener buildAddConnectionLinkSelectionListener() {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ DatabaseGroup.this.addConnection();
+ }
+ @Override
+ public String toString() {
+ return "DatabaseConnectionWizardPage add connection link selection listener"; //$NON-NLS-1$
+ }
+ };
+ }
+
+ private SelectionListener buildReconnectLinkSelectionListener() {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ DatabaseGroup.this.reconnect();
+ }
+ @Override
+ public String toString() {
+ return "DatabaseConnectionWizardPage reconnect link selection listener"; //$NON-NLS-1$
+ }
+ };
+ }
+
+ private ConnectionListener buildConnectionListener() {
+ return new ConnectionAdapter() {
+ @Override
+ public void opened(ConnectionProfile cp) {
+ this.connectionChanged();
+ }
+ @Override // this probably won't ever get called...
+ public void closed(ConnectionProfile cp) {
+ this.connectionChanged();
+ }
+ private void connectionChanged() {
+ Display.getDefault().asyncExec(
+ new Runnable() {
+ public void run() {
+ DatabaseGroup.this.connectionChanged();
+ }
+ }
+ );
+ }
+ @Override
+ public String toString() {
+ return "DatabaseConnectionWizardPage connection listener"; //$NON-NLS-1$
+ }
+ };
+ }
+
+
+ // ********** listeners **********
+
+ public void addListener(Listener listener) {
+ if ( ! this.listeners.add(listener)) {
+ throw new IllegalArgumentException("duplicate listener: " + listener); //$NON-NLS-1$
+ }
+ }
+
+ public void removeListener(Listener listener) {
+ if ( ! this.listeners.remove(listener)) {
+ throw new IllegalArgumentException("missing listener: " + listener); //$NON-NLS-1$
+ }
+ }
+
+ private Iterator<Listener> listeners() {
+ return new CloneIterator<Listener>(this.listeners);
+ }
+
+ void fireConnectionProfileChanged(ConnectionProfile connectionProfile) {
+ for (Iterator<Listener> stream = this.listeners(); stream.hasNext(); ) {
+ stream.next().selectedConnectionProfileChanged(connectionProfile);
+ }
+ }
+
+ void fireSchemaChanged(Schema schema) {
+ for (Iterator<Listener> stream = this.listeners(); stream.hasNext(); ) {
+ stream.next().selectedSchemaChanged(schema);
+ }
+ }
+
+ // ********** UI components **********
+
+ /**
+ * build and return a label
+ */
+ private Label buildLabel(Composite parent, int span, String text) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ label.setLayoutData(gd);
+ return label;
+ }
+
+ /**
+ * build and return a combo-box
+ */
+ private Combo buildComboBox(Composite parent, int widthHint, SelectionListener listener) {
+ Combo combo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+ combo.addSelectionListener(listener);
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ //data.grabExcessHorizontalSpace = true ;
+ data.widthHint = widthHint;
+ combo.setLayoutData(data);
+ return combo;
+ }
+
+ /**
+ * build and return a link
+ */
+ private Button buildButton(Composite parent, String toolTipText, Image image, SelectionListener listener) {
+ Button button = new Button(parent, SWT.NONE);
+ GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
+ data.horizontalSpan = 1;
+ button.setLayoutData(data);
+ button.setImage( image );
+ button.setToolTipText( toolTipText);
+ button.addSelectionListener(listener);
+ return button;
+ }
+
+ // ********** listener interface **********
+
+ /**
+ * Allows clients to listen for changes to the selected connection profile
+ * and schema.
+ */
+ public interface Listener extends EventListener
+ {
+ void selectedConnectionProfileChanged(ConnectionProfile connectionProfile);
+ void selectedSchemaChanged(Schema schema);
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java
new file mode 100644
index 0000000000..23c60e30a8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal2.ORMGenTable;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * A wizard page allowing the entry of the default table generation
+ * properties (Java classes package, base class, etc).
+ * These properties apply to all tables unless explicitly overridden (in the table generation page).
+ *
+ * @author Danny Ju
+ */
+public class DefaultTableGenerationWizardPage extends NewTypeWizardPage {
+
+ private JpaProject jpaProject;
+
+ /*the instance used to get/set the default properties.*/
+ private ORMGenTable defaultsTable;
+
+ private ORMGenCustomizer customizer;
+
+ private TableGenPanel defaultTableGenPanel ;
+
+ protected DefaultTableGenerationWizardPage(JpaProject jpaProject) {
+ super(true, "DefaultTableGenerationWizardPage"); //$NON-NLS-1$
+ this.jpaProject = jpaProject;
+ setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_title);
+ setDescription( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_desc);
+ }
+
+
+ // -------- Initialization ---------
+ /**
+ * The wizard owning this page is responsible for calling this method with the
+ * current selection. The selection is used to initialize the fields of the wizard
+ * page.
+ *
+ * @param selection used to initialize the fields
+ */
+ void init(IStructuredSelection selection) {
+ if( jpaProject != null ){
+ IJavaElement jelem = this.jpaProject.getJavaProject();
+ initContainerPage(jelem);
+ initTypePage(jelem);
+ }
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+ Composite composite = new Composite(parent, SWT.NULL);
+ int nColumns= 4 ;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ composite.setLayout(layout);
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.DIALOG_GENERATE_ENTITIES);
+
+ //Create entity access, collection type, etc
+ defaultTableGenPanel = new TableGenPanel(composite, 4, true , this);
+
+ createDomainJavaClassesPropertiesGroup(composite, 4);
+ setControl(composite);
+
+
+ this.setPageComplete( true );
+
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if(visible){
+ ORMGenCustomizer customizer = getCustomizer();
+ //If user changed the connection or schema
+ if( this.customizer != customizer ){
+ this.customizer = customizer;
+ ORMGenTable newTable;
+ newTable = getCustomizer().createGenTable(null);
+ this.defaultsTable = newTable;
+ defaultTableGenPanel.setORMGenTable(newTable);
+
+ //set the super class and implemented interfaces value
+ String baseClass = defaultsTable.getExtends()==null?"":defaultsTable.getExtends();
+ setSuperClass(baseClass, true);
+ setSuperInterfaces(defaultsTable.getImplements(), true);
+
+ setPackageName( defaultsTable.getPackage() );
+
+
+ }
+ }
+ }
+
+ private void setPackageName(String packageName) {
+ if( packageName==null )
+ return;
+ // Copied from org.eclipse.pde.internal.ui.editor.plugin.JavaAttributeWizardPage
+ try {
+ IPackageFragmentRoot srcEntryDft = null;
+ IJavaProject javaProject = jpaProject.getJavaProject();
+ IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
+ for (int i = 0; i < roots.length; i++) {
+ if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
+ srcEntryDft = roots[i];
+ break;
+ }
+ }
+ IPackageFragmentRoot packageFragmentRoot;
+ if (srcEntryDft != null)
+ packageFragmentRoot = srcEntryDft;
+ else {
+ packageFragmentRoot = javaProject.getPackageFragmentRoot(javaProject.getResource());
+ }
+ IFolder packageFolder = javaProject.getProject().getFolder(packageName);
+ IPackageFragment packageFragment = packageFragmentRoot.getPackageFragment(packageFolder.getProjectRelativePath().toOSString());
+ setPackageFragment(packageFragment, true/*canBeModified*/);
+ } catch (CoreException e) {
+ JptUiPlugin.log(e);
+ }
+ }
+
+
+ protected void createDomainJavaClassesPropertiesGroup(Composite composite, int columns) {
+ Group parent = new Group( composite, SWT.NONE);
+ parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_domainJavaClass);
+ parent.setLayout(new GridLayout( columns, false));
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = true;
+ parent.setLayoutData(layoutData);
+
+ //default Java package name only available for default table generation
+ createPackageControls(parent, columns);
+ createSuperClassControls(parent, columns);
+ createSuperInterfacesControls(parent, columns);
+
+ }
+
+ protected IStatus packageChanged() {
+ IStatus status = super.packageChanged();
+ IPackageFragment packageFragment = getPackageFragment();
+ String srcFolder = packageFragment.getPath().toPortableString();
+ if(defaultsTable!=null && !status.matches(IStatus.ERROR)){
+ defaultsTable.setPackage(srcFolder, packageFragment.getElementName());
+ }
+ return status;
+ }
+
+ protected IStatus superClassChanged() {
+ IStatus status = super.superClassChanged();
+ String baseClass = getSuperClass();
+ if(baseClass!=null && defaultsTable!=null && !status.matches(IStatus.ERROR)){
+ String oldBaseClass = defaultsTable.getExtends();
+ if( !baseClass.equals(oldBaseClass))
+ defaultsTable.setExtends(baseClass);
+ }
+ return status;
+ }
+
+ protected void handleFieldChanged(String fieldName) {
+ super.handleFieldChanged(fieldName);
+ if( this.fPackageStatus.matches(IStatus.ERROR) ){
+ updateStatus(fPackageStatus);
+ }else if( this.fSuperClassStatus.matches(IStatus.ERROR)){
+ updateStatus(fSuperClassStatus);
+ }else{
+ setMessage("", IMessageProvider.NONE);
+ setErrorMessage(null);
+ updateStatus(fPackageStatus);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected IStatus superInterfacesChanged() {
+ IStatus ret = super.superInterfacesChanged();
+ if( ret.isOK() ){
+ List interfaces = getSuperInterfaces();
+ if(defaultsTable!=null)
+ defaultsTable.setImplements(interfaces);
+ }
+ return ret;
+ }
+
+ private ORMGenCustomizer getCustomizer(){
+ GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
+ return wizard.getCustomizer();
+ }
+
+ @Override
+ public final void performHelp()
+ {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+ }
+}
+
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java
new file mode 100644
index 0000000000..65713b2337
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java
@@ -0,0 +1,416 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.core.internal.runtime.AdapterManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jpt.core.EntityGeneratorDatabaseAnnotationNameBuilder;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.core.internal.synch.SynchronizeClassesJob;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal2.BaseEntityGenCustomizer;
+import org.eclipse.jpt.gen.internal2.DatabaseAnnotationNameBuilder;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal2.PackageGenerator2;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+@SuppressWarnings("restriction")
+public class GenerateEntitiesFromSchemaWizard extends Wizard
+ implements INewWizard {
+
+ public static final String HELP_CONTEXT_ID = JptUiPlugin.PLUGIN_ID + ".GenerateEntitiesFromSchemaWizard"; //$NON-NLS-1$
+
+ private JpaProject jpaProject;
+
+ private IStructuredSelection selection;
+
+ private ORMGenCustomizer customizer = null;
+
+ private boolean synchronizePersistenceXml;
+
+ private PromptJPAProjectWizardPage projectPage;
+
+ private TablesSelectorWizardPage tablesSelectorPage;
+
+ private TableAssociationsWizardPage tableAssociationsPage;
+
+ private DefaultTableGenerationWizardPage defaultTableGenerationPage;
+
+ private TablesAndColumnsCustomizationWizardPage tablesAndColumnsCustomizationPage;
+
+ public GenerateEntitiesFromSchemaWizard() {
+ this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_generateEntities);
+ }
+
+ public GenerateEntitiesFromSchemaWizard( JpaProject jpaProject, IStructuredSelection selection) {
+ super();
+ this.jpaProject = jpaProject;
+ this.selection = selection;
+ this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_generateEntities);
+ }
+
+ public Image getDefaultPageImage() {
+ return JptUiPlugin.getImage( JptUiIcons.ENTITY_WIZ_BANNER ) ;
+ }
+
+ public void addPages() {
+ super.addPages();
+
+ setForcePreviousAndNextButtons(true);
+
+ //If this.jpaProject is not initialized because user didn't select a JPA project
+ if( this.jpaProject == null ){
+ projectPage = new PromptJPAProjectWizardPage( HELP_CONTEXT_ID );
+ this.addPage(projectPage);
+ return;
+ }
+ addMainPages();
+ }
+
+ private void addMainPages()
+ {
+ this.tablesSelectorPage = new TablesSelectorWizardPage( this.jpaProject );
+ this.addPage(tablesSelectorPage);
+
+ this.tableAssociationsPage = new TableAssociationsWizardPage( this.jpaProject );
+ this.addPage(tableAssociationsPage);
+
+ this.defaultTableGenerationPage = new DefaultTableGenerationWizardPage( this.jpaProject);
+ this.addPage(defaultTableGenerationPage);
+ this.defaultTableGenerationPage.init(this.selection);
+
+ this.tablesAndColumnsCustomizationPage = new TablesAndColumnsCustomizationWizardPage( this.jpaProject );
+ this.addPage(tablesAndColumnsCustomizationPage);
+ this.tablesAndColumnsCustomizationPage.init(selection);
+ }
+
+ public ORMGenCustomizer getORMGenCustomizer(){
+ return this.customizer;
+ }
+
+ /**
+ * Create the ORMGenCustomizer when user selects a new connection profile and schema
+ *
+ * JpaPlatform implementor can provide a custom ORMGenCustomizer specific to a platform
+ * with AdapterFactory through Eclipse org.eclipse.core.runtime.adapters extension point:
+ * <pre>
+ *
+ *<extension
+ * point="org.eclipse.core.runtime.adapters">
+ * <factory
+ * adaptableType="org.eclipse.jpt.eclipselink.core.internal.EclipseLinkPlatform"
+ * class="oracle.eclipse.tools.orm.internal.EclipseLinkORMGenCustomizerAdapterFactory">
+ * <adapter
+ * type="oracle.eclipse.tools.orm.internal.ORMGenCustomizer">
+ * </adapter>
+ * </factory>
+ *</extension>
+ *</pre>
+ *
+ * @param schema
+ */
+ public ORMGenCustomizer createORMGenCustomizer(Schema schema){
+ JpaPlatform jpaPlatform = this.jpaProject.getJpaPlatform();
+ Object obj = AdapterManager.getDefault().getAdapter( jpaPlatform, ORMGenCustomizer.class );
+ if( obj != null ){
+ customizer = (ORMGenCustomizer) obj ;
+ customizer.init(getCustomizationFile(), schema );
+ }else{
+ customizer = new BaseEntityGenCustomizer( );
+ customizer.init(getCustomizationFile(), schema );
+ }
+ return customizer;
+ }
+
+ protected String getCustomizationFileName() {
+ ConnectionProfile profile = getProjectConnectionProfile();
+ String connection = profile==null?"":profile.getName();
+ String name = "org.eclipse.jpt.entitygen." + (connection==null?"":connection.replace(' ', '-')); //$NON-NLS-1$
+ Schema schema = getDefaultSchema();
+ if ( schema!= null ) {
+ name += "." + schema.getName();//$NON-NLS-1$
+ }
+ return name.toLowerCase();
+ }
+
+ /**
+ * Returns the nodes state file.
+ */
+ private File getCustomizationFile() {
+ String projectPath = jpaProject.getProject().getLocation().toPortableString();
+ File genDir = new File(projectPath + "/.settings");//$NON-NLS-1$
+ genDir.mkdirs();
+ return new File(genDir, getCustomizationFileName());
+ }
+
+ public boolean performFinish() {
+ if( this.jpaProject == null )
+ return true;
+
+ try {
+ this.customizer.setDatabaseAnnotationNameBuilder( buildDatabaseAnnotationNameBuilder() );
+ this.customizer.save();
+ } catch (IOException e) {
+ JptUiPlugin.log(e);
+ }
+
+ this.synchronizePersistenceXml = this.tablesSelectorPage.synchronizePersistenceXml();
+
+ if( WarnOverwriteDialog.shouldShowDialog() ){
+ if( !this.openConfirmDialog() )
+ return false;
+ }
+
+ WorkspaceJob genEntitiesJob = new GenerateEntitiesJob( this.jpaProject, getCustomizer() );
+
+ WorkspaceJob synchClassesJob = null;
+ if (synchronizePersistenceXml()) {
+ // we currently only support *one* persistence.xml file per project
+ PersistenceXml persistenceXml = jpaProject.getRootContextNode().getPersistenceXml();
+ if (persistenceXml != null) {
+ // TODO casting to IFile - just trying to get rid of all compiler errors for now
+ synchClassesJob = new SynchronizeClassesJob((IFile) persistenceXml.getResource());
+ }
+ }
+
+ genEntitiesJob.schedule();
+ if (synchClassesJob != null) {
+ synchClassesJob.schedule();
+ }
+
+ return true;
+ }
+
+ // ********** generate entities job **********
+
+ static class GenerateEntitiesJob extends WorkspaceJob {
+ JpaProject jpaProject ;
+ ORMGenCustomizer customizer;
+ GenerateEntitiesJob(JpaProject jpaProject, ORMGenCustomizer customizer) {
+ super(JptUiMessages.EntitiesGenerator_jobName);
+ this.customizer = customizer;
+ this.jpaProject = jpaProject ;
+ this.setRule(jpaProject.getProject());
+ }
+
+ @Override
+ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+ PackageGenerator2.generate(jpaProject.getJavaProject(),this.customizer, monitor);
+ return Status.OK_STATUS;
+ }
+
+ }
+
+ private DatabaseAnnotationNameBuilder buildDatabaseAnnotationNameBuilder() {
+ return new LocalDatabaseAnnotationNameBuilder(this.jpaProject.getJpaPlatform().getEntityGeneratorDatabaseAnnotationNameBuilder());
+ }
+
+ // ********** name builder adapter **********
+
+ /**
+ * adapt the JPA platform-supplied builder to the builder interface
+ * expected by the entity generator
+ */
+ static class LocalDatabaseAnnotationNameBuilder implements DatabaseAnnotationNameBuilder {
+ private EntityGeneratorDatabaseAnnotationNameBuilder builder;
+ LocalDatabaseAnnotationNameBuilder(EntityGeneratorDatabaseAnnotationNameBuilder builder) {
+ super();
+ this.builder = builder;
+ }
+ public String buildTableAnnotationName(String entityName, Table table) {
+ return this.builder.buildTableAnnotationName(entityName, table);
+ }
+ public String buildColumnAnnotationName(String attributeName, Column column) {
+ return this.builder.buildColumnAnnotationName(attributeName, column);
+ }
+ public String buildJoinColumnAnnotationName(String attributeName, ForeignKey foreignKey) {
+ return this.builder.buildJoinColumnAnnotationName(attributeName, foreignKey);
+ }
+ public String buildJoinColumnAnnotationName(Column column) {
+ return this.builder.buildJoinColumnAnnotationName(column);
+ }
+ public String buildJoinTableAnnotationName(Table table) {
+ return this.builder.buildJoinTableAnnotationName(table);
+ }
+ }
+
+ @Override
+ public IWizardPage getStartingPage() {
+ if (this.projectPage != null) {
+ if (this.tablesSelectorPage != null)
+ return this.tablesSelectorPage;
+ else
+ return this.projectPage;
+ }
+ else
+ return super.getStartingPage();
+ }
+
+ public ORMGenCustomizer getCustomizer (){
+ return customizer;
+ }
+ Collection<Table> getPossibleTables() {
+ if ( this.tablesSelectorPage != null) {
+ return this.tablesSelectorPage.getTables();
+ }
+ return ( this.projectDefaultSchemaExists()) ? CollectionTools.collection( this.getDefaultSchema().tables()) : Collections.<Table>emptyList();
+ }
+
+ public ConnectionProfile getProjectConnectionProfile() {
+ return this.jpaProject.getConnectionProfile();
+ }
+
+ public JpaProject getJpaProject(){
+ return this.jpaProject;
+ }
+
+ public void setJpaProject(JpaProject jpaProject) {
+ if (this.jpaProject == null) {
+ this.jpaProject = jpaProject;
+ IWizardPage currentPage = getContainer().getCurrentPage();
+ if (projectPage != null && currentPage.equals(projectPage)) {
+ addMainPages();
+ }
+ }
+ }
+
+ public Schema getDefaultSchema() {
+ return getJpaProject().getDefaultDbSchema() ;
+ }
+
+ private boolean projectDefaultSchemaExists() {
+ return ( this.getDefaultSchema() != null);
+ }
+
+ public boolean synchronizePersistenceXml() {
+ return this.synchronizePersistenceXml;
+ }
+
+ public void init(IWorkbench workbench, IStructuredSelection selection) {
+
+ Object sel = selection.getFirstElement();
+ if( sel instanceof IResource ){
+ IProject proj = ((IResource) sel).getProject();
+ JpaProject jpaProj = JptCorePlugin.getJpaProject( proj );
+ this.jpaProject = jpaProj;
+ }else if( sel instanceof org.eclipse.jdt.core.IPackageFragmentRoot ){
+ org.eclipse.jdt.core.IPackageFragmentRoot root = (org.eclipse.jdt.core.IPackageFragmentRoot)sel;
+ IProject proj = root.getJavaProject().getProject();
+ JpaProject jpaProj = JptCorePlugin.getJpaProject( proj );
+ this.jpaProject = jpaProj;
+ }else if( sel instanceof org.eclipse.jdt.core.IPackageFragment){
+ org.eclipse.jdt.core.IPackageFragment frag = (org.eclipse.jdt.core.IPackageFragment)sel;
+ IProject proj = frag.getJavaProject().getProject();
+ JpaProject jpaProj = JptCorePlugin.getJpaProject( proj );
+ this.jpaProject = jpaProj;
+ }
+
+ this.selection = selection;
+ this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_generateEntities);
+
+ }
+
+ public boolean openConfirmDialog() {
+ Shell parent = Display.getDefault().getActiveShell();
+ String title = JptUiEntityGenMessages.WarningDialogTitle;
+ String message = JptUiEntityGenMessages.GenerateEntitiesWizard_fileWillBeOverwritten;
+ WarnOverwriteDialog dialog = new WarnOverwriteDialog(parent, title, null, // accept
+ // the
+ // default
+ // window
+ // icon
+ message, MessageDialog.QUESTION, new String[] { IDialogConstants.OK_LABEL,
+ IDialogConstants.CANCEL_LABEL }, 0); // OK is the
+ // default
+ return dialog.open() == 0;
+ }
+
+}
+
+/**
+ * A simple dialog displaying warning message that existing files would be overwritten
+ */
+class WarnOverwriteDialog extends MessageDialog {
+ static final String DONT_SHOW_OVERWRITE_WARNING = "DONT_SHOW_OVERWRITE_WARNING"; //$NON-NLS-1$
+
+ public WarnOverwriteDialog (Shell parentShell, String dialogTitle,
+ Image dialogTitleImage, String dialogMessage, int dialogImageType,
+ String[] dialogButtonLabels, int defaultIndex) {
+ super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType,
+ dialogButtonLabels, defaultIndex);
+ }
+
+ @Override
+ protected Control createCustomArea(Composite composite) {
+ final Button checkbox = new Button( composite, SWT.CHECK );
+ checkbox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_doNotShowWarning );
+ checkbox.setSelection(false);
+ final IEclipsePreferences pref = new InstanceScope().getNode( JptUiPlugin.PLUGIN_ID);
+ checkbox.setLayoutData( new GridData(GridData.FILL_BOTH) );
+ checkbox.addSelectionListener(new SelectionListener (){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ boolean b = checkbox.getSelection();
+ if( b ){
+ pref.putBoolean( DONT_SHOW_OVERWRITE_WARNING, true);
+ }
+ }
+ });
+ return checkbox;
+ }
+
+ public static boolean shouldShowDialog(){
+ IEclipsePreferences pref = new InstanceScope().getNode( JptUiPlugin.PLUGIN_ID);
+ boolean ret = ! pref.getBoolean( DONT_SHOW_OVERWRITE_WARNING, true) ;
+ return( ret );
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java
new file mode 100644
index 0000000000..42a346c36c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java
@@ -0,0 +1,605 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.util.TableLayoutComposite;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+
+public class JoinColumnsPage extends NewAssociationWizardPage {
+
+ private Label joinColumnsDescLabel1;
+ /*the table containing the association columns between table1 and table2
+ * , or table1 and join table if many to many*/
+ private TableViewer joinColumnsTable1;
+ private ArrayList<SimpleJoin> tableDataModel1 = new ArrayList<SimpleJoin>();
+ private Composite tablesGroup1;
+
+ private Label joinColumnsDescLabel2;
+ /*the table containing the association columns between join table and table2
+ * if many to many*/
+ private TableViewer joinColumnsTable2;
+ private ArrayList<SimpleJoin> tableDataModel2 = new ArrayList<SimpleJoin>();
+ private Composite tablesGroup2;
+
+ static final String[] JOINCOLUMNS_TABLE_COLUMN_PROPERTIES = { "referrerColumn", "referencedColumn" };
+
+ private static final int JOINCOLUMN1_COLUMN_INDEX = 0;
+ private static final int JOINCOLUMN2_COLUMN_INDEX = 1;
+
+ protected JoinColumnsPage(ORMGenCustomizer customizer ) {
+ super(customizer, "JoinColumnsPage");
+ setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_title);
+ setDescription(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_desc);
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ composite.setLayout(layout);
+
+ tablesGroup1 = new Composite(composite, SWT.SHADOW_ETCHED_IN);
+ tablesGroup1.setLayoutData(new GridData());
+ tablesGroup1.setLayout(new GridLayout(2, false));
+ createJoinColumnsTableControl1(tablesGroup1);
+
+ //createMtmJoinColumnsTable2(composite);
+
+ setControl(composite);
+ this.setPageComplete( false);
+
+ ((WizardDialog)getContainer()).addPageChangedListener(new IPageChangedListener(){
+ public void pageChanged(PageChangedEvent event) {
+ if( event.getSelectedPage() == JoinColumnsPage.this ){
+ ((Composite)JoinColumnsPage.this.getControl()).getParent().layout() ;
+
+ }
+ }
+ });
+ }
+
+ private void createMtmJoinColumnsTable2(Composite composite) {
+ tablesGroup2 = new Composite(composite, SWT.SHADOW_ETCHED_IN);
+ tablesGroup2.setLayoutData(new GridData());
+ tablesGroup2.setLayout(new GridLayout(2, false));
+ createJoinColumnsTableControl2(tablesGroup2);
+ }
+
+ /**
+ * Update wizard page UI with new table names
+ */
+ public void updateWithNewTables() {
+ String cardinality = this.getCardinality() ;
+ if( Association.MANY_TO_MANY.equals( cardinality ) ){
+ updateWithMtmTables();
+ }else{
+ updateWithOtmTables();
+ }
+ }
+
+ /**
+ * Update Wizard UI with a single TableViewer with columns from the two associated database tables
+ */
+ public void updateWithOtmTables() {
+ TableColumn[] columns = joinColumnsTable1.getTable().getColumns();
+ String table1Name = this.getReferrerTableName() ;
+ String table2Name = this.getReferencedTableName() ;
+
+ if( table1Name ==null || table2Name == null )
+ return;
+
+ columns[0].setText( table1Name );
+ columns[1].setText( table2Name );
+
+ //Hide the Join column table 2
+ if( tablesGroup2 !=null )
+ tablesGroup2.setVisible(false);
+
+ tableDataModel1.clear();
+ joinColumnsTable1.refresh();
+
+ String msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, table1Name, table2Name);
+ joinColumnsDescLabel1.setText(msg);
+ joinColumnsDescLabel1.setToolTipText( msg );
+ tablesGroup1.layout();
+
+ String[] referrerColumnValues = getTableColumns(table1Name);
+ String[] referencedColumnValues = getTableColumns(table2Name);
+
+ updateCellEditors(joinColumnsTable1, referrerColumnValues, referencedColumnValues);
+
+
+ ((Composite)this.getControl()).layout() ;
+ }
+
+ /**
+ * Update Wizard UI with a two TableViewers with the first with columns from table1 to the MTM join table
+ * and the second one with columns from the MTM join table to table2
+ */
+ public void updateWithMtmTables() {
+ TableColumn[] columns = joinColumnsTable1.getTable().getColumns();
+ String table1Name = this.getReferrerTableName() ;
+ String table2Name = this.getReferencedTableName() ;
+ String joinTableName = this.getJoinTableName() ;
+ if( table1Name==null || table2Name==null || joinTableName==null ){
+ return;
+ }
+ if( tablesGroup2 == null ){
+ createMtmJoinColumnsTable2( tablesGroup1.getParent());
+ }
+
+ columns[0].setText( table1Name==null?"":table1Name );
+ columns[1].setText( table2Name==null?"":joinTableName );
+
+ //Update join column TableViewer 1
+ tableDataModel1.clear();
+ joinColumnsTable1.refresh();
+
+ String msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, table1Name, joinTableName);
+ joinColumnsDescLabel1.setText(msg);
+ joinColumnsDescLabel1.setToolTipText( msg );
+ String[] referrerColumnValues = getTableColumns(table1Name);
+ String[] referencedColumnValues = getTableColumns(joinTableName);
+
+ updateCellEditors(joinColumnsTable1, referrerColumnValues, referencedColumnValues );
+
+ //Update join column TableViewer 2
+ columns = joinColumnsTable2.getTable().getColumns();
+ columns[0].setText( joinTableName==null?"":joinTableName );
+ columns[1].setText( table2Name==null?"":table2Name );
+ tablesGroup1.layout();
+
+ tableDataModel2.clear();
+ joinColumnsTable2.refresh();
+ msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, joinTableName, table2Name);
+ joinColumnsDescLabel2.setText(msg);
+ joinColumnsDescLabel2.setToolTipText( msg );
+ referrerColumnValues = getTableColumns(joinTableName);
+ referencedColumnValues = getTableColumns(table2Name);
+ updateCellEditors(joinColumnsTable2, referrerColumnValues, referencedColumnValues );
+
+ tablesGroup2.layout();
+
+ //Show the Join column TableViewer 2
+ tablesGroup2.setVisible(true);
+
+
+ ((Composite)this.getControl()).layout(new Control[]{this.tablesGroup1, this.tablesGroup2});
+ }
+
+
+ private void createAddRemoveButtonComposite(Composite tablesGroup, final TableViewer joinColumnsTable, final ArrayList<SimpleJoin> tableDataModel) {
+ //Add and Remove JoinColumns buttons
+ Composite buttonComposite = new Composite(tablesGroup, SWT.NULL);
+ GridLayout buttonLayout = new GridLayout(1, false);
+ buttonComposite.setLayout(buttonLayout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.verticalAlignment = GridData.BEGINNING;
+ buttonComposite.setLayoutData(data);
+
+ Button addButton = new Button(buttonComposite, SWT.PUSH);
+ addButton.setText( JptUiEntityGenMessages.add );
+ GridData gridData = new GridData();
+ gridData.horizontalAlignment = GridData.FILL;
+ addButton.setLayoutData(gridData);
+ addButton.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ @SuppressWarnings("unchecked")
+ public void widgetSelected(SelectionEvent e) {
+
+ SimpleJoin join = getDefaultNewJoin(joinColumnsTable);
+ tableDataModel.add(join);
+ joinColumnsTable.refresh();
+
+ //Update Wizard model
+ TreeMap<String, String> joins = null;
+ if( joinColumnsTable == joinColumnsTable1 ){
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+ }else{
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+ }
+ joins.put( join.foreignKey, join.primaryKey);
+
+ updatePageComplete();
+ }
+ });
+
+ Button removeButton = new Button(buttonComposite, SWT.PUSH);
+ removeButton.setText( JptUiEntityGenMessages.remove );
+ gridData = new GridData();
+ gridData.horizontalAlignment = GridData.FILL;
+ removeButton.setLayoutData(gridData);
+ removeButton.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ @SuppressWarnings("unchecked")
+ public void widgetSelected(SelectionEvent e) {
+ StructuredSelection selection = (StructuredSelection)joinColumnsTable.getSelection();
+ if( selection.isEmpty())
+ return;
+ SimpleJoin join = (SimpleJoin)selection.getFirstElement();
+
+ //Update TableViewer model
+ tableDataModel.remove( join );
+ //Update Wizard model
+
+ TreeMap<String, String> joins = null;
+ if( joinColumnsTable == joinColumnsTable1 ){
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+ }else{
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+ }
+ joins.remove(join.foreignKey);
+
+ joinColumnsTable.refresh();
+ }
+ });
+
+ addButton.setFocus();
+
+ }
+
+ protected SimpleJoin getDefaultNewJoin(TableViewer joinColumnsTable) {
+ String table1Name = "";
+ String table2Name = "";
+ if( joinColumnsTable == this.joinColumnsTable1 ){
+ if( this.getJoinTableName() == null) {
+ table1Name = this.getReferrerTableName();
+ table2Name = this.getReferencedTableName() ;
+ }else{
+ table1Name = this.getReferrerTableName();
+ table2Name = this.getJoinTableName() ;
+ }
+ }else{
+ table1Name = this.getJoinTableName();
+ table2Name = this.getReferencedTableName() ;
+ }
+ String[] table1ColumnValues = getTableColumns(table1Name);
+ String[] table2ColumnValues = getTableColumns(table2Name);
+ return new SimpleJoin(table1ColumnValues[0], table2ColumnValues[0]);
+ }
+
+ public boolean canFlipToNextPage() {
+ return isPageComplete();
+ }
+
+ public void updatePageComplete() {
+ boolean ret = tableDataModel1.size()> 0 ;
+ setPageComplete( ret );
+ }
+
+ private Label createLabel(Composite container, int span, String text) {
+ Label label = new Label(container, SWT.NONE);
+ label.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ label.setLayoutData(gd);
+ return label;
+ }
+
+ private void createJoinColumnsTableControl1(Composite tablesGroup) {
+ joinColumnsDescLabel1 = createLabel(tablesGroup, 2, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label );
+ joinColumnsTable1 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel1);
+ createAddRemoveButtonComposite(tablesGroup, joinColumnsTable1, tableDataModel1);
+ }
+
+ private void createJoinColumnsTableControl2(Composite tablesGroup) {
+ joinColumnsDescLabel2 = createLabel(tablesGroup, 2, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label );
+ joinColumnsTable2 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel2);
+ createAddRemoveButtonComposite(tablesGroup, joinColumnsTable2, tableDataModel2);
+ }
+
+ private TableViewer createJoinColumnsTableControl(Composite parent, ArrayList<SimpleJoin> tableDataModel ){
+
+ TableLayoutComposite layout= new TableLayoutComposite(parent, SWT.NONE);
+ addColumnLayoutData(layout);
+
+ final org.eclipse.swt.widgets.Table table = new org.eclipse.swt.widgets.Table(layout, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER );
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ TableColumn referrerColumn = new TableColumn(table, SWT.NONE, JOINCOLUMN1_COLUMN_INDEX);
+ referrerColumn.setText("%table1");
+ referrerColumn.setResizable(true);
+
+ TableColumn referencedColumn = new TableColumn(table, SWT.NONE, JOINCOLUMN2_COLUMN_INDEX);
+ referencedColumn.setText("%table2");
+ referencedColumn.setResizable(true);
+
+ GridData gd= new GridData(GridData.FILL_BOTH);
+ gd.heightHint= SWTUtil.getTableHeightHint(table, 3);
+ gd.widthHint = 300;
+ layout.setLayoutData(gd);
+
+ TableViewer newJoinColumnsTable = new TableViewer(table);
+ newJoinColumnsTable.setUseHashlookup(true);
+ newJoinColumnsTable.setLabelProvider(this.buildTableTableLabelProvider());
+ newJoinColumnsTable.setContentProvider(this.buildTableTableContentProvider());
+ newJoinColumnsTable.setSorter(new ViewerSorter() {
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ return ((SimpleJoin) e1).foreignKey.compareTo(((SimpleJoin) e2).foreignKey);
+ }
+ });
+
+ newJoinColumnsTable.addPostSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ //handleTablesListSelectionChanged(event);
+ }
+ });
+ populateTableDataModel();
+ newJoinColumnsTable.setInput( tableDataModel );
+ return newJoinColumnsTable;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void populateTableDataModel(){
+ HashMap<String, Object> dataModel = (HashMap<String, Object> )getWizardDataModel();
+ TreeMap<String, String> joinColumns = (TreeMap<String, String>)dataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
+ if( joinColumns!= null ){
+ for( String referrerColumn : joinColumns.keySet() ){
+ tableDataModel1.add(new SimpleJoin(referrerColumn, joinColumns.get(referrerColumn) ));
+ }
+ }
+
+ TreeMap<String, String> joinColumns2 = (TreeMap<String, String>)dataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2);
+ if( joinColumns2!= null ){
+ for( String referrerColumn : joinColumns2.keySet() ){
+ tableDataModel2.add(new SimpleJoin(referrerColumn, joinColumns2.get(referrerColumn) ));
+ }
+ }
+
+ }
+
+ private IContentProvider buildTableTableContentProvider() {
+ return new JoinColumnsContentProvider();
+ }
+
+
+ private IBaseLabelProvider buildTableTableLabelProvider() {
+ return new JoinColumnsTableLabelProvider();
+ }
+
+
+ private void addColumnLayoutData(TableLayoutComposite layout) {
+ layout.addColumnData(new ColumnWeightData(50, true));
+ layout.addColumnData(new ColumnWeightData(50, true));
+ }
+
+
+ private void updateCellEditors(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues ){
+ joinColumnsTable.setColumnProperties(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES);
+ ComboBoxCellEditor[] editors = new ComboBoxCellEditor[JOINCOLUMNS_TABLE_COLUMN_PROPERTIES.length];
+
+ editors[JOINCOLUMN1_COLUMN_INDEX]= new ComboBoxCellEditor(joinColumnsTable.getTable(), referrerColumnValues, SWT.SINGLE);
+ editors[JOINCOLUMN2_COLUMN_INDEX]= new ComboBoxCellEditor(joinColumnsTable.getTable(), referencedColumnValues, SWT.SINGLE);
+
+ joinColumnsTable.setCellEditors(editors);
+ joinColumnsTable.setCellModifier(this.buildTableTableCellModifier(joinColumnsTable, referrerColumnValues, referencedColumnValues ));
+ }
+
+ public String[] getTableColumns(String tableName){
+ Schema schema = (Schema)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_SCHEMA);
+ Table table = schema.getTableNamed(tableName);
+ Iterator<Column> columns = table.columns() ;
+ List<String> list = new ArrayList<String>();
+ while( columns.hasNext() ){
+ list.add(columns.next().getName());
+ }
+ String[] ret = new String[list.size()];
+ list.toArray(ret);
+ return ret;
+ }
+
+ private ICellModifier buildTableTableCellModifier(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues) {
+ return new JoinColumnsCellModifier(joinColumnsTable, referrerColumnValues, referencedColumnValues);
+ }
+
+ /**
+ * A ContentProvider translates the SimpleJoin list into a Collection for display
+ *
+ */
+ private class JoinColumnsContentProvider implements IStructuredContentProvider {
+
+ JoinColumnsContentProvider() {
+ super();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+ public void dispose() {}
+ public Object[] getElements(Object inputElement) {
+ return ((Collection<?>) inputElement).toArray();
+ }
+ }
+
+ /**
+ * Simple value object used as model backing the JFace table
+ *
+ */
+ private class SimpleJoin {
+ public SimpleJoin(String foreignKey, String primaryKey) {
+ this.foreignKey = foreignKey;
+ this.primaryKey = primaryKey;
+ }
+ public String foreignKey;
+ public String primaryKey;
+
+ public String toString(){
+ return "["+ this.foreignKey + " = " + this.primaryKey + "]";
+ }
+ }
+
+ /**
+ * A CellModifier to update the join columns in the wizard data model
+ */
+ private class JoinColumnsCellModifier implements ICellModifier {
+ private TableViewer joinColumnsTable;
+ private String[] referrerColumnValues;
+ private String[] referencedColumnValues;
+ JoinColumnsCellModifier(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues) {
+ super();
+ this.joinColumnsTable = joinColumnsTable;
+ this.referrerColumnValues = referrerColumnValues;
+ this.referencedColumnValues = referencedColumnValues;
+ }
+
+ public boolean canModify(Object element, String property) {
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getValue(Object element, String property) {
+// SimpleJoin join = (SimpleJoin) element;
+// if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN2_COLUMN_INDEX])) {
+// return join.primaryKey;
+// }
+// return join.foreignKey;
+ // returnt the index of the value in the ComboxCellEditor
+ ArrayList<SimpleJoin> tableDataModel = (ArrayList<SimpleJoin>) joinColumnsTable.getInput();
+ for(int i=0; i< tableDataModel.size(); i ++ ){
+ if( tableDataModel.get(i) == element )
+ return new Integer(i);
+ }
+ return new Integer(0);
+
+ }
+
+ /**
+ * element is the selected TableItem
+ * value is the selected item index in the comboCellEditor
+ */
+ @SuppressWarnings("unchecked")
+ public void modify(Object element, String property, Object value) {
+ if ( ! (element instanceof TableItem)) {
+ return;
+ }
+ Integer index = (Integer)value;
+ TableItem item = (TableItem)element;
+ boolean unchanged = false;
+ SimpleJoin join = (SimpleJoin) item.getData();
+ if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN1_COLUMN_INDEX])) {
+ unchanged = join.foreignKey.equals( referrerColumnValues[ index.intValue() ] );
+ if (! unchanged) {
+
+ //update the wizard datamodel
+ TreeMap<String, String> joins = null;
+ if( joinColumnsTable == joinColumnsTable1 ){
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+ }else{
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+ }
+ joins.remove(join.foreignKey);
+ joins.put(referrerColumnValues[ index.intValue() ], join.primaryKey);
+
+ //Update the TableViewer model
+ join.foreignKey = referrerColumnValues[ index.intValue()];
+ joinColumnsTable.refresh();
+ }
+ return;
+ }
+
+ if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN2_COLUMN_INDEX])) {
+ unchanged = join.primaryKey.equals( referencedColumnValues[ index.intValue()] ) ;
+ if (! unchanged) {
+ //Update the TableViewer model
+ join.primaryKey = referencedColumnValues[ index.intValue()] ;
+
+ //Update wizard data model
+ TreeMap<String, String> joins = null;
+ if( joinColumnsTable == joinColumnsTable1 ){
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+ }else{
+ joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+ }
+ joins.put(join.foreignKey, join.primaryKey);
+
+ joinColumnsTable.refresh();
+ }
+ }
+
+
+ }
+
+ }
+
+ /**
+ * A table label provider to return the join column names for display
+ *
+ */
+ private final class JoinColumnsTableLabelProvider extends LabelProvider implements ITableLabelProvider {
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+ public String getColumnText(Object element, int columnIndex) {
+ if( !(element instanceof SimpleJoin) )
+ return null;
+ switch (columnIndex) {
+ case 0:
+ return ((SimpleJoin)element).foreignKey;
+ case 1:
+ return ((SimpleJoin)element).primaryKey;
+ default:
+ Assert.isTrue(false);
+ return null;
+ }
+ }
+ public String getText(Object element) {
+ return getColumnText(element, 0); // needed to make the sorter work
+ }
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java
new file mode 100644
index 0000000000..4a90b55e22
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java
@@ -0,0 +1,112 @@
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali UI.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class JptUiEntityGenMessages {
+ private static final String BUNDLE_NAME = "jpt_ui_entity_gen"; //$NON-NLS-1$
+ private static final Class<?> BUNDLE_CLASS = JptUiEntityGenMessages.class;
+ public static String GenerateEntitiesWizard_generateEntities;
+ public static String GenerateEntitiesWizard_fileWillBeOverwritten;
+ public static String WarningDialogTitle;
+ public static String GenerateEntitiesWizard_doNotShowWarning;
+ public static String GenerateEntitiesWizard_selectJPAProject;
+ public static String GenerateEntitiesWizard_selectJPAProject_msg;
+ public static String GenerateEntitiesWizard_tableSelectPage_selectTable;
+ public static String GenerateEntitiesWizard_tableSelectPage_chooseEntityTable;
+ public static String GenerateEntitiesWizard_tableSelectPage_synchronizeClasses;
+ public static String GenerateEntitiesWizard_tableSelectPage_tables;
+ public static String GenerateEntitiesWizard_tableSelectPage_tableColumn;
+ //Database connection group
+ public static String connection;
+ public static String addConnectionLink;
+ public static String connectLink;
+ public static String schemaInfo;
+ public static String schema;
+
+ //Default table gen properties
+ public static String GenerateEntitiesWizard_defaultTablePage_title;
+ public static String GenerateEntitiesWizard_defaultTablePage_desc;
+ public static String GenerateEntitiesWizard_defaultTablePage_domainJavaClass;
+ public static String GenerateEntitiesWizard_defaultTablePage_tableMapping;
+ public static String GenerateEntitiesWizard_tablePanel_className;
+ public static String GenerateEntitiesWizard_defaultTablePage_fetch;
+ public static String GenerateEntitiesWizard_defaultTablePage_collType;
+ public static String GenerateEntitiesWizard_defaultTablePage_sequence;
+ public static String GenerateEntitiesWizard_defaultTablePage_sequenceNote;
+ public static String GenerateEntitiesWizard_defaultTablePage_access;
+ public static String GenerateEntitiesWizard_defaultTablePage_keyGen;
+ public static String GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations;
+ public static String GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc;
+
+ //Asso figure
+ public static String manyToOneDesc;
+ public static String oneToOneDesc;
+ public static String manyToManyDesc;
+ //table association wizard page
+ public static String GenerateEntitiesWizard_assocPage_title;
+ public static String GenerateEntitiesWizard_assocPage_desc;
+ public static String GenerateEntitiesWizard_assocPage_label;
+ public static String GenerateEntitiesWizard_assocPage_newAssoc;
+ public static String GenerateEntitiesWizard_assocPage_delAssoc;
+ public static String GenerateEntitiesWizard_assocEditor_genAssoc;
+ public static String GenerateEntitiesWizard_assocEditor_entityRef;
+ public static String property;
+ public static String cascade;
+ public static String GenerateEntitiesWizard_assocEditor_setRef;
+ public static String GenerateEntitiesWizard_assocEditor_joinedWhen;
+ public static String GenerateEntitiesWizard_assocEditor_tableJoin;
+ public static String cardinality;
+ public static String selectCascadeDlgTitle;
+ //new association wizard
+ public static String GenerateEntitiesWizard_newAssoc_title;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_title;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_desc;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_assocKind;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_simpleAssoc;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_m2mAssoc;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_assocTables;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_table1;
+ public static String GenerateEntitiesWizard_newAssoc_tablesPage_table2;
+ public static String GenerateEntitiesWizard_newAssoc_colsPage_title;
+ public static String GenerateEntitiesWizard_newAssoc_colsPage_desc;
+ public static String GenerateEntitiesWizard_newAssoc_colsPage_label;
+ public static String add;
+ public static String remove;
+ public static String GenerateEntitiesWizard_newAssoc_cardinalityPage_title;
+ public static String GenerateEntitiesWizard_newAssoc_cardinalityPage_desc;
+ public static String manyToOne;
+ public static String oneToMany;
+ public static String oneToOne;
+ public static String manyToMany;
+ //select table dialog
+ public static String AnnotateJavaClassWizard_classMappingPage_selectTableDlgTitle;
+ public static String AnnotateJavaClassWizard_classMappingPage_selectTableDlgDesc;
+ //individual table and column gen properties
+ public static String GenerateEntitiesWizard_tablesAndColumnsPage_title;
+ public static String GenerateEntitiesWizard_tablesAndColumnsPage_desc;
+ public static String GenerateEntitiesWizard_tablesAndColumnsPage_labelTableAndColumns;
+ public static String GenerateEntitiesWizard_colPanel_genProp;
+ public static String GenerateEntitiesWizard_colPanel_colMapping;
+ public static String GenerateEntitiesWizard_colPanel_propName;
+ public static String GenerateEntitiesWizard_colPanel_propType;
+ public static String GenerateEntitiesWizard_colPanel_mapKind;
+ public static String GenerateEntitiesWizard_colPanel_colUpdateable;
+ public static String GenerateEntitiesWizard_colPanel_colInsertable;
+ public static String GenerateEntitiesWizard_colPanel_beanProp;
+ public static String GenerateEntitiesWizard_colPanel_getterScope;
+ public static String GenerateEntitiesWizard_colPanel_setterScope;
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+ }
+
+ private JptUiEntityGenMessages() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java
new file mode 100644
index 0000000000..ef6e3b5649
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+
+
+public class NewAssociationWizard extends Wizard {
+
+ public static String ASSOCIATION_SCHEMA = "ASSOCIATION_SCHEMA";
+ public static String ASSOCIATION_REFERRER_TABLE = "ASSOCIATION_REFERRER_TABLE";
+ public static String ASSOCIATION_REFERENCED_TABLE = "ASSOCIATION_REFERENCED_TABLE";
+ public static String ASSOCIATION_JOIN_COLUMNS1 = "ASSOCIATION_REFERRER_COLUMNS1";
+ public static String ASSOCIATION_JOIN_COLUMNS2 = "ASSOCIATION_REFERRER_COLUMNS2"; //used in MTM associations only
+ public static String ASSOCIATION_JOIN_TABLE = "ASSOCIATION_JOIN_TABLE"; // TreeMap<String, String>
+ public static String ASSOCIATION_CADINALITY = "ASSOCIATION_CADINALITY";
+
+ private JpaProject jpaProject;
+ private HashMap<String, Object> associationDataModel = new HashMap<String, Object>();
+
+ private ORMGenCustomizer customizer = null;
+
+ private AssociationTablesPage associationTablesPage;
+ private JoinColumnsPage joinColumnsPage;
+ private CardinalityPage cardinalityPage;
+
+ public NewAssociationWizard( JpaProject jpaProject, ORMGenCustomizer customizer ) {
+ super();
+ this.jpaProject = jpaProject;
+ this.customizer = customizer;
+ this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_title);
+
+ this.associationDataModel.put( NewAssociationWizard.ASSOCIATION_SCHEMA, this.customizer.getSchema());
+ this.associationDataModel.put( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1, new TreeMap<String, String>());
+ this.associationDataModel.put( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2, new TreeMap<String, String>());
+ }
+
+ public void addPages() {
+ super.addPages();
+ this.associationTablesPage = new AssociationTablesPage( customizer );
+ addPage(this.associationTablesPage);
+
+ this.joinColumnsPage = new JoinColumnsPage(customizer);
+ addPage(this.joinColumnsPage);
+
+ this.cardinalityPage = new CardinalityPage(customizer);
+ addPage(this.cardinalityPage);
+ }
+
+ public boolean performFinish() {
+ return true;
+ }
+
+ public ORMGenCustomizer getCustomizer (){
+ return customizer;
+ }
+
+ public JpaProject getJpaProject(){
+ return this.jpaProject;
+ }
+
+// public Schema getDefaultSchema() {
+// return getJpaProject().getDefaultDbSchema();
+// }
+//
+// private boolean projectDefaultSchemaExists() {
+// return ( this.getDefaultSchema() != null);
+// }
+
+ public HashMap<String, Object> getDataModel(){
+ return this.associationDataModel;
+ }
+
+ public void updateTableNames(){
+ IWizardPage[] pages = this.getPages();
+ for( IWizardPage page : pages){
+ ((NewAssociationWizardPage)page).updateWithNewTables();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Association getNewAssociation(){
+ String referrerTableName =getReferrerTableName();
+ String referencedTableName = getReferencedTableName();
+ List<String> referrerColNames = new ArrayList<String>();
+ List<String> referencedColNames = new ArrayList<String>();
+
+ String cardinality = (String)associationDataModel.get( NewAssociationWizard.ASSOCIATION_CADINALITY );
+ if( cardinality.equals(Association.MANY_TO_MANY) ){
+ return createManyToManyAssociation();
+ }
+
+ Object value = associationDataModel.get( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
+ if(value!=null){
+ TreeMap<String, String> joinColumns = (TreeMap<String, String>)value;
+ for( String pk : joinColumns.keySet()){
+ referrerColNames.add(pk);
+ referencedColNames.add( joinColumns.get(pk));
+ }
+ }
+
+ /*if one-to-many then convert it to many-to-one to be consistent
+ * with the associations computed from the db foreign keys.
+ * Don't see at this point how one-to-many would
+ * affect the generation.*/
+ if( cardinality.equals(Association.ONE_TO_MANY) ){
+ cardinality = Association.MANY_TO_ONE;
+
+ String temp1 = referrerTableName;
+ referrerTableName = referencedTableName;
+ referencedTableName = temp1;
+
+ List<String> temp2 = referrerColNames;
+ referrerColNames = referencedColNames;
+ referencedColNames = temp2;
+ }
+
+ Association association = null;
+ association = new Association(this.customizer, referrerTableName, referrerColNames , referencedTableName, referencedColNames);
+ association.setCardinality( cardinality );
+ association.setCustom(true);
+ return association;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Association createManyToManyAssociation() {
+ String referrerTableName =getReferrerTableName();
+ String joinTable = getJoinTableName();
+ String referencedTableName = getReferencedTableName();
+
+ List<String> referrerColNames = new ArrayList<String>();
+ List<String> referrerJoinColNames = new ArrayList<String>();
+ Object value = associationDataModel.get( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
+ if(value!=null){
+ TreeMap<String, String> joinColumns = (TreeMap<String, String>)value;
+ for( String pk : joinColumns.keySet()){
+ referrerColNames.add(pk);
+ referrerJoinColNames.add( joinColumns.get(pk));
+ }
+ }
+
+ value = associationDataModel.get( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2);
+ List<String> referencedColNames = new ArrayList<String>();
+ List<String> referencedJoinColNames = new ArrayList<String>();
+ if(value!=null){
+ TreeMap<String, String> joinColumns = (TreeMap<String, String>)value;
+ for( String pk : joinColumns.keySet()){
+ referencedJoinColNames.add(pk);
+ referencedColNames.add( joinColumns.get(pk));
+ }
+ }
+
+
+ Association association = null;
+ association = new Association(this.customizer, referrerTableName, referrerColNames,
+ referencedTableName, referencedColNames, joinTable, referrerJoinColNames, referencedJoinColNames);
+ return association;
+ }
+
+ String getReferrerTableName(){
+ return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_REFERRER_TABLE);
+ }
+
+ String getReferencedTableName(){
+ return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_REFERENCED_TABLE);
+ }
+
+ String getJoinTableName(){
+ return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_TABLE );
+ }
+
+ String getCardinality(){
+ return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_CADINALITY );
+ }
+
+} \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java
new file mode 100644
index 0000000000..6eaf73e9cb
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.HashMap;
+
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+
+
+public abstract class NewAssociationWizardPage extends WizardPage {
+
+ protected ORMGenCustomizer customizer;
+
+ public NewAssociationWizardPage(ORMGenCustomizer customizer, String name) {
+ super(name);
+ this.customizer = customizer ;
+ }
+
+ protected HashMap<String, Object> getWizardDataModel(){
+ return ((NewAssociationWizard)this.getWizard()).getDataModel();
+ }
+
+ protected String getReferrerTableName(){
+ return ((NewAssociationWizard)getWizard()).getReferrerTableName();
+ }
+
+ protected String getReferencedTableName(){
+ return ((NewAssociationWizard)getWizard()).getReferencedTableName();
+ }
+
+ protected String getJoinTableName(){
+ return ((NewAssociationWizard)getWizard()).getJoinTableName();
+ }
+
+ protected String getCardinality(){
+ return ((NewAssociationWizard)getWizard()).getCardinality() ;
+ }
+
+ public void updateWithNewTables() {
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java
new file mode 100644
index 0000000000..5189394c3c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+
+public class PromptJPAProjectWizardPage extends WizardPage {
+
+ private static String SELECT_PROJECT_PAGE_NAME = "SelectJPAProject"; //$NON-NLS-1$
+ private Table projTable;
+ private TableViewer projTableViewer;
+ private static int PROJECT_NAME_COLUMN_INDEX = 0;
+ private final String helpContextId;
+
+ protected PromptJPAProjectWizardPage( final String helpContextId ) {
+ super(SELECT_PROJECT_PAGE_NAME);
+ setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_selectJPAProject );
+ setMessage( JptUiEntityGenMessages.GenerateEntitiesWizard_selectJPAProject_msg );
+ this.helpContextId = helpContextId;
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NULL);
+ int nColumns= 1;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ composite.setLayout(layout);
+ Label label = new Label( composite, SWT.NONE );
+ label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_selectJPAProject );
+
+ projTableViewer = new TableViewer(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.VIRTUAL);
+ projTable = projTableViewer.getTable();
+ GridData gd = new GridData( SWT.FILL, SWT.FILL, true, true );
+ projTable.setLayoutData(gd);
+
+ projTable.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ handleJpaProjectSelection();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ });
+
+ projTableViewer = new TableViewer(projTable);
+ projTableViewer.setLabelProvider(new ProjectTableLabelProvider());
+ projTableViewer.setContentProvider(new ProjectTableContentProvider());
+ fillJpaProjectList();
+ setControl( composite );
+ validate();
+ }
+
+ private void handleJpaProjectSelection() {
+ if (projTable.getSelectionIndex() != -1) {
+ TableItem item = projTable.getItem(projTable.getSelectionIndex());
+ String projName = item.getText(0);
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName);
+ JpaProject jpaProj = JptCorePlugin.getJpaProject( project );
+ ((GenerateEntitiesFromSchemaWizard)getWizard()).setJpaProject(jpaProj);
+ validate();
+ }
+ }
+
+ private void fillJpaProjectList() {
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ List<String> projNames = new ArrayList<String>();
+ for ( IProject project : projects )
+ {
+ JpaProject jpaProj = JptCorePlugin.getJpaProject( project );
+ if ( jpaProj != null ) {
+ projNames.add(project.getName());
+ }
+ }
+ projTableViewer.setInput(projNames);
+ }
+
+ private void validate() {
+ if (projTable.getSelectionIndex() != -1)
+ setPageComplete(true);
+ else
+ setPageComplete(false);
+ }
+
+ @Override
+ public final void performHelp()
+ {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelp( this.helpContextId );
+ }
+
+ // inner classes
+ private final class ProjectTableLabelProvider extends LabelProvider implements ITableLabelProvider {
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ if (columnIndex == PROJECT_NAME_COLUMN_INDEX)
+ return PlatformUI.getWorkbench().getSharedImages().getImage(org.eclipse.ui.ide.IDE.SharedImages.IMG_OBJ_PROJECT);
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex)
+ {
+ assert element instanceof String;
+ String projectName = (String)element;
+ if (columnIndex == PROJECT_NAME_COLUMN_INDEX)
+ return projectName;
+ return null;
+ }
+ }
+
+ private final class ProjectTableContentProvider implements IStructuredContentProvider
+ {
+ public Object[] getElements(Object inputElement){
+ return ((Collection<?>) inputElement).toArray();
+ }
+
+ public void dispose(){}
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput){}
+
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java
new file mode 100644
index 0000000000..98b6b61d3e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Collection of utility methods to create SWT UI
+ *
+ */
+public class SWTUtil {
+ /**
+ * Set the layoutData of the input control to occupy specified number of columns
+ * @param c
+ * @param columns
+ */
+ public static void fillColumns(Control c, int columns){
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ c.setLayoutData(layoutData);
+ return ;
+ }
+
+ public static void fillColumnsWithIndent(Control c, int columns, int indent){
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ layoutData.horizontalIndent = indent ;
+ c.setLayoutData(layoutData);
+ return ;
+ }
+
+ public static Label createLabel(Composite container, int span, String text) {
+ Label label = new Label(container, SWT.NONE);
+ label.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ label.setLayoutData(gd);
+ return label;
+ }
+
+ /**
+ * Create a new label which occupies one grid column
+ * @param parent
+ * @param text
+ */
+ public static Label newLabel(Composite parent, String text) {
+ Label label = new Label( parent, SWT.NONE);
+ label.setText( text );
+ label.setLayoutData(new GridData());
+ return label;
+ }
+
+ /**
+ * Create a new label which occupies one grid column
+ * @param parent
+ * @param text
+ */
+ public static Label newLabelWithIndent(Composite parent, String text, int indent) {
+ Label label = new Label( parent, SWT.NONE);
+ label.setText( text );
+ GridData layoutData = new GridData();
+ layoutData.horizontalAlignment = SWT.BEGINNING;
+ layoutData.verticalAlignment = SWT.TOP ;
+ layoutData.horizontalIndent = indent ;
+ label.setLayoutData(layoutData);
+ return label;
+ }
+
+ /**
+ * Creates a separator line. Expects a <code>GridLayout</code> with at least 1 column.
+ *
+ * @param composite the parent composite
+ * @param nColumns number of columns to span
+ */
+ @SuppressWarnings("restriction")
+ public static void createSeparator(Composite composite, int nColumns) {
+ (new org.eclipse.jdt.internal.ui.wizards.dialogfields.Separator(
+ SWT.SEPARATOR | SWT.HORIZONTAL)).doFillIntoGrid(composite, nColumns, 5);
+ }
+
+
+ public static Button createButton(Composite container, int span, String text, int style) {
+ Button btn = new Button(container, style);
+ btn.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ btn.setLayoutData(gd);
+ return btn;
+ }
+
+ public static Combo createCombo(Composite container, int span ) {
+ Combo combo = new Combo(container, SWT.SINGLE | SWT.READ_ONLY);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ gd.grabExcessHorizontalSpace=true;
+ gd.horizontalAlignment = SWT.FILL;
+ combo.setLayoutData(gd);
+ return combo;
+ }
+
+ public static Text createText(Composite container, int span ) {
+ Text text = new Text(container, SWT.BORDER);
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ gd.grabExcessHorizontalSpace=true;
+ gd.horizontalAlignment = SWT.FILL;
+ text.setLayoutData(gd);
+ return text;
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java
new file mode 100644
index 0000000000..66311e56f4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+/**
+ * A database table selection dialog which allows user to filter tables by name
+ */
+public class SelectTableDialog extends ElementListSelectionDialog {
+
+ public SelectTableDialog(Shell shell){
+ super(shell, new ILabelProvider(){
+ public Image getImage(Object element) {
+ return CommonImages.createImage(CommonImages.TABLE_IMAGE) ;
+ }
+
+ public String getText(Object element) {
+ return element.toString();
+ }
+ public void addListener(ILabelProviderListener listener) {}
+ public void dispose() {}
+
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {}
+
+ });
+ this.setTitle( JptUiEntityGenMessages.AnnotateJavaClassWizard_classMappingPage_selectTableDlgTitle );//
+ this.setMessage( JptUiEntityGenMessages.AnnotateJavaClassWizard_classMappingPage_selectTableDlgDesc);//
+ }
+
+ public SelectTableDialog(Shell shell, Schema schema){
+ this(shell);
+
+ ArrayList<String> list = new ArrayList<String>();
+ Iterator<Table> tablesIt = schema.tables();
+ while (tablesIt.hasNext())
+ {
+ Table table = tablesIt.next();
+ list.add(table.getName());
+ }
+ this.setElements( list.toArray() );
+
+ }
+
+ public SelectTableDialog(Shell shell, List<String> tableNames){
+ this(shell);
+ this.setElements( tableNames.toArray() );
+ }
+ public String getSelectedTable()
+ {
+ String tableName = (String)this.getFirstResult();
+ return tableName ;
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java
new file mode 100644
index 0000000000..b36e5f6109
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java
@@ -0,0 +1,751 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.fillColumns;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.newLabel;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.newLabelWithIndent;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.jpt.gen.internal2.AssociationRole;
+import org.eclipse.jpt.gen.internal2.ORMGenColumn;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+public class TableAssociationsWizardPage extends WizardPage {
+
+ private JpaProject jpaProject;
+ private ORMGenCustomizer customizer ;
+
+ private AssociationsListComposite associationList;
+ private Association selectedAssociation;
+ private Button deleteAssociationLink ;
+ private Button createAssociationLink ;
+
+ //Controls in Association Edit Panel
+ private Composite associationsEditPanel ;
+ private Button generateAssociationCheckBox;
+ private Label cardinalityLabel ;
+ private Combo cardinalityCombo ;
+ /*whether to generate the referrer-->referenced role.*/
+ private Button referrerRoleCheckBox;
+ /*the name of the property in the referrer-->referenced role.*/
+ private Label referrerRolePropertyLabel;
+ private Text referrerRolePropertyField ;
+ /*the cascade in the referrer-->referenced role.*/
+ @SuppressWarnings("restriction")
+ private StringButtonDialogField referrerRoleCascadeField;
+ /*whether to generate the referenced->referrer role.*/
+ private Button referencedRoleCheckBox;
+ /*the name of the property in the referenced->referrer role.*/
+ private Label referencedRolePropertyLabel;
+ private Text referencedRolePropertyField ;
+ /*the cascade in the referenced->referrer role.*/
+ @SuppressWarnings("restriction")
+ private StringButtonDialogField referencedRoleCascadeField;
+ private Label joinConditionLabel;
+ private Text joinConditionText;
+
+ private Composite detailPanel ;
+ private StackLayout detailPanelStatckLayout ;
+ private Composite emptyPanel ;
+
+ protected TableAssociationsWizardPage(JpaProject jpaProject ) {
+ super("Table Associations"); //$NON-NLS-1$
+ this.jpaProject = jpaProject;
+ setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_title);
+ setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_desc);
+
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+
+ Composite composite = new Composite(parent, SWT.NULL);
+ int nColumns= 2 ;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ composite.setLayout(layout);
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.DIALOG_GENERATE_ENTITIES);
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_label );
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData( gd );
+
+ createAssociationsListPanel(composite);
+ createAddDeleteButtons(composite, nColumns);
+ SWTUtil.createSeparator(composite, nColumns);
+
+ createDetailPanel(composite);
+ setControl(composite);
+
+ composite.layout(true);
+ this.setPageComplete( true);
+
+ }
+
+ private void createAddDeleteButtons(Composite composite, int columns) {
+
+ Composite c = new Composite( composite, SWT.NONE);
+ fillColumns(c, 1);
+ c.setLayout( new GridLayout(1,true) );
+
+ createAssociationLink = new Button(c, SWT.NONE);
+ createAssociationLink.setToolTipText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_newAssoc );
+ createAssociationLink.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_ADD) );
+ createAssociationLink.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ launchNewAssociationsWizard();
+ }
+
+ });
+
+ deleteAssociationLink = new Button(c, SWT.NONE);
+ deleteAssociationLink.setForeground( new Color(Display.getDefault(), 0,0,255));
+ deleteAssociationLink.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_DELETE) );
+ deleteAssociationLink.setToolTipText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_delAssoc );
+ deleteAssociationLink.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ Association association = associationList.getSelectedAssociation();
+ if( association != null ){
+ ORMGenCustomizer customizer = getCustomizer();
+ customizer.deleteAssociation(association);
+ List<Association> associations = customizer.getAssociations();
+ associationList.updateAssociations(associations);
+ if( associations.size()==0 ){
+ hideAssociationDetail();
+ }
+ }
+ }
+ });
+ deleteAssociationLink.setEnabled(false);
+
+ }
+
+ private void createGenerateAssociationCheckbox(Composite composite, int columns) {
+ generateAssociationCheckBox = new Button(composite, SWT.CHECK);
+ generateAssociationCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_genAssoc);
+ generateAssociationCheckBox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ Association association = associationList.getSelectedAssociation();
+ if( association == null )
+ return;
+ association.setGenerated(generateAssociationCheckBox.getSelection());
+
+ updateAssociationEditPanel(association);
+ associationList.updateSelectedAssociation();
+ }
+
+ });
+
+ fillColumns(generateAssociationCheckBox, columns-1);
+ newLabel(composite, "");
+ }
+
+ @SuppressWarnings("restriction")
+ private void createGenerateReferrerRoleControls(Composite parent, int columns) {
+ referrerRoleCheckBox = new Button(parent, SWT.CHECK);
+ referrerRoleCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef );
+ referrerRoleCheckBox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ boolean generate = referrerRoleCheckBox.getSelection();
+ //referrerRolePropertyField.setEditable( generate );
+ referrerRolePropertyLabel.setEnabled( generate );
+ referrerRolePropertyField.setEnabled( generate );
+ referrerRoleCascadeField.setEnabled(generate);
+
+ //If both referencedRoleCheckBox and referencedRoleCheckBox unchecked,
+ //the association itself shouldn't be generated
+ if( !generate && !referencedRoleCheckBox.getSelection()){
+ generateAssociationCheckBox.setSelection(false);
+ cardinalityLabel.setEnabled( false );
+ cardinalityCombo.setEnabled(false);
+ referrerRoleCheckBox.setEnabled(false);
+ referencedRoleCheckBox.setEnabled(false);
+ }
+
+ directionalityCheckBoxChanged( );
+
+ if( generate ){
+ AssociationRole role = selectedAssociation.getReferrerRole();
+ referrerRolePropertyField.setText( role.getPropertyName() );
+ }
+ }
+
+ });
+
+ SWTUtil.fillColumnsWithIndent(referrerRoleCheckBox , columns-1, 20 );
+ newLabel(parent, "");//$NON-NLS-1$
+
+ referrerRolePropertyLabel = newLabelWithIndent( parent, JptUiEntityGenMessages.property, 40 ); //$NON-NLS-1$
+ referrerRolePropertyField = new Text( parent, SWT.BORDER);
+ fillColumns(referrerRolePropertyField, 2);
+ referrerRolePropertyField.addModifyListener(new ModifyListener(){
+ @SuppressWarnings("deprecation")
+ public void modifyText(ModifyEvent e) {
+ if( selectedAssociation.getReferrerRole() == null )
+ return;
+ String fieldName = referrerRolePropertyField.getText();
+ IStatus status = JavaConventions.validateFieldName( fieldName );
+ if( !status.matches(IStatus.ERROR) ){
+ selectedAssociation.getReferrerRole().setPropertyName(fieldName);
+ }
+ updateStatus(status);
+ }
+ });
+
+ Label label = new Label( parent, SWT.NONE);
+ label.setText( "" );//$NON-NLS-1$
+ label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+
+ referrerRoleCascadeField = new StringButtonDialogField( new IStringButtonAdapter(){
+ public void changeControlPressed(DialogField field) {
+ if( editCascade( selectedAssociation.getReferrerRole() )){
+ referrerRoleCascadeField.setText(selectedAssociation.getReferrerRole().getCascade());
+ }
+ }
+ }) ;
+ referrerRoleCascadeField.setLabelText( JptUiEntityGenMessages.cascade ); //$NON-NLS-1$
+ referrerRoleCascadeField.setButtonLabel(""); //$NON-NLS-1$
+ referrerRoleCascadeField.doFillIntoGrid(parent, 3);
+ referrerRoleCascadeField.getTextControl(parent).setEditable(false);
+ int maxFieldWidth = convertWidthInCharsToPixels(40);
+ LayoutUtil.setWidthHint(referrerRoleCascadeField.getTextControl(null), maxFieldWidth );
+ Button btn = referrerRoleCascadeField.getChangeControl(null);
+ GridData data = (GridData)btn.getLayoutData();
+ btn.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_BROWSE) );
+ data.horizontalAlignment = SWT.BEGINNING;
+ data.widthHint = 30;
+ btn.setLayoutData(data);
+
+ Label labelCtrl = referrerRoleCascadeField.getLabelControl(parent);
+ data = (GridData)labelCtrl.getLayoutData();
+ data.horizontalIndent = 40 ;
+ labelCtrl.setLayoutData(data);
+
+
+ label = new Label( parent, SWT.NONE);
+ label.setText( "" );//$NON-NLS-1$
+ label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+
+ }
+
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if( visible ){
+ hideAssociationDetail();
+ updateAssociationsListPanel();
+ }
+ }
+
+ private void hideAssociationDetail( ){
+ this.detailPanelStatckLayout.topControl = emptyPanel;
+ this.detailPanel.layout();
+ this.detailPanel.getParent().layout();
+ }
+
+ /**
+ * Updates the status line and the OK button according to the given status
+ *
+ * @param status status to apply
+ */
+ @SuppressWarnings("restriction")
+ protected void updateStatus(IStatus status) {
+ setPageComplete(!status.matches(IStatus.ERROR));
+
+ StatusUtil.applyToStatusLine(this, status);
+ if( status.getCode() == Status.OK ){
+ setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_desc);
+ }
+ }
+
+ @SuppressWarnings("restriction")
+ private void createGenerateReferencedRoleControls(Composite parent, int columns) {
+ referencedRoleCheckBox = new Button(parent, SWT.CHECK);
+ referencedRoleCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef );
+ referencedRoleCheckBox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ boolean generate = referencedRoleCheckBox.getSelection();
+ referencedRolePropertyLabel.setEnabled( generate);
+ referencedRolePropertyField.setEnabled( generate);
+ referencedRoleCascadeField.setEnabled(generate);
+
+ if( !generate && !referrerRoleCheckBox.getSelection()){
+ generateAssociationCheckBox.setSelection(false);
+ cardinalityCombo.setEnabled(false);
+ referrerRoleCheckBox.setEnabled(false);
+ referencedRoleCheckBox.setEnabled(false);
+ }
+ directionalityCheckBoxChanged();
+ if( generate ){
+ AssociationRole role = selectedAssociation.getReferencedRole();
+ referencedRolePropertyField.setText( role.getPropertyName() );
+ }
+ }
+
+ });
+
+ SWTUtil.fillColumnsWithIndent( referencedRoleCheckBox , columns-1, 20 );
+ newLabel(parent, "");//$NON-NLS-1$
+
+ referencedRolePropertyLabel = SWTUtil.newLabelWithIndent(parent, JptUiEntityGenMessages.property, 40 ); //$NON-NLS-1$
+
+ referencedRolePropertyField = new Text( parent, SWT.BORDER);
+ fillColumns(referencedRolePropertyField, 2);
+ referencedRolePropertyField.addModifyListener(new ModifyListener(){
+ public void modifyText(ModifyEvent e) {
+ if( selectedAssociation.getReferencedRole() == null )
+ return ;
+
+ String fieldName = referencedRolePropertyField.getText();
+ IStatus status = JavaConventions.validateIdentifier(fieldName,
+ CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+ if( !status.matches(IStatus.ERROR) ){
+ if( !fieldName.equals(selectedAssociation.getReferencedRole().getPropertyName()) )
+ selectedAssociation.getReferencedRole().setPropertyName(fieldName);
+ }
+ updateStatus(status);
+ }
+ });
+
+
+ Label label = new Label( parent, SWT.NONE);
+ label.setText( "" );//$NON-NLS-1$
+ label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+
+
+ referencedRoleCascadeField = new StringButtonDialogField( new IStringButtonAdapter(){
+ public void changeControlPressed(DialogField field) {
+ if( editCascade( selectedAssociation.getReferencedRole() ) ){
+ referencedRoleCascadeField.setText( selectedAssociation.getReferencedRole().getCascade() );
+ }
+ }
+ }) ;
+ referencedRoleCascadeField.setLabelText( JptUiEntityGenMessages.cascade ); //$NON-NLS-1$
+ referencedRoleCascadeField.setButtonLabel(""); //$NON-NLS-1$
+ referencedRoleCascadeField.doFillIntoGrid(parent, 3);
+ referencedRoleCascadeField.getTextControl(parent).setEditable( false);
+ int maxFieldWidth = convertWidthInCharsToPixels(40);
+ LayoutUtil.setWidthHint(referencedRoleCascadeField.getTextControl(null), maxFieldWidth );
+ Button btn = referencedRoleCascadeField.getChangeControl(null);
+ btn.setImage( CommonImages.createImage( CommonImages.DESC_BUTTON_BROWSE) );
+ GridData data = (GridData)btn.getLayoutData();
+ data.horizontalAlignment = SWT.BEGINNING;
+ data.widthHint = 30;
+ btn.setLayoutData(data);
+
+ Label labelCtrl = referencedRoleCascadeField.getLabelControl(parent);
+ data = (GridData)labelCtrl.getLayoutData();
+ data.horizontalIndent = 40 ;
+ labelCtrl.setLayoutData(data);
+
+ label = new Label( parent, SWT.NONE);
+ label.setText( "" );//$NON-NLS-1$
+ label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+
+ }
+
+ private void createDetailPanel(Composite composite ) {
+
+ this.detailPanel = new Composite( composite, SWT.NONE);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.grabExcessVerticalSpace = false;
+ this.detailPanel.setLayoutData(gd);
+ this.detailPanelStatckLayout = new StackLayout();
+ this.detailPanel.setLayout( this.detailPanelStatckLayout );
+
+ emptyPanel = new Composite( detailPanel, SWT.NONE);
+ emptyPanel.setLayoutData(new GridData());
+ detailPanelStatckLayout.topControl = emptyPanel;
+ detailPanel.layout();
+
+ composite.layout();
+ }
+
+
+ private Composite createAssociationsEditPanel(Composite composite, int columns) {
+ Composite parent = new Composite( composite, SWT.NONE);
+ fillColumns(parent, 4);
+
+ createGenerateAssociationCheckbox(parent,columns);
+ int nColumns= 4 ;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ parent.setLayout(layout);
+
+ //Cardinality
+ cardinalityLabel = new Label(parent, SWT.NONE);
+ cardinalityLabel.setText( JptUiEntityGenMessages.cardinality);
+ GridData gd = new GridData();
+ gd.horizontalIndent = 20;
+ cardinalityLabel.setLayoutData( gd );
+
+ cardinalityCombo = new Combo(parent, SWT.SINGLE | SWT.READ_ONLY );
+
+ fillColumns(cardinalityCombo, 1);
+
+ cardinalityCombo.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ selectedAssociation.setCardinality( cardinalityCombo.getText());
+ associationList.updateSelectedAssociation();
+ }
+ });
+
+ //Adding a filler column
+ Label label = new Label( parent, SWT.NONE);
+ label.setText( "");//$NON-NLS-1$
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = 2;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ label.setLayoutData(layoutData);
+
+ //Table join condition
+ joinConditionLabel = newLabelWithIndent(parent, JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_tableJoin, 20 );
+
+ joinConditionText = new Text( parent, SWT.MULTI | SWT.BORDER );
+ joinConditionText.setEditable(false);
+ joinConditionText.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen);
+ layoutData = new GridData();
+ layoutData.horizontalSpan = 2;
+ layoutData.verticalAlignment = SWT.TOP;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ layoutData.heightHint = 50;
+ joinConditionText.setLayoutData(layoutData);
+ newLabel(parent, "");//$NON-NLS-1$
+
+ //Generate UI controls for ReferrerRole
+ createGenerateReferrerRoleControls(parent, columns);
+
+ //Generate UI controls for ReferencedRole
+ createGenerateReferencedRoleControls(parent, columns);
+
+
+ return parent;
+ }
+
+ public boolean editCascade(AssociationRole role) {
+ CascadeDialog dlg = CascadeDialog.create(role);
+ if (dlg.open() == Window.CANCEL ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void createAssociationsListPanel(Composite parent) {
+ Composite composite = new Composite( parent, SWT.NULL );
+ composite.setLayout( new FillLayout());
+ composite.setBackground(new Color(Display.getDefault(),255, 0,0) );
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = 1;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = false;
+ layoutData.grabExcessVerticalSpace = true;
+ layoutData.widthHint = 400;
+ layoutData.heightHint = 400;
+ composite.setLayoutData(layoutData);
+
+ associationList = new AssociationsListComposite(composite, this);
+ }
+
+ private void launchNewAssociationsWizard() {
+ ORMGenCustomizer customizer = getCustomizer();
+ NewAssociationWizard wizard = new NewAssociationWizard(this.jpaProject, customizer );
+
+ WizardDialog dialog = new WizardDialog( this.getShell(), wizard);
+ dialog.create();
+ int returnCode = dialog.open();
+ if (returnCode == Window.OK) {
+ Association association = wizard.getNewAssociation();
+ if( association !=null ){
+ customizer.addAssociation(association);
+ updateForeignKeyColumnGenProperty(association);
+ updateAssociationsListPanel();
+ }
+ }
+ }
+ /**
+ * For user created association:
+ * If association is to be generated, no need to generate the getter/setter for the column itself
+ */
+ private void updateForeignKeyColumnGenProperty(Association association) {
+ //Need to process MANY_TO_ONE only since the the associations list are optimized to have MANY_TO_ONE
+ if( association.isCustom() && association.getCardinality().equals( Association.MANY_TO_ONE ) ){
+ boolean generateColumn = !association.isGenerated();
+ //The "MANY" side DB table
+ //ORMGenTable table1 = association.getReferrerTable();
+ //The "ONE" side DB table
+ //ORMGenTable table2 = association.getReferencedTable();
+ //The list of foreign key columns in the MANY side, should not be generated
+ //The list of primary keys in the ONE side, will be generated
+ //List<ORMGenColumn> list2 = association.getReferencedColumns();
+ List<ORMGenColumn> list1 = association.getReferrerColumns();
+ for(ORMGenColumn c : list1 ){
+ if( c.isGenerated() != generateColumn){
+ if( !generateColumn && DTPUtil.isPrimaryKey( c.getDbColumn() ) ){
+ continue;
+ }
+ c.setGenerated(generateColumn);
+ c.setInsertable(generateColumn);
+ c.setUpdateable(generateColumn);
+ }
+ }
+ }
+ }
+
+ private void updateAssociationsListPanel() {
+ ORMGenCustomizer customizer = getCustomizer();
+ //If user changed the connection or schema
+ if( this.customizer != customizer ){
+ this.customizer = customizer;
+ }
+ List<Association> associations = customizer.getAssociations();
+ this.associationList.updateAssociations( associations );
+ }
+
+ @SuppressWarnings("restriction")
+ public void updateAssociationEditPanel(Association association) {
+ this.selectedAssociation = association;
+
+ boolean enabled = association.isCustom();
+ this.deleteAssociationLink.setEnabled(enabled);
+
+ //Create and display the associationsEditPanel if it was hidden before
+ if( associationsEditPanel == null ){
+ associationsEditPanel = this.createAssociationsEditPanel(this.detailPanel, 4);
+ }
+ this.detailPanelStatckLayout.topControl = associationsEditPanel;
+ this.detailPanel.layout();
+ this.detailPanel.getParent().layout();
+
+ //Update the UI controls from the model
+ String table1Name = association.getReferrerTableName();
+ String table2Name = association.getReferencedTableName();
+ String joinTableName = association.getJoinTableName();
+
+ boolean isGenerated = association.isGenerated();
+ this.generateAssociationCheckBox.setSelection(isGenerated);
+ this.referrerRolePropertyLabel.setEnabled( isGenerated );
+ this.referrerRolePropertyField.setEnabled( isGenerated );
+ this.referrerRoleCheckBox.setEnabled( isGenerated );
+ this.referencedRolePropertyLabel.setEnabled( isGenerated );
+ this.referencedRolePropertyField.setEnabled( isGenerated );
+ this.referencedRoleCheckBox.setEnabled( isGenerated );
+ this.cardinalityLabel.setEnabled(isGenerated);
+ this.cardinalityCombo.setEnabled(isGenerated);
+ this.joinConditionLabel.setEnabled( isGenerated );
+ this.joinConditionText.setEnabled( isGenerated );
+
+ String cardinality = association.getCardinality();
+ if( Association.MANY_TO_MANY.equals( cardinality ) ){
+ cardinalityCombo.removeAll();
+ cardinalityCombo.add( Association.MANY_TO_MANY);
+ }else{
+ cardinalityCombo.removeAll();
+ cardinalityCombo.add( Association.MANY_TO_ONE);
+ cardinalityCombo.add( Association.ONE_TO_ONE);
+ }
+
+ cardinalityCombo.setText(cardinality);
+ cardinalityCombo.setEnabled(enabled);
+
+ String text = null;
+ //if MTM
+ if( Association.MANY_TO_MANY.equals( cardinality ) ){
+ text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef, table2Name, table1Name);
+ }else{
+ text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef, table2Name, table1Name);
+ }
+ this.referrerRoleCheckBox.setText(text);
+
+ //if OTO
+ if( Association.ONE_TO_ONE.equals( cardinality ) ){
+ text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef, table1Name, table2Name);
+ }else{
+ text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef, table1Name, table2Name);
+ }
+ this.referencedRoleCheckBox.setText(text);
+
+ //AssociationRole properties
+ AssociationRole referrerRole = association.getReferrerRole();
+ if( referrerRole != null){
+ this.referrerRoleCheckBox.setSelection( true );
+ this.referrerRolePropertyField.setEditable(true);
+ this.referrerRolePropertyField.setText(referrerRole.getPropertyName());
+ this.referrerRoleCascadeField.setEnabled(true);
+ String cascade = referrerRole.getCascade();
+ if( cascade!=null )
+ this.referrerRoleCascadeField.setText( cascade );
+
+ //if MTO:
+ if( Association.MANY_TO_ONE.equals( cardinality ) ){
+ this.referrerRoleCheckBox.setEnabled( false );
+ }
+ }else{
+ this.referrerRoleCheckBox.setSelection( false );
+ this.referrerRolePropertyLabel.setEnabled(false);
+ this.referrerRolePropertyField.setEditable(false);
+ this.referrerRolePropertyField.setText("");
+ this.referrerRoleCascadeField.setEnabled(false);
+ }
+
+ AssociationRole referencedRole = association.getReferencedRole();
+ if( referencedRole != null){
+ this.referencedRoleCheckBox.setSelection( true );
+ this.referencedRolePropertyLabel.setEnabled(true);
+ this.referencedRolePropertyField.setEditable(true);
+ this.referencedRolePropertyField.setText(referencedRole.getPropertyName());
+ this.referencedRoleCascadeField.setEnabled(true);
+ String cascade = referencedRole.getCascade();
+ if( cascade!=null )
+ this.referencedRoleCascadeField.setText(cascade);
+ }else{
+ this.referencedRoleCheckBox.setSelection( false );
+ this.referencedRolePropertyLabel.setEnabled(false);
+ this.referencedRolePropertyField.setEditable(false);
+ this.referencedRolePropertyField.setText("");
+ this.referencedRoleCascadeField.setEnabled(false);
+ }
+
+ //Join conditions
+ updateJoinConditions(association, table1Name, table2Name, joinTableName);
+ }
+
+ private void updateJoinConditions(Association association,
+ String table1Name, String table2Name, String joinTableName) {
+ String text = "%s";
+ if( joinTableName == null ){
+ StringBuilder strText = new StringBuilder();
+ //text = JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen;
+ List<String> columnList1 = association.getReferrerColumnNames() ;
+ List<String> columnList2 = association.getReferencedColumnNames();
+ for( int i=0; i < columnList1.size(); i++){
+ strText.append( table1Name + "." + columnList1.get(i) );//$NON-NLS-1$
+ strText.append( "=" );//$NON-NLS-1$
+ strText.append( table2Name + "." + columnList2.get(i) );//$NON-NLS-1$
+ if( i < columnList1.size()-1 )
+ strText.append( "\n AND " );//$NON-NLS-1$
+ }
+ joinConditionText.setText( String.format( text , strText.toString()) );
+ }else{
+ StringBuilder strText = new StringBuilder();
+ //text = JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen;
+ List<String> columnList1 = association.getReferrerColumnNames() ;
+ List<String> joinColumnList1 = association.getReferrerJoinColumnNames() ;
+ for( int i=0; i < columnList1.size(); i++){
+ strText.append( table1Name + "." + columnList1.get(i) );//$NON-NLS-1$
+ strText.append( "=" );//$NON-NLS-1$
+ strText.append( joinTableName + "." + joinColumnList1.get(i) );
+ strText.append( "\n AND " );//$NON-NLS-1$
+ }
+
+ List<String> joinTableColumnList2 = association.getReferencedJoinColumnNames();
+ List<String> columnList2 = association.getReferencedColumnNames();
+ for( int i=0; i < joinTableColumnList2.size(); i++){
+ strText.append( joinTableName + "." + joinTableColumnList2.get(i) );
+ strText.append( "=" );//$NON-NLS-1$
+ strText.append( table2Name + "." + columnList2.get(i) );//$NON-NLS-1$
+ if( i < joinTableColumnList2.size()-1 )
+ strText.append( "\n AND " );//$NON-NLS-1$
+ }
+
+ joinConditionText.setText( String.format( text , strText.toString()) );
+
+ }
+ }
+
+ /**
+ * Called when one of referrerRoleCheckBox or referencedRoleCheckBox
+ * changes value.
+ *
+ */
+ private void directionalityCheckBoxChanged() {
+ String dir;
+ if (referrerRoleCheckBox.getSelection()) {
+ dir = referencedRoleCheckBox.getSelection() ? Association.BI_DI : Association.NORMAL_DI;
+ } else {
+ if (referencedRoleCheckBox.getSelection()) {
+ dir = Association.OPPOSITE_DI;
+ } else {
+ dir = null;
+ }
+ }
+ if (dir != null) {
+ selectedAssociation.setDirectionality(dir);
+ } else {
+ selectedAssociation.setGenerated(false);
+ }
+
+ this.associationList.updateSelectedAssociation();
+ }
+
+ private ORMGenCustomizer getCustomizer(){
+ GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
+ return wizard.getCustomizer();
+ }
+
+
+ @Override
+ public final void performHelp()
+ {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java
new file mode 100644
index 0000000000..7fd0e75a64
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.GridLayout;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * A draw2D figure representing a database table
+ *
+ */
+public class TableFigure extends Figure {
+ public static Color tableColor = new Color(null,220,232,241);
+ public static Font tableFont = new Font(null, "Arial", 8, SWT.NONE);
+ public static Color disabledColor = ColorConstants.white;
+ public static Color borderColor = new Color( null, 14,66,115);
+
+ public static final int OUTLINE_CORNER_RADIUS = 6;
+
+ public TableFigure(String name) {
+ GridLayout gl = new GridLayout();
+ gl.marginHeight = 2;
+ gl.marginWidth = 10;
+ setLayoutManager(gl);
+
+ setBorder(new LineBorder(tableColor,0));
+ setBackgroundColor(tableColor);
+ setOpaque(true);
+ setSize(150, 20);
+
+ Label nameLabel = new Label("", CommonImages.createImage( CommonImages.TABLE_OBJ_IMAGE));
+ nameLabel.setFont(tableFont);
+ nameLabel.setText(name);
+ nameLabel.setForegroundColor(borderColor);
+ nameLabel.setLabelAlignment(PositionConstants.CENTER);
+ add(nameLabel);
+ }
+
+ protected void paintClientArea(Graphics graphics)
+ {
+ super.paintClientArea(graphics);
+ graphics.pushState();
+ Rectangle r = getBounds().getCopy();
+ graphics.drawRoundRectangle(r.expand(new Insets(-1, -1, -2, -2)),
+ OUTLINE_CORNER_RADIUS, OUTLINE_CORNER_RADIUS );
+ graphics.popState();
+ }
+
+ public void setEnabled(boolean enabled ) {
+ super.setEnabled(enabled);
+ if( enabled ){
+ setBackgroundColor(tableColor);
+ }else{
+ setBackgroundColor(disabledColor);
+ }
+ }
+} \ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java
new file mode 100644
index 0000000000..c0c4293cc7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.gen.internal2.ORMGenTable;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * The UI panel for setting the default and specific
+ * table entity generation properties.
+ *
+ */
+class TableGenPanel
+{
+ WizardPage wizardPage ;
+
+ private Text classNameField; // used in setting individual table/entity generation only
+
+ private Combo idGeneratorCombo;
+ private Text sequenceNameField;
+
+ private Button entityAccessField;
+ private Button entityAccessProperty;
+ private Button associationFetchEager;
+ private Button associationFetchLazy;
+
+ private Button collectionTypeSet;
+ private Button collectionTypeList;
+
+ private Button generateOptionalAnnotations;
+
+ private Label sequenceNameNoteLabel;
+
+ private boolean isUpdatingControls;
+
+ private ORMGenTable mTable;
+
+ private boolean isDefaultTable = false;
+
+ private static Color NOTE_LABEL_COLOR = new Color( Display.getDefault(), 102,102,102);
+
+ public TableGenPanel(Composite parent, int columns , boolean isDefaultTable, WizardPage wizardPage ){
+ super();
+ this.wizardPage = wizardPage;
+ this.isDefaultTable = isDefaultTable;
+ createTableMappingPropertiesGroup(parent, columns);
+ SWTUtil.createLabel(parent, 4, "");
+ }
+
+ protected void createTableMappingPropertiesGroup(Composite composite, int columns) {
+ Group parent = new Group(composite, SWT.NONE );
+ parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_tableMapping);
+ parent.setLayout(new GridLayout(columns, false));
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ parent.setLayoutData(layoutData);
+
+ createClassNameControl(parent, columns);
+
+ createIdGeneratorControls(parent, columns);
+ createEntityAccessControls(parent, columns);
+
+ //AssociationFetch and CollectionType only available for default table generation
+ if( isDefaultTable ){
+ createAssociationFetchControls(parent, columns);
+ createCollectionTypeControls(parent, columns);
+ createGenerateOptionalAnnotationControls(parent, columns);
+ }
+ }
+
+ private void createGenerateOptionalAnnotationControls(Group parent, int columns) {
+ SWTUtil.createLabel(parent, 1, "");
+ generateOptionalAnnotations = new Button(parent, SWT.CHECK );
+ generateOptionalAnnotations.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations);
+ generateOptionalAnnotations.setToolTipText(JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc);
+
+ GridData gd = new GridData();
+ gd.horizontalSpan = columns-1;
+ gd.horizontalIndent = 3 ;
+ generateOptionalAnnotations.setLayoutData(gd);
+ generateOptionalAnnotations.addSelectionListener(new SelectionListener(){
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ boolean selected = generateOptionalAnnotations.getSelection();
+ mTable.setGenerateDDLAnnotations(selected);
+ }
+ });
+ }
+
+ private void createClassNameControl(Composite parent, int columns) {
+ //Customize class name for specific table only
+ if( !isDefaultTable ){
+ SWTUtil.createLabel( parent, 1 , JptUiEntityGenMessages.GenerateEntitiesWizard_tablePanel_className );
+
+ classNameField = new Text(parent, SWT.SINGLE | SWT.BORDER );
+ //mPackageNameField.setEditable(false);
+ SWTUtil.fillColumns(classNameField,3);
+ classNameField.addModifyListener(new ModifyListener(){
+ @SuppressWarnings({ "deprecation" })
+ public void modifyText(ModifyEvent e) {
+ if (e.getSource() == null || !isUpdatingControls) {
+ String className = classNameField.getText();
+ IStatus status = JavaConventions.validateJavaTypeName( className );
+ if( !status.matches(IStatus.ERROR) ){
+ mTable.setClassName( className );
+ wizardPage.setErrorMessage(null);
+ }else{
+ wizardPage.setErrorMessage(status.getMessage());
+ }
+ }
+ }
+ });
+ }
+ }
+
+ class AssociationFetchListener implements SelectionListener{
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!isUpdatingControls) {
+ Button radioBtn = (Button)e.getSource();
+ mTable.setDefaultFetch( radioBtn.getData().toString());
+ }
+ }
+ }
+
+ private void createAssociationFetchControls(Composite composite, int columns) {
+ SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_fetch );
+
+ Composite parent = new Composite( composite, SWT.NONE);
+ parent.setLayout(new RowLayout());
+ SWTUtil.fillColumns( parent , 3);
+
+ associationFetchEager = new Button( parent, SWT.RADIO );
+ associationFetchEager.setText( "&Eager");
+ associationFetchEager.setData( ORMGenTable.EAGER_FETCH );
+
+ associationFetchLazy = new Button( parent, SWT.RADIO );
+ associationFetchLazy.setText( "La&zy");
+ associationFetchLazy.setData( ORMGenTable.LAZY_FETCH );
+
+ AssociationFetchListener associationFetchListener = new AssociationFetchListener();
+ associationFetchLazy.addSelectionListener( associationFetchListener );
+ associationFetchEager.addSelectionListener( associationFetchListener );
+
+ }
+
+ class CollectionTypeListener implements SelectionListener{
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!isUpdatingControls) {
+ Button radioBtn = (Button)e.getSource();
+ mTable.setDefaultCollectionType( radioBtn.getData().toString());
+ }
+ }
+ }
+
+ private void createCollectionTypeControls(Composite composite, int columns){
+ SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_collType );
+
+ Composite parent = new Composite( composite, SWT.NONE);
+ parent.setLayout(new RowLayout());
+ SWTUtil.fillColumns( parent , 3);
+
+ this.collectionTypeSet = new Button( parent, SWT.RADIO);
+ this.collectionTypeSet.setText( "java.util.Se&t");
+ this.collectionTypeSet.setData( ORMGenTable.SET_COLLECTION_TYPE );
+ this.collectionTypeList = new Button( parent, SWT.RADIO);
+ this.collectionTypeList.setText("java.util.&List");
+ this.collectionTypeList.setData(ORMGenTable.LIST_COLLECTION_TYPE);
+
+ CollectionTypeListener collectionTypeListener = new CollectionTypeListener();
+ collectionTypeList.addSelectionListener( collectionTypeListener );
+ collectionTypeSet.addSelectionListener( collectionTypeListener );
+
+ }
+
+
+ public void setORMGenTable(ORMGenTable table) {
+ mTable = table;
+
+ isUpdatingControls = true;
+
+ try {
+ //ClassNameField is not available for default table
+ if(classNameField!= null )
+ classNameField.setText( mTable.getClassName() );
+
+ final List<String> schemes = this.mTable.getCustomizer().getAllIdGenerators();
+ String[] values = new String[schemes.size()];
+ schemes.toArray(values);
+ idGeneratorCombo.setItems( values );
+ idGeneratorCombo.setText( mTable.getIdGenerator());
+
+ String sequenceName = mTable.isDefaultsTable() ? mTable.getSequence() : mTable.getFormattedSequence();
+ sequenceName = ( sequenceName==null?"":sequenceName );
+ sequenceNameField.setText( sequenceName );
+ if( sequenceName.length()> 0 ){
+ sequenceNameField.setEnabled(true);
+ sequenceNameNoteLabel.setEnabled(true);
+ }else{
+ sequenceNameField.setEnabled(false);
+ sequenceNameNoteLabel.setEnabled(false);
+ }
+
+ String access = mTable.getAccess() ;
+ if( ORMGenTable.FIELD_ACCESS.equals( access ) ){
+ this.entityAccessField.setSelection( true );
+ }else{
+ this.entityAccessProperty.setSelection( true );
+ }
+
+ if(associationFetchLazy!=null && associationFetchEager != null ){
+ String defaultFetch = mTable.getDefaultFetch();
+ if( ORMGenTable.EAGER_FETCH.equals( defaultFetch ) )
+ associationFetchEager.setSelection(true);
+ else
+ associationFetchLazy.setSelection(true);
+ }
+
+ //DefautlTable only
+ if(collectionTypeList!=null){
+ String cType = mTable.getDefaultCollectionType();
+ if( ORMGenTable.LIST_COLLECTION_TYPE.equals( cType ) ){
+ this.collectionTypeList.setSelection( true );
+ }else{
+ this.collectionTypeSet.setSelection( true );
+ }
+
+ this.generateOptionalAnnotations.setSelection( mTable.isGenerateDDLAnnotations());
+ }
+
+ } catch (Exception e) {
+ JptUiPlugin.log(e);
+ }
+
+ isUpdatingControls = false;
+ }
+
+ private void createIdGeneratorControls(Composite parent, int columns) {
+ SWTUtil.createLabel(parent, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_keyGen );
+
+ idGeneratorCombo = new Combo(parent,SWT.SINGLE | SWT.READ_ONLY);
+ SWTUtil.fillColumns(idGeneratorCombo,3);
+
+ idGeneratorCombo.addSelectionListener( new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ if (isUpdatingControls) {
+ return;
+ }
+
+ idGenChanged();
+ }});
+
+ SWTUtil.createLabel(parent, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_sequence );
+ sequenceNameField = new Text( parent, SWT.SINGLE | SWT.BORDER );
+
+ SWTUtil.fillColumns(sequenceNameField, 3);
+ sequenceNameField.addModifyListener(new ModifyListener(){
+ public void modifyText(ModifyEvent e) {
+ if (e.getSource() == null || !isUpdatingControls) {
+
+ if( idGeneratorCombo.getText().equals("sequence")){
+ String sequenceName = sequenceNameField.getText();
+ if( sequenceName.toLowerCase().indexOf("$table")>=0 ||
+ sequenceName.toLowerCase().indexOf("$pk")>=0 ){
+ sequenceName = convertVarToLowerCase("$table", sequenceName);
+ sequenceName = convertVarToLowerCase("$pk", sequenceName);
+ }
+ if( sequenceName.trim().length() != 0 ){
+ mTable.setSeqence( sequenceName );
+ wizardPage.setErrorMessage(null);
+ wizardPage.setPageComplete(true);
+ }else{
+ wizardPage.setErrorMessage("Please specify a sequence name.");
+ wizardPage.setPageComplete(false);
+ }
+ }else{
+ wizardPage.setErrorMessage(null);
+ wizardPage.setPageComplete(true);
+ }
+ }
+ }
+
+ private String convertVarToLowerCase(String var, String sequenceName) {
+ int n = sequenceName.toLowerCase().indexOf( var );
+ if( n==0 ){
+ return var + sequenceName.substring( var.length());
+ }else if( n >0 ){
+ return sequenceName.substring(0,n) + var + sequenceName.substring( n + var.length());
+ }
+ return sequenceName;
+ }
+ });
+
+ SWTUtil.newLabel(parent, "");//$NON-NLS-1$
+ sequenceNameNoteLabel = new Label(parent, SWT.NONE);
+ String text =String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_sequenceNote,
+ ORMGenTable.TABLE_SEQ_PATTERN, ORMGenTable.PK_SEQ_PATTERN);
+ sequenceNameNoteLabel.setText( text ) ;
+ sequenceNameNoteLabel.setEnabled(false);
+ SWTUtil.fillColumns( sequenceNameNoteLabel, 3);
+ }
+
+ private void idGenChanged() {
+ String scheme = (String)idGeneratorCombo.getText();
+ mTable.setIdGenerator(scheme);
+
+ boolean isSequence = this.mTable.getCustomizer().getSequenceIdGenerators().contains(scheme);
+ if (!isSequence) {
+ sequenceNameField.setText("");
+ sequenceNameField.setEnabled(false);
+ mTable.setSeqence(null);
+ sequenceNameNoteLabel.setEnabled(false);
+ }else{
+ sequenceNameField.setEnabled(true);
+ sequenceNameNoteLabel.setForeground( NOTE_LABEL_COLOR );
+ sequenceNameNoteLabel.setEnabled(true);
+ if( sequenceNameField.getText().length()==0 ) {
+ String newMessage = "Please specify a sequence name";
+ this.wizardPage.setErrorMessage(newMessage);
+ this.wizardPage.setPageComplete(false);
+ }else{
+ this.wizardPage.setErrorMessage(null);
+ this.wizardPage.setPageComplete(true);
+ }
+ }
+ }
+
+ class EntityAccessFetchListener implements SelectionListener{
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ public void widgetSelected(SelectionEvent e) {
+ if (!isUpdatingControls) {
+ Button radioBtn = (Button)e.getSource();
+ mTable.setAccess( radioBtn.getData().toString() );
+ }
+ }
+ }
+
+ private void createEntityAccessControls(Composite composite, int columns) {
+ SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_access );
+
+ Composite parent = new Composite( composite, SWT.NONE);
+ SWTUtil.fillColumns( parent , 3);
+ parent.setLayout(new RowLayout());
+
+ entityAccessField = new Button( parent, SWT.RADIO );
+ entityAccessField.setText( "&Field" ); //$NON-NLS1$
+ entityAccessField.setData( ORMGenTable.FIELD_ACCESS);
+
+ entityAccessProperty = new Button( parent, SWT.RADIO );
+ entityAccessProperty.setText( "&Property" );//$NON-NLS1$
+ entityAccessProperty.setData( ORMGenTable.PROPERTY_ACCESS );
+
+ EntityAccessFetchListener entityAccessFetchListener = new EntityAccessFetchListener();
+ entityAccessField.addSelectionListener( entityAccessFetchListener );
+ entityAccessProperty.addSelectionListener( entityAccessFetchListener );
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java
new file mode 100644
index 0000000000..c51ef8ad58
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal2.ORMGenColumn;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal2.ORMGenTable;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.PlatformUI;
+
+public class TablesAndColumnsCustomizationWizardPage extends NewTypeWizardPage {
+
+ @SuppressWarnings("unused")
+ private JpaProject jpaProject;
+
+ private TreeViewer tableColumnTreeViewer ;
+
+ private Composite detailPanel ;
+ private StackLayout detailPanelStatckLayout ;
+ private Composite tableGenDetatilGroup;
+ private ColumnGenPanel columnGenPanel;
+ private Composite columnGenDetatilGroup;
+ private TableGenPanel tableGenPanel;
+ private ORMGenTable selectedTable;
+
+ private ORMGenCustomizer customizer;
+
+ protected TablesAndColumnsCustomizationWizardPage(JpaProject jpaProject ) {
+ super(true, "TablesAndColumnsCustomizationWizardPage"); //$NON-NLS-1$
+ this.jpaProject = jpaProject;
+ setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_tablesAndColumnsPage_title );
+ setMessage( JptUiEntityGenMessages.GenerateEntitiesWizard_tablesAndColumnsPage_desc);
+ }
+
+ // -------- Initialization ---------
+ /**
+ * The wizard owning this page is responsible for calling this method with the
+ * current selection. The selection is used to initialize the fields of the wizard
+ * page.
+ *
+ * @param selection used to initialize the fields
+ */
+ void init(IStructuredSelection selection) {
+ if( jpaProject != null ){
+ IJavaElement jelem = this.jpaProject.getJavaProject();
+ initContainerPage(jelem);
+ initTypePage(jelem);
+ }
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+ Composite composite = new Composite(parent, SWT.NULL);
+ int nColumns= 1 ;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ composite.setLayout(layout);
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.DIALOG_GENERATE_ENTITIES);
+
+ createTableAndColumnsListPanel(composite, 1);
+
+ SWTUtil.createLabel( composite, 1, ""); //$NON-NLS-1$
+
+ SWTUtil.createSeparator(composite, 1);
+
+ createGenerateDetailGroup(composite, 1);
+
+ setControl(composite);
+ this.setPageComplete( true );
+ }
+
+ /**
+ * A panel with JFace TreeViewer showing tables and columns to be generated into JPA entities
+ *
+ * @param parent
+ * @param columns
+ */
+ private void createTableAndColumnsListPanel(Composite parent, int columns) {
+ Label label = new Label(parent, columns );
+ label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_tablesAndColumnsPage_labelTableAndColumns );
+ SWTUtil.fillColumns( label , columns);
+
+ GridData data = new GridData();
+ data.horizontalSpan = columns;
+ data.verticalAlignment = SWT.FILL;
+ data.horizontalAlignment = SWT.FILL;
+ data.grabExcessHorizontalSpace = true;
+ data.heightHint = 200;
+ data.grabExcessVerticalSpace = true;
+
+ tableColumnTreeViewer = new TreeViewer(parent);
+ tableColumnTreeViewer.getTree().setLayoutData( data);
+ tableColumnTreeViewer.setContentProvider(new TableColumnTreeContentProvider());
+ tableColumnTreeViewer.setLabelProvider(new TableColumnTreeLabelProvider());
+
+ tableColumnTreeViewer.addSelectionChangedListener( new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent event) {
+ updateDetailPanel(event.getSelection());
+ }
+
+ });
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if(visible){
+ ORMGenCustomizer customizer = getCustomizer();
+ //If user changed the connection or schema
+ if( this.customizer != customizer ){
+ this.customizer = customizer;
+ tableColumnTreeViewer.setInput( customizer );
+ }else{
+ tableColumnTreeViewer.refresh();
+ }
+ List<String> tableNames = this.customizer.getTableNames();
+
+ //Select the first table
+ ORMGenTable ormGenTable = this.customizer.getTable(tableNames.get(0));
+ updateTabelGenDetail( ormGenTable );
+ }
+ }
+
+
+ private void updateDetailPanel(ISelection selection) {
+ TreeSelection ts = (TreeSelection)selection;
+ Object selectedObject = ts.getFirstElement();
+ if( selectedObject instanceof ORMGenTable ){
+ updateTabelGenDetail( (ORMGenTable)selectedObject );
+ }else if( selectedObject instanceof ORMGenColumn ){
+ updateColumnGenDetail( (ORMGenColumn)selectedObject );
+ }
+ }
+
+ private void updateColumnGenDetail(ORMGenColumn column) {
+ if(columnGenDetatilGroup==null){
+ columnGenDetatilGroup = new Composite(detailPanel, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 4;
+ columnGenDetatilGroup.setLayout(gridLayout);
+ this.columnGenPanel = new ColumnGenPanel(columnGenDetatilGroup, 4, getCustomizer() , this );
+ }
+ columnGenPanel.setColumn(column);
+ this.detailPanelStatckLayout.topControl = columnGenDetatilGroup;
+ this.detailPanel.layout();
+ detailPanel.getParent().layout();
+ }
+
+ private void updateTabelGenDetail(ORMGenTable table) {
+ this.selectedTable = table;
+ if(tableGenDetatilGroup==null){
+ tableGenDetatilGroup = new Composite(detailPanel, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 4;
+ tableGenDetatilGroup.setLayout(gridLayout);
+
+ this.tableGenPanel = new TableGenPanel(tableGenDetatilGroup, 4 , false, this );
+ createDomainJavaClassesPropertiesGroup(tableGenDetatilGroup, 4 );
+ }
+ tableGenPanel.setORMGenTable(table);
+
+ this.detailPanelStatckLayout.topControl = tableGenDetatilGroup;
+ this.detailPanel.layout();
+
+ String baseClass = table.getExtends();
+ if( baseClass!= null )
+ setSuperClass(baseClass, true);
+
+ setSuperInterfaces( table.getImplements(), true);
+
+ detailPanel.getParent().layout();
+ }
+
+ protected void createDomainJavaClassesPropertiesGroup(Composite composite, int columns) {
+ Group parent = new Group( composite, SWT.NONE);
+ parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_domainJavaClass );
+ parent.setLayout(new GridLayout(columns, false));
+ SWTUtil.fillColumns( parent, columns);
+
+ createSuperClassControls(parent, columns);
+ createSuperInterfacesControls(parent, columns);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#superClassChanged()
+ */
+ protected IStatus superClassChanged() {
+ IStatus status = super.superClassChanged();
+ String baseClass = getSuperClass();
+ if(baseClass!=null && this.selectedTable!=null ){
+ String oldBaseClass = this.selectedTable.getExtends();
+ if( !oldBaseClass.equals(baseClass ))
+ this.selectedTable.setExtends(baseClass);
+ }
+ return status;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#addSuperInterface(java.lang.String)
+ */
+ @SuppressWarnings("unchecked")
+ public boolean addSuperInterface(String superInterface) {
+ super.addSuperInterface(superInterface);
+ List interfaces = getSuperInterfaces();
+ if(this.selectedTable!=null)
+ this.selectedTable.setImplements(interfaces);
+ return true;
+ }
+
+ protected void handleFieldChanged(String fieldName) {
+ super.handleFieldChanged(fieldName);
+ if( this.fSuperClassStatus.matches(IStatus.ERROR)){
+ updateStatus(fSuperClassStatus);
+ }else{
+ setMessage("", IMessageProvider.NONE);
+ setErrorMessage(null);
+ }
+
+ }
+
+ private ORMGenCustomizer getCustomizer(){
+ GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
+ return wizard.getCustomizer();
+ }
+ /**
+ * Content provider, and label provider for the DB Table/Column TreeViewer
+ *
+ */
+ class TableColumnTreeContentProvider implements ITreeContentProvider {
+ public Object[] getElements(Object inputElement) {
+ if( inputElement instanceof ORMGenCustomizer ){
+ ORMGenCustomizer input = (ORMGenCustomizer )inputElement;
+ List<String> tableNameList = input.getGenTableNames();
+ List<ORMGenTable> ret = new ArrayList<ORMGenTable>();
+ for(String t : tableNameList){
+ ORMGenTable ormGenTable = getCustomizer().getTable( t );
+ ret.add( ormGenTable );
+ }
+ return ret.toArray();
+ }
+ return new Object[]{};
+ }
+ public Object[] getChildren(Object parentElement) {
+ if( parentElement instanceof ORMGenTable ){
+ ORMGenTable table = (ORMGenTable) parentElement;
+ List<ORMGenColumn> columns = table.getColumns();
+ List<ORMGenColumn> ret = new ArrayList<ORMGenColumn>();
+ boolean isCompositePk = DTPUtil.getPrimaryKeyColumnNames(table.getDbTable()).size()>1;
+ for( ORMGenColumn col : columns){
+ if( col.isForeignKey() )
+ continue;
+ if( col.isPrimaryKey() && isCompositePk ){
+ continue;
+ }
+ ret.add(col);
+ }
+ return ret.toArray();
+ }
+ return new Object[]{};
+ }
+ public Object getParent(Object element) {
+ if( element instanceof ORMGenColumn){
+ return null;
+ }
+ return null;
+ }
+ public boolean hasChildren(Object element) {
+ return( element instanceof ORMGenTable );
+ }
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+ public void dispose() {}
+ }
+
+ class TableColumnTreeLabelProvider extends LabelProvider{
+
+ public Image getImage(Object element) {
+ if( element instanceof ORMGenTable ){
+ return CommonImages.createImage( CommonImages.TABLE_IMAGE );
+ }else if( element instanceof ORMGenColumn ){
+ ORMGenColumn col = ( ORMGenColumn)element;
+ if( col.isPrimaryKey() )
+ return CommonImages.createImage( CommonImages.COLUMN_KEY_IMAGE);
+ return CommonImages.createImage( CommonImages.COLUMN_IMAGE);
+ }
+ return null;
+ }
+
+
+ public String getText(Object element) {
+ if( element instanceof ORMGenTable ){
+ return ((ORMGenTable)element).getName();
+ }else if( element instanceof ORMGenColumn ){
+ return ((ORMGenColumn)element).getName();
+ }
+ return super.getText(element);
+ }
+ }
+
+ private void createGenerateDetailGroup(Composite parent, int columns) {
+ detailPanel = new Composite(parent, SWT.NONE);
+ SWTUtil.fillColumns( detailPanel, columns);
+
+ detailPanelStatckLayout = new StackLayout();
+ detailPanel.setLayout(detailPanelStatckLayout);
+
+ Composite emptyPanel = new Composite(detailPanel, SWT.NONE);
+ emptyPanel.setLayoutData(new GridData());
+
+ detailPanelStatckLayout.topControl = emptyPanel;
+ detailPanel.layout();
+ }
+
+ @Override
+ public final void performHelp()
+ {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+ }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java
new file mode 100644
index 0000000000..30e05e850a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java
@@ -0,0 +1,533 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jpt.ui.internal.wizards.gen;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal2.Association;
+import org.eclipse.jpt.gen.internal2.ORMGenColumn;
+import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal2.util.DTPUtil;
+import org.eclipse.jpt.ui.CommonImages;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.util.TableLayoutComposite;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+
+class TablesSelectorWizardPage extends WizardPage{
+
+ private static final int TABLE_COLUMN_INDEX = 0;
+ private JpaProject jpaProject;
+ private Schema schema = null;
+ private ORMGenCustomizer customizer = null;
+ private boolean synchronizePersistenceXml = true;
+
+ private DatabaseGroup databaseGroup;
+ private CheckboxTableViewer tableTable;
+
+ TablesSelectorWizardPage(JpaProject jpaProject ) {
+ super("TablesSelectorWizardPage"); //$NON-NLS-1$
+ this.jpaProject = jpaProject;
+ this.schema = jpaProject.getDefaultDbSchema();
+ setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_selectTable );
+ setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_chooseEntityTable );
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ }
+
+ // -------- Provide access to wrapped DTP connection related classes ---------
+ ConnectionProfile getProjectConnectionProfile() {
+ String profileName = this.jpaProject.getDataSource().getConnectionProfileName();
+ return this.connectionProfileNamed(profileName);
+ }
+
+ ConnectionProfile connectionProfileNamed(String profileName) {
+ return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(profileName);
+ }
+
+ Schema getSchema(){
+ return this.schema;
+ }
+
+ void setSchema(Schema s){
+ this.schema = s;
+ }
+
+ public Collection<Table> getTables() {
+ Schema schema = this.getSchema();
+ if (schema != null && schema.getName() != null) {
+ return CollectionTools.collection(schema.tables());
+ }
+ return Collections.<Table> emptyList();
+ }
+
+
+ // -------- Initialization ---------
+ /**
+ * The wizard owning this page is responsible for calling this method with the
+ * current selection. The selection is used to initialize the fields of the wizard
+ * page.
+ *
+ * @param selection used to initialize the fields
+ */
+ void init(IStructuredSelection selection) {
+ doStatusUpdate();
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+
+ Composite composite = new Composite(parent, SWT.NULL);
+ int nColumns= 3;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = nColumns;
+ composite.setLayout(layout);
+
+ this.databaseGroup = createDatabaseGroup(composite, 400);
+
+ createTablesSelectionControl(composite, nColumns);
+
+ //Filler column
+ new Label( composite, SWT.NONE);
+
+ final Button synchronizeClassesCheckBox = new Button(composite, SWT.CHECK);
+ synchronizeClassesCheckBox.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_synchronizeClasses );
+ synchronizeClassesCheckBox.setSelection(true);
+ synchronizeClassesCheckBox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ setSynchronizePersistenceXml(synchronizeClassesCheckBox.getSelection());
+ }
+
+ });
+ fillColumns( synchronizeClassesCheckBox, 2);
+
+
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this.tableTable.getControl(), JpaHelpContextIds.DIALOG_GENERATE_ENTITIES_TABLES);
+
+ setControl(composite);
+
+ setPageComplete(true);
+ }
+
+ @Override
+ public void dispose() {
+ if (this.databaseGroup != null)
+ this.databaseGroup.dispose();
+ super.dispose();
+ }
+
+ @Override
+ public IWizardPage getPreviousPage() {
+ IWizardPage prevPage = super.getPreviousPage();
+ if (prevPage instanceof PromptJPAProjectWizardPage)
+ //Prevent going back to the PromptJPAProjectWizardPage
+ //if JPA project already selected
+ return prevPage.getPreviousPage();
+ else
+ return prevPage;
+ }
+
+ private DatabaseGroup createDatabaseGroup(Composite parent, int widthHint) {
+ DatabaseGroup dbGroup = new DatabaseGroup(this.getContainer(), jpaProject, parent, widthHint);
+ /**
+ * listen for when the Database Connection changes its selected schema
+ * so we can keep the page in synch
+ */
+ class DatabasePageListener implements DatabaseGroup.Listener {
+ public void selectedConnectionProfileChanged(ConnectionProfile connectionProfile) {
+ // ignore
+ jpaProject.getDataSource().setConnectionProfileName(connectionProfile.getName());
+ JptCorePlugin.setConnectionProfileName(jpaProject.getProject(), connectionProfile.getName());
+
+ }
+ @SuppressWarnings("unchecked")
+ public void selectedSchemaChanged(Schema schema) {
+ if( schema==null ){
+ updateTablesListViewer(Collections.EMPTY_LIST );
+ doStatusUpdate();
+ return;
+ }
+ jpaProject.setUserOverrideDefaultSchema(schema.getName());
+ setSchema( schema );
+ updateTablesSelector(schema);
+ }
+ }
+ dbGroup.addListener(new DatabasePageListener());
+ dbGroup.init();
+ return dbGroup;
+ }
+
+ boolean synchronizePersistenceXml() {
+ return this.synchronizePersistenceXml;
+ }
+
+ private void setSynchronizePersistenceXml(boolean synchronizePersistenceXml){
+ this.synchronizePersistenceXml = synchronizePersistenceXml;
+ }
+
+ private void selectAllTables(){
+ this.tableTable.setAllChecked(true);
+ doStatusUpdate();
+ }
+
+ private void deselectAllTables(){
+ this.tableTable.setAllChecked(false);
+ doStatusUpdate();
+ }
+
+ private void initTablesSelectionControl(Collection<Table> possibleTables) {
+ this.tableTable.setInput(possibleTables);
+ }
+
+ private void createTablesSelectionControl(Composite parent, int columns) {
+ Label tableLabel = new Label(parent, SWT.NONE);
+ GridData gd= new GridData();
+ gd.horizontalAlignment = GridData.FILL;
+ gd.verticalAlignment = GridData.BEGINNING;
+ tableLabel.setLayoutData( gd );
+ tableLabel.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_tables );
+
+ TableLayoutComposite layout= new TableLayoutComposite(parent, SWT.NONE);
+ addColumnLayoutData(layout);
+
+ final org.eclipse.swt.widgets.Table table = new org.eclipse.swt.widgets.Table(layout, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.CHECK);
+
+ TableColumn tableNameColumn = new TableColumn(table, SWT.NONE, TABLE_COLUMN_INDEX);
+ tableNameColumn.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_tableColumn );
+ tableNameColumn.setResizable(true);
+
+ gd= new GridData(GridData.FILL_BOTH);
+ gd.heightHint= SWTUtil.getTableHeightHint(table, 20);
+ gd.widthHint = 250;
+ gd.grabExcessHorizontalSpace = true;
+ gd.grabExcessVerticalSpace = true ;
+ layout.setLayoutData(gd);
+ layout.setBackground(new Color( Display.getDefault(), 255, 0,0));
+
+ this.tableTable = new CheckboxTableViewer(table);
+ this.tableTable.setUseHashlookup(true);
+ this.tableTable.setLabelProvider(this.buildTableTableLabelProvider());
+ this.tableTable.setContentProvider(this.buildTableTableContentProvider());
+ this.tableTable.setSorter(new ViewerSorter() {
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ return ((Table) e1).getName().compareTo(((Table) e2).getName());
+ }
+ });
+
+ this.tableTable.addPostSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ handleTablesListSelectionChanged(event);
+ }
+ });
+
+ table.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == SWT.F2 && e.stateMask == SWT.NONE) {
+ editEntityNameIfPossible();
+ e.doit= false;
+ }
+ }
+ });
+
+
+ updateTablesSelector( databaseGroup.getSelectedSchema() );
+
+ createButtonComposite(parent);
+
+ GenerateEntitiesFromSchemaWizard generateEntitiesWizard = ((GenerateEntitiesFromSchemaWizard)this.getWizard());
+ Collection<Table> possibleTables = generateEntitiesWizard.getPossibleTables();
+
+ initTablesSelectionControl(possibleTables);
+ }
+
+ private void createButtonComposite(Composite parent){
+
+ Composite buttonComposite = new Composite(parent, SWT.NULL);
+ GridLayout buttonLayout = new GridLayout(1, false);
+ buttonComposite.setLayout(buttonLayout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.verticalAlignment = GridData.BEGINNING;
+ buttonComposite.setLayoutData(data);
+
+ Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
+ selectAllButton.setToolTipText(JptUiMessages.General_selectAll);
+ selectAllButton.setImage( CommonImages.createImage(CommonImages.DESC_BUTTON_SELECT_ALL) );
+ GridData gridData = new GridData();
+ gridData.horizontalAlignment = GridData.FILL;
+ selectAllButton.setLayoutData(gridData);
+ selectAllButton.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ selectAllTables();
+ }
+ });
+
+ Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
+ deselectAllButton.setToolTipText(JptUiMessages.General_deselectAll);
+ deselectAllButton.setImage( CommonImages.createImage(CommonImages.DESC_BUTTON_DESELECT_ALL) );
+ gridData = new GridData();
+ gridData.horizontalAlignment = GridData.FILL;
+ deselectAllButton.setLayoutData(gridData);
+ deselectAllButton.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ deselectAllTables();
+ }
+ });
+ }
+
+
+ private void addColumnLayoutData(TableLayoutComposite layout) {
+ layout.addColumnData(new ColumnWeightData(50, true));
+ }
+
+ void editEntityNameIfPossible(){
+ Object[] selected = ((IStructuredSelection) this.tableTable.getSelection()).toArray();
+ if (selected.length != 1) {
+ return;
+ }
+ }
+
+ void handleTablesListSelectionChanged(SelectionChangedEvent event) {
+ doStatusUpdate();
+ }
+
+ private IBaseLabelProvider buildTableTableLabelProvider() {
+ return new TableTableLabelProvider();
+ }
+
+ private IContentProvider buildTableTableContentProvider() {
+ return new TableTableContentProvider();
+ }
+
+
+ Collection<Table> getSelectedTables() {
+ ArrayList<Table> selectedTables = new ArrayList<Table>();
+ for (Object selectedTable : this.tableTable.getCheckedElements())
+ selectedTables.add((Table) selectedTable);
+ return selectedTables;
+ }
+
+ private boolean hasTablesSelected() {
+ return (this.tableTable != null) ? (this.getSelectedTables().size() > 0) : false;
+ }
+
+ void updateTablesListViewer(Collection<Table> possibleTables) {
+ if (this.tableTable != null) {
+ this.initTablesSelectionControl(possibleTables);
+ }
+ }
+
+ /**
+ * Update the status line and the OK button according to the given status
+ */
+ protected void doStatusUpdate() {
+ if ( ! this.hasTablesSelected()) {
+ this.setPageComplete(false);
+ }else{
+ try{
+ getContainer().run(false, false, new IRunnableWithProgress(){
+ public void run( final IProgressMonitor monitor )
+ throws InvocationTargetException, InterruptedException
+ {
+ monitor.beginTask("Updating", 10);
+
+ Collection<Table> ret = getSelectedTables();
+ ArrayList<String> tableNames = new ArrayList<String>();
+ for( Table t : ret ){
+ tableNames.add(t.getName());
+ }
+ Schema schema = getSchema();
+ if( schema == null ){
+ return ;
+ }
+ customizer.setSchema(schema);
+ customizer.setTableNames(tableNames);
+ monitor.done();
+ }
+ });
+ } catch (Exception e) {
+ JptUiPlugin.log(e);
+ }
+
+ setPageComplete(true);
+ }
+ }
+
+ // ********** inner classes **********
+ private class TableTableLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ TableTableLabelProvider() {
+ super();
+ }
+
+ @Override
+ public String getText(Object element) {
+ return ((Table) element).getName();
+ }
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ if (element == null) {
+ return null;
+ }
+ switch (columnIndex) {
+ case TABLE_COLUMN_INDEX:
+ return ((Table) element).getName();
+
+ }
+ throw new IllegalArgumentException("invalid column index: " + columnIndex);// $NON-NLS-1$
+ }
+
+ }
+
+
+ private class TableTableContentProvider implements IStructuredContentProvider {
+
+ TableTableContentProvider() {
+ super();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { }
+
+ public void dispose() {}
+
+ public Object[] getElements(Object inputElement) {
+ return ((Collection<?>) inputElement).toArray();
+ }
+
+ }
+
+ private void updateTablesSelector(final Schema schema) {
+ if(schema ==null)
+ return;
+ this.jpaProject.setUserOverrideDefaultSchema( schema.getName());
+ JptCorePlugin.setUserOverrideDefaultSchemaName(jpaProject.getProject(), schema.getName());
+
+ updateTablesListViewer( CollectionTools.collection(schema.tables()));
+
+ //Create the ORMGenCustomizer
+ GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) getWizard();
+ customizer = wizard.createORMGenCustomizer( schema );
+
+ if( tableTable!=null && customizer != null ){
+ restoreWizardState();
+ }
+ doStatusUpdate();
+
+ }
+
+ private boolean restoreWizardState(){
+ boolean pageComplete = false;
+ List<String> preSelectedTableNames = this.customizer.getTableNames();
+ if(preSelectedTableNames!=null && preSelectedTableNames.size()>0) {
+ Set<String> set = new HashSet<String>();
+ for(String s : preSelectedTableNames ){
+ set.add(s);
+ }
+ TableItem[] items = this.tableTable.getTable().getItems();
+ for (int i = 0; i < items.length; ++i) {
+ TableItem item = items[i];
+ org.eclipse.jpt.db.Table element = (org.eclipse.jpt.db.Table)item.getData();
+ if (element != null) {
+ boolean check = set.contains(element.getName());
+ // only set if different, to avoid flicker
+ if (item.getChecked() != check) {
+ item.setChecked(check);
+ pageComplete = true;
+ }
+ }
+ }
+ }
+ return pageComplete;
+ }
+
+
+ /**
+ * Set the layoutData of the input control to occupy specified number of columns
+ * @param c
+ * @param columns
+ */
+ private void fillColumns(Control c, int columns){
+ GridData layoutData = new GridData();
+ layoutData.horizontalSpan = columns;
+ layoutData.verticalAlignment = SWT.FILL;
+ layoutData.horizontalAlignment = SWT.FILL;
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = false;
+ c.setLayoutData(layoutData);
+ return ;
+ }
+
+ @Override
+ public final void performHelp()
+ {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+ }
+}

Back to the top