You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2018/11/14 14:27:36 UTC

[05/32] cayenne git commit: Cgen. Refactoring, changes

Cgen. Refactoring, changes


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/0e19c961
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0e19c961
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0e19c961

Branch: refs/heads/master
Commit: 0e19c96147992fcbd10d285d13d3b029cc013f7d
Parents: b85a090
Author: Arseni Bulatski <an...@gmail.com>
Authored: Thu Jun 21 16:55:07 2018 +0300
Committer: Arseni Bulatski <an...@gmail.com>
Committed: Wed Oct 24 13:41:33 2018 +0300

----------------------------------------------------------------------
 .../cayenne/gen/ClassGenerationAction.java      | 110 +++++----
 .../org/apache/cayenne/gen/DataMapArtifact.java |   1 -
 .../cayenne/gen/xml/CgenConfigHandler.java      |  55 ++++-
 .../apache/cayenne/gen/xml/CgenExtension.java   |  21 ++
 .../cayenne/gen/xml/CgenLoaderDelegate.java     |  21 ++
 .../cayenne/gen/xml/CgenSaverDelegate.java      |  21 ++
 .../cayenne/gen/xml/EmbeddableHandler.java      |  21 ++
 .../cayenne/gen/xml/ObjEntityHandler.java       |  21 ++
 .../cayenne/modeler/CodeTemplateManager.java    |  44 +++-
 .../editor/cgen/ClassesTabController.java       |   9 +-
 .../modeler/editor/cgen/ClassesTabPanel.java    |  17 +-
 .../editor/cgen/CodeGeneratorController.java    |   2 +-
 .../cgen/CodeGeneratorControllerBase.java       |  26 +-
 .../editor/cgen/CustomModeController.java       | 188 ++++-----------
 .../modeler/editor/cgen/CustomModePanel.java    | 238 ++++++++++++-------
 .../editor/cgen/CustomPreferencesUpdater.java   | 193 ---------------
 .../editor/cgen/GeneratorController.java        |  29 +--
 .../editor/cgen/GeneratorControllerPanel.java   |  34 ++-
 .../editor/cgen/GeneratorTabController.java     |   5 -
 .../modeler/editor/cgen/GeneratorTabPanel.java  |   1 +
 .../cayenne/modeler/util/ComboBoxAdapter.java   |  72 ++++++
 21 files changed, 575 insertions(+), 554 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
index 35e34cf..f56f81e 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
@@ -22,7 +22,10 @@ package org.apache.cayenne.gen;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.gen.xml.CgenExtension;
-import org.apache.cayenne.map.*;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.QueryDescriptor;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
 import org.apache.velocity.Template;
@@ -102,6 +105,9 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		this.embeddableTemplate = EMBEDDABLE_SUBCLASS_TEMPLATE;
 		this.embeddableSuperTemplate = EMBEDDABLE_SUPERCLASS_TEMPLATE;
 
+		this.queryTemplate = DATAMAP_SUBCLASS_TEMPLATE;
+		this.querySuperTemplate = DATAMAP_SUPERCLASS_TEMPLATE;
+
 		this.artifactsGenerationMode = ArtifactsGenerationMode.ENTITY;
 
 		this.artifacts = new ArrayList<>();
@@ -218,6 +224,11 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 	 */
 	public void execute() throws Exception {
 
+		resetArtifacts();
+		addAllEntities();
+		addAllEmbeddables();
+		addQueries(dataMap.getQueryDescriptors());
+
 		validateAttributes();
 
 		try {
@@ -255,26 +266,6 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		}
 	}
 
-	public void prepareArtifacts(){
-//		resetArtifacts();
-		if(!entityArtifacts.isEmpty()) {
-			for(String name : entityArtifacts) {
-				ObjEntity objEntity = dataMap.getObjEntity(name);
-				if(objEntity != null) {
-					artifacts.add(new EntityArtifact(objEntity));
-				}
-			}
-		}
-		if(!embeddableArtifacts.isEmpty()) {
-			for(String name : embeddableArtifacts) {
-				Embeddable embeddable = dataMap.getEmbeddable(name);
-				if(embeddable != null) {
-					artifacts.add(new EmbeddableArtifact(embeddable));
-				}
-			}
-		}
-	}
-
 	private Template getTemplate(TemplateType type) {
 
 		String templateName = customTemplateName(type);
@@ -577,20 +568,36 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		}
 	}
 
-	public void loadEntity(String name) {
-		if (artifactsGenerationMode == ArtifactsGenerationMode.ENTITY
+    private void addAllEntities() {
+		if(artifactsGenerationMode == ArtifactsGenerationMode.ENTITY
 				|| artifactsGenerationMode == ArtifactsGenerationMode.ALL) {
-			entityArtifacts.add(name);
+            entityArtifacts.forEach(val ->
+                artifacts.add(new EntityArtifact(dataMap.getObjEntity(val))));
 		}
 	}
 
-	public void loadEmbeddable(String name) {
-		if (artifactsGenerationMode == ArtifactsGenerationMode.ENTITY
+    private void addAllEmbeddables() {
+		if(artifactsGenerationMode == ArtifactsGenerationMode.ENTITY
 				|| artifactsGenerationMode == ArtifactsGenerationMode.ALL) {
-			embeddableArtifacts.add(name);
+		    embeddableArtifacts.forEach(val ->
+                    artifacts.add(new EmbeddableArtifact(dataMap.getEmbeddable(val))));
 		}
 	}
 
+    /**
+     * @since 4.1
+     */
+	public void loadEntity(String name) {
+		entityArtifacts.add(name);
+	}
+
+    /**
+     * @since 4.1
+     */
+	public void loadEmbeddable(String name) {
+		embeddableArtifacts.add(name);
+	}
+
 	/**
 	 * Sets an optional shared VelocityContext. Useful with tools like VPP that
 	 * can set custom values in the context, not known to Cayenne.
@@ -625,21 +632,23 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		}
 	}
 
-	/**
-	 * @since 4.1
-	 */
-	public boolean isCreatePKProperties() {
-		return createPKProperties;
-	}
+    /**
+     * @since 4.1
+     */
+    public boolean isCreatePKProperties() {
+        return createPKProperties;
+    }
 
-	/**
-	 * @since 4.1
-	 */
-	public void setCreatePKProperties(boolean createPKProperties) {
-		this.createPKProperties = createPKProperties;
-	}
+    /**
+     * @since 4.1
+     */
+    public void setCreatePKProperties(boolean createPKProperties) {
+        this.createPKProperties = createPKProperties;
+    }
 
-	public Collection<EntityArtifact> getEntityArtifacts() {
+    private Collection<EntityArtifact> getEntityArtifacts() {
+		resetArtifacts();
+		addAllEntities();
 		Collection<EntityArtifact> entityArtifacts = new ArrayList<>();
 		for(Artifact artifact : artifacts){
 			if(artifact instanceof EntityArtifact){
@@ -649,7 +658,9 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		return entityArtifacts;
 	}
 
-	public Collection<EmbeddableArtifact> getEmbeddableArtifacts() {
+    private Collection<EmbeddableArtifact> getEmbeddableArtifacts() {
+		resetArtifacts();
+		addAllEmbeddables();
 		Collection<EmbeddableArtifact> embeddableArtifacts = new ArrayList<>();
 		for(Artifact artifact : artifacts){
 			if(artifact instanceof EmbeddableArtifact){
@@ -699,7 +710,7 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		return superPkg;
 	}
 
-	public void resetArtifacts(){
+	private void resetArtifacts(){
 		this.artifacts = new ArrayList<>();
 	}
 
@@ -735,6 +746,19 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 		return embeddableSuperTemplate;
 	}
 
+	public String getQueryTemplate() {
+	    return queryTemplate;
+    }
+
+    public String getQuerySuperTemplate() {
+        return querySuperTemplate;
+    }
+
+    public void resetCollections(){
+		this.embeddableArtifacts = new ArrayList<>();
+		this.entityArtifacts = new ArrayList<>();
+	}
+
 	@Override
 	public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
 		encoder.start("cgen")
@@ -743,6 +767,8 @@ public class ClassGenerationAction implements Serializable, XMLSerializable {
 				.nested(this.getEmbeddableArtifacts(), delegate)
 				.simpleTag("outputDirectory", this.destDir.getAbsolutePath())
 				.simpleTag("generationMode", this.artifactsGenerationMode.getLabel())
+                .simpleTag("dataMapTemplate", this.queryTemplate)
+                .simpleTag("dataMapSuperclassTemplate", this.querySuperTemplate)
 				.simpleTag("subclassTemplate", this.template)
 				.simpleTag("superclassTemplate", this.superTemplate)
 				.simpleTag("embeddableTemplate", this.embeddableTemplate)

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java
index 54a7426..937f451 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java
@@ -137,5 +137,4 @@ public class DataMapArtifact implements Artifact {
     public DataMap getDataMap() {
     	return dataMap;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java
index 667a4a6..f77f1f1 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.gen.xml;
 
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
@@ -9,6 +27,9 @@ import org.xml.sax.SAXException;
 
 import java.io.File;
 
+/**
+ * @since 4.1
+ */
 public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{
 
     public static final String CONFIG_TAG = "cgen";
@@ -28,6 +49,8 @@ public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{
     private static final String ENCODING_TAG = "encoding";
     private static final String EMBEDDABLE_TEMPLATE_TAG = "embeddableTemplate";
     private static final String EMBEDDABLE_SUPERCLASS_TEMPLATE_TAG = "embeddableSuperclassTemplate";
+    private static final String DATAMAP_TEMPLATE_TAG = "dataMapTemplate";
+    private static final String DATAMAP_SUPERCLASS_TEMPLATE_TAG = "dataMapSuperclassTemplate";
 
     public static final String TRUE = "true";
 
@@ -108,7 +131,12 @@ public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{
             case EMBEDDABLE_SUPERCLASS_TEMPLATE_TAG:
                 createEmbeddableSuperclassTemplate(data);
                 break;
-
+            case DATAMAP_TEMPLATE_TAG:
+                createDataMapTemplate(data);
+                break;
+            case DATAMAP_SUPERCLASS_TEMPLATE_TAG:
+                createDataMapSuperclassTemplate(data);
+                break;
         }
     }
 
@@ -152,7 +180,7 @@ public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{
         }
     }
 
-    public void createEmbeddableTemplate(String template) {
+    private void createEmbeddableTemplate(String template) {
         if(template.trim().length() == 0) {
             return;
         }
@@ -162,7 +190,7 @@ public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{
         }
     }
 
-    public void createEmbeddableSuperclassTemplate(String template) {
+    private void createEmbeddableSuperclassTemplate(String template) {
         if(template.trim().length() == 0) {
             return;
         }
@@ -258,11 +286,30 @@ public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{
         }
     }
 
+    private void createDataMapTemplate(String data) {
+        if(data.trim().length() == 0) {
+            return;
+        }
+
+        if(configuration != null) {
+            configuration.setQueryTemplate(data);
+        }
+    }
+
+    private void createDataMapSuperclassTemplate(String data) {
+        if(data.trim().length() == 0) {
+            return;
+        }
+
+        if(configuration != null) {
+            configuration.setQuerySuperTemplate(data);
+        }
+    }
+
     private void createConfig() {
         configuration = new ClassGenerationAction();
         loaderContext.addDataMapListener(dataMap -> {
             configuration.setDataMap(dataMap);
-            configuration.prepareArtifacts();
             CgenConfigHandler.this.metaData.add(dataMap, configuration);
         });
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
index e98eca9..074a532 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.gen.xml;
 
 import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
@@ -9,6 +27,9 @@ import org.apache.cayenne.project.extension.LoaderDelegate;
 import org.apache.cayenne.project.extension.ProjectExtension;
 import org.apache.cayenne.project.extension.SaverDelegate;
 
+/**
+ * @since 4.1
+ */
 public class CgenExtension implements ProjectExtension {
 
     public static final String NAMESPACE = "http://cayenne.apache.org/schema/" + Project.VERSION + "/cgen";

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java
index 8b3728f..b2f1cba 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.gen.xml;
 
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
@@ -5,6 +23,9 @@ import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
 
 import org.apache.cayenne.project.extension.LoaderDelegate;
 
+/**
+ * @since 4.1
+ */
 public class CgenLoaderDelegate implements LoaderDelegate {
 
     private DataChannelMetaData metaData;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java
index d4d4b8f..8d25cf1 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.gen.xml;
 
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
@@ -5,6 +23,9 @@ import org.apache.cayenne.gen.ClassGenerationAction;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.project.extension.BaseSaverDelegate;
 
+/**
+ * @since 4.1
+ */
 public class CgenSaverDelegate extends BaseSaverDelegate{
 
     private DataChannelMetaData metaData;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/EmbeddableHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/EmbeddableHandler.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/EmbeddableHandler.java
index 4e11a6f..4772348 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/EmbeddableHandler.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/EmbeddableHandler.java
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.gen.xml;
 
 import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
@@ -5,6 +23,9 @@ import org.apache.cayenne.gen.ClassGenerationAction;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
+/**
+ * @since 4.1
+ */
 public class EmbeddableHandler extends NamespaceAwareNestedTagHandler {
 
     private static final String EMBEDDABLE_TAG = "embeddable";

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/ObjEntityHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/ObjEntityHandler.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/ObjEntityHandler.java
index f4ebc48..593a002 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/ObjEntityHandler.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/ObjEntityHandler.java
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.gen.xml;
 
 import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
@@ -5,6 +23,9 @@ import org.apache.cayenne.gen.ClassGenerationAction;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
+/**
+ * @since 4.1
+ */
 public class ObjEntityHandler extends NamespaceAwareNestedTagHandler {
 
     private static final String OBJENTITY_TAG = "objEntity";

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CodeTemplateManager.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CodeTemplateManager.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CodeTemplateManager.java
index b56851a..98f0dc9 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CodeTemplateManager.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CodeTemplateManager.java
@@ -43,19 +43,26 @@ public class CodeTemplateManager {
 	static final String STANDARD_CLIENT_SUPERCLASS = "Standard Client Superclass";
 	static final String STANDARD_CLIENT_SUBCLASS = "Standard Client Subclass";
 
-	public static final String STANDART_EMBEDDABLE_SUPERCLASS = "Standart Embeddable Superclass";
-	public static final String STANDART_EMBEDDABLE_SUBCLASS = "Standart Embeddable Subclass";
-	public static final String SINGLE_EMBEDDABLE_CLASS = "Single Embeddable class";
+	private static final String STANDART_EMBEDDABLE_SUPERCLASS = "Standart Embeddable Superclass";
+	private static final String STANDART_EMBEDDABLE_SUBCLASS = "Standart Embeddable Subclass";
+	private static final String SINGLE_EMBEDDABLE_CLASS = "Single Embeddable class";
+
+	private static final String STANDART_DATAMAP_SUPERCLASS = "Standart DataMap Superclass";
+	private static final String STANDART_DATAMAP_SUBCLASS = "Standart DataMap Subclass";
+	private static final String SINGLE_DATAMAP_CLASS = "Single DataMap class";
 
 	public static final String NODE_NAME = "codeTemplateManager";
 
-	protected List<String> standardSubclassTemplates;
-	protected List<String> standardSuperclassTemplates;
-	protected Map<String, String> customTemplates;
-	protected Map<String, String> standardTemplates;
+	private List<String> standardSubclassTemplates;
+	private List<String> standardSuperclassTemplates;
+	private Map<String, String> customTemplates;
+	private Map<String, String> standardTemplates;
+
+	private List<String> standartEmbeddableTemplates;
+	private List<String> standartEmbeddableSuperclassTemplates;
 
-	protected List<String> standartEmbeddableTemplates;
-	protected List<String> standartEmbeddableSuperclassTemplates;
+	private List<String> standartDataMapTemplates;
+	private List<String> standartDataMapSuperclassTemplates;
 
 	private Map<String, String> reverseStandartTemplates;
 
@@ -83,6 +90,13 @@ public class CodeTemplateManager {
 		standartEmbeddableSuperclassTemplates = new ArrayList<>();
 		standartEmbeddableSuperclassTemplates.add(STANDART_EMBEDDABLE_SUPERCLASS);
 
+		standartDataMapTemplates = new ArrayList<>();
+		standartDataMapTemplates.add(STANDART_DATAMAP_SUBCLASS);
+		standartDataMapTemplates.add(SINGLE_DATAMAP_CLASS);
+
+		standartDataMapSuperclassTemplates = new ArrayList<>();
+		standartDataMapSuperclassTemplates.add(STANDART_DATAMAP_SUPERCLASS);
+
 		updateCustomTemplates(getTemplatePreferences(application));
 
 		standardTemplates = new HashMap<>();
@@ -96,6 +110,10 @@ public class CodeTemplateManager {
 		standardTemplates.put(STANDART_EMBEDDABLE_SUBCLASS, ClassGenerationAction.EMBEDDABLE_SUBCLASS_TEMPLATE);
 		standardTemplates.put(SINGLE_EMBEDDABLE_CLASS, ClassGenerationAction.EMBEDDABLE_SINGLE_CLASS_TEMPLATE);
 
+		standardTemplates.put(STANDART_DATAMAP_SUBCLASS, ClassGenerationAction.DATAMAP_SUBCLASS_TEMPLATE);
+		standardTemplates.put(SINGLE_DATAMAP_CLASS, ClassGenerationAction.DATAMAP_SINGLE_CLASS_TEMPLATE);
+		standardTemplates.put(STANDART_DATAMAP_SUPERCLASS, ClassGenerationAction.DATAMAP_SUPERCLASS_TEMPLATE);
+
 		reverseStandartTemplates = new HashMap<>();
 		reverseStandartTemplates.put(ClassGenerationAction.SUBCLASS_TEMPLATE, STANDARD_SERVER_SUBCLASS);
 		reverseStandartTemplates.put(ClientClassGenerationAction.SUBCLASS_TEMPLATE, STANDARD_CLIENT_SUBCLASS);
@@ -106,6 +124,10 @@ public class CodeTemplateManager {
 		reverseStandartTemplates.put(ClassGenerationAction.EMBEDDABLE_SUPERCLASS_TEMPLATE, STANDART_EMBEDDABLE_SUPERCLASS);
 		reverseStandartTemplates.put(ClassGenerationAction.EMBEDDABLE_SUBCLASS_TEMPLATE, STANDART_EMBEDDABLE_SUBCLASS);
 		reverseStandartTemplates.put(ClassGenerationAction.EMBEDDABLE_SINGLE_CLASS_TEMPLATE, SINGLE_EMBEDDABLE_CLASS);
+
+		reverseStandartTemplates.put(ClassGenerationAction.DATAMAP_SUBCLASS_TEMPLATE, STANDART_DATAMAP_SUBCLASS);
+		reverseStandartTemplates.put(ClassGenerationAction.DATAMAP_SINGLE_CLASS_TEMPLATE, SINGLE_DATAMAP_CLASS);
+		reverseStandartTemplates.put(ClassGenerationAction.DATAMAP_SUPERCLASS_TEMPLATE, STANDART_DATAMAP_SUPERCLASS);
 	}
 
 	/**
@@ -166,4 +188,8 @@ public class CodeTemplateManager {
 	public List<String> getStandartEmbeddableSuperclassTemplates() {
 		return standartEmbeddableSuperclassTemplates;
 	}
+
+	public List<String> getStandartDataMapTemplates() { return standartDataMapTemplates; }
+
+	public List<String> getStandartDataMapSuperclassTemplates() { return standartDataMapSuperclassTemplates; }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java
index 586416e..704e851 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java
@@ -106,7 +106,7 @@ public class ClassesTabController extends CayenneController {
         else if (selectedCount == getParentController().getClasses().size()) {
             view.getCheckAll().setSelected(true);
         }
-        updateEntities();
+        getParentController().updateEntities();
     }
 
     /**
@@ -116,12 +116,7 @@ public class ClassesTabController extends CayenneController {
     public void checkAllAction() {
         if (getParentController().updateSelection(view.getCheckAll().isSelected() ? o -> true : o -> false)) {
             tableBinding.updateView();
-            updateEntities();
+            getParentController().updateEntities();
         }
     }
-
-    private void updateEntities(){
-        getParentController().updateEntities();
-//        getParentController().getProjectController().setDirty(true);
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java
index e4fc20c..f6cad0b 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java
@@ -21,8 +21,6 @@ package org.apache.cayenne.modeler.editor.cgen;
 
 import javax.swing.*;
 import java.awt.*;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
 
 /**
  */
@@ -42,15 +40,12 @@ public class ClassesTabPanel extends JPanel {
         this.checkAll = new JCheckBox();
         this.checkAllLabel = new JLabel("Check All Classes");
 
-        checkAll.addItemListener(new ItemListener() {
-
-            public void itemStateChanged(ItemEvent event) {
-                if (checkAll.isSelected()) {
-                    checkAllLabel.setText("Uncheck All Classess");
-                }
-                else {
-                    checkAllLabel.setText("Check All Classes");
-                }
+        checkAll.addItemListener(event -> {
+            if (checkAll.isSelected()) {
+                checkAllLabel.setText("Uncheck All Classess");
+            }
+            else {
+                checkAllLabel.setText("Check All Classes");
             }
         });
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java
index ac5e152..64a15fa 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java
@@ -58,7 +58,6 @@ public class CodeGeneratorController extends CodeGeneratorControllerBase {
         projectController.addDataMapDisplayListener(e -> {
             super.startup(e.getDataMap());
             classesSelector.startup();
-            generatorSelector.startup(e.getDataMap());
 
             GeneratorController modeController = generatorSelector.getGeneratorController();
             ClassGenerationAction classGenerationAction = modeController.createGenerator();
@@ -125,6 +124,7 @@ public class CodeGeneratorController extends CodeGeneratorControllerBase {
         }
         
         view.getClassesCount().setText(label);
+        projectController.setDirty(true);
     }
 
     public void generateAction() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java
index d99e708..0642fb9 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java
@@ -264,20 +264,16 @@ public abstract class CodeGeneratorControllerBase extends CayenneController {
         DataMap map = getProjectController().getCurrentDataMap();
         ClassGenerationAction generator = projectController.getApplication().getMetaData().get(map, ClassGenerationAction.class);
         if(generator != null) {
-            generator.resetArtifacts();
-            LinkedList<ObjEntity> objEntities = new LinkedList<>(map.getObjEntities());
-
-            Collection<ObjEntity> selected = new ArrayList<>(getSelectedEntities());
-            selected.removeIf(ObjEntity::isGeneric);
-
-            objEntities.retainAll(selected);
-            generator.addEntities(objEntities);
-
-            LinkedList<Embeddable> embeddables = new LinkedList<>(map.getEmbeddables());
-            embeddables.retainAll(getSelectedEmbeddables());
-            generator.addEmbeddables(embeddables);
+            generator.resetCollections();
+            for(ObjEntity entity: getSelectedEntities()) {
+                if(!entity.isGeneric()) {
+                    generator.loadEntity(entity.getName());
+                }
+            }
 
-            generator.addQueries(map.getQueryDescriptors());
+            for(Embeddable embeddable : getSelectedEmbeddables()) {
+                generator.loadEmbeddable(embeddable.getClassName());
+            }
         }
     }
 
@@ -312,8 +308,4 @@ public abstract class CodeGeneratorControllerBase extends CayenneController {
     public void setCurrentClass(Object currentClass) {
         this.currentClass = currentClass;
     }
-
-//    public Collection<DataMap> getDataMaps() {
-//        return dataMaps;
-//    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java
index 134381b..2559657 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java
@@ -23,11 +23,8 @@ import org.apache.cayenne.gen.ClassGenerationAction;
 import org.apache.cayenne.modeler.CodeTemplateManager;
 import org.apache.cayenne.modeler.dialog.pref.PreferenceDialog;
 import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.cayenne.swing.ObjectBinding;
 
 import javax.swing.*;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -38,17 +35,17 @@ import java.util.List;
 public class CustomModeController extends GeneratorController {
 
     // correspond to non-public constants on MapClassGenerator.
-    static final String MODE_DATAMAP = "datamap";
-    static final String MODE_ENTITY = "entity";
-    static final String MODE_ALL = "all";
+    private static final String MODE_DATAMAP = "datamap";
+    private static final String MODE_ENTITY = "entity";
+    private static final String MODE_ALL = "all";
 
-    static final String DATA_MAP_MODE_LABEL = "DataMap generation";
-    static final String ENTITY_MODE_LABEL = "Entity and Embeddable generation";
+    private static final String DATA_MAP_MODE_LABEL = "DataMap generation";
+    private static final String ENTITY_MODE_LABEL = "Entity and Embeddable generation";
     static final String ALL_MODE_LABEL = "Generate all";
 
     static final Map<String, String> modesByLabel = new HashMap<>();
 
-    static final Map<String, String> labelByMode = new HashMap<>();
+    private static final Map<String, String> labelByMode = new HashMap<>();
 
     static {
         modesByLabel.put(DATA_MAP_MODE_LABEL, MODE_DATAMAP);
@@ -60,56 +57,29 @@ public class CustomModeController extends GeneratorController {
     }
 
     protected CustomModePanel view;
-    private CodeTemplateManager templateManager;
-
-    protected ObjectBinding superTemplate;
-    protected ObjectBinding subTemplate;
-
-    private BindingBuilder builder;
-
-    private CustomPreferencesUpdater preferencesUpdater;
 
     private ClassGenerationAction classGenerationAction;
 
     public CustomModeController(CodeGeneratorControllerBase parent) {
         super(parent);
-        this.view = new CustomModePanel();
-        initListeners();
+        this.view = new CustomModePanel(parent.getProjectController());
         bind();
+        initListeners();
     }
 
     private void bind() {
         initBindings(new BindingBuilder(getApplication().getBindingFactory(), this));
-        builder = new BindingBuilder(getApplication().getBindingFactory(), this);
+        BindingBuilder builder = new BindingBuilder(getApplication().getBindingFactory(), this);
         builder.bindToAction(view.getManageTemplatesLink(), "popPreferencesAction()");
 
         updateTemplates();
     }
 
-    protected void createDefaults() {
-//        TreeMap<DataMap, DataMapDefaults> map = new TreeMap<>();
-//        DataMap dataMap = getParentController().getDataMap();
-//        DataMapDefaults preferences;
-//        preferences = getApplication().getFrameController().getProjectController()
-//                .getDataMapPreferences(this.getClass().getName().replace(".", "/"), dataMap);
-//        preferences.setSuperclassPackage("");
-//        preferences.updateSuperclassPackage(dataMap, false);
-//
-//        map.put(dataMap, preferences);
-//
-//        if (getOutputPath() == null) {
-//            setOutputPath(preferences.getOutputPath());
-//        }
-//
-//        setMapPreferences(map);
-//        preferencesUpdater = new CustomPreferencesUpdater(map);
-    }
-
     protected void updateTemplates() {
         Object[] modeChoices = new Object[]{ENTITY_MODE_LABEL, DATA_MAP_MODE_LABEL, ALL_MODE_LABEL};
-        view.getGenerationMode().setModel(new DefaultComboBoxModel(modeChoices));
+        view.getGenerationMode().getComboBox().setModel(new DefaultComboBoxModel(modeChoices));
 
-        this.templateManager = getApplication().getCodeTemplateManager();
+        CodeTemplateManager templateManager = getApplication().getCodeTemplateManager();
 
         List<String> customTemplates = new ArrayList<>(templateManager.getCustomTemplates().keySet());
         Collections.sort(customTemplates);
@@ -130,11 +100,22 @@ public class CustomModeController extends GeneratorController {
         Collections.sort(embeddableSuperTemplates);
         embeddableSuperTemplates.addAll(customTemplates);
 
-        this.view.getSubclassTemplate().setModel(new DefaultComboBoxModel(subTemplates.toArray()));
-        this.view.getSuperclassTemplate().setModel(new DefaultComboBoxModel(superTemplates.toArray()));
+        List<String> dataMapTemplates = new ArrayList<>(templateManager.getStandartDataMapTemplates());
+        Collections.sort(dataMapTemplates);
+        dataMapTemplates.addAll(customTemplates);
+
+        List<String> dataMapSuperTemplates = new ArrayList<>(templateManager.getStandartDataMapSuperclassTemplates());
+        Collections.sort(dataMapSuperTemplates);
+        dataMapSuperTemplates.addAll(customTemplates);
+
+        this.view.getSubclassTemplate().getComboBox().setModel(new DefaultComboBoxModel(subTemplates.toArray()));
+        this.view.getSuperclassTemplate().getComboBox().setModel(new DefaultComboBoxModel(superTemplates.toArray()));
 
-        this.view.getEmbeddableTemplate().setModel(new DefaultComboBoxModel(embeddableTemplates.toArray()));
-        this.view.getEmbeddableSuperTemplate().setModel(new DefaultComboBoxModel(embeddableSuperTemplates.toArray()));
+        this.view.getEmbeddableTemplate().getComboBox().setModel(new DefaultComboBoxModel(embeddableTemplates.toArray()));
+        this.view.getEmbeddableSuperTemplate().getComboBox().setModel(new DefaultComboBoxModel(embeddableSuperTemplates.toArray()));
+
+        this.view.getDataMapTemplate().getComboBox().setModel(new DefaultComboBoxModel(dataMapTemplates.toArray()));
+        this.view.getDataMapSuperTemplate().getComboBox().setModel(new DefaultComboBoxModel(dataMapSuperTemplates.toArray()));
     }
 
     public Component getView() {
@@ -144,6 +125,19 @@ public class CustomModeController extends GeneratorController {
     public void popPreferencesAction() {
         new PreferenceDialog(getApplication().getFrameController()).startupAction(PreferenceDialog.TEMPLATES_KEY);
         updateTemplates();
+        updateComboBoxes();
+    }
+
+    private void updateComboBoxes() {
+        view.getEmbeddableTemplate().setItem(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getEmbeddableTemplate()));
+        view.getEmbeddableSuperTemplate().setItem(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getEmbeddableSuperTemplate()));
+        view.getSubclassTemplate().setItem(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getTemplate()));
+        view.getSuperclassTemplate().setItem(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getSuperclassTemplate()));
+        view.getGenerationMode().setItem(labelByMode.get(classGenerationAction.getArtifactsGenerationMode()));
+        view.getDataMapTemplate().setItem(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getQueryTemplate()));
+        view.getDataMapSuperTemplate().setItem(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getQuerySuperTemplate()));
+
+        view.setDisableSuperComboBoxes(view.getPairs().isSelected());
     }
 
     @Override
@@ -154,19 +148,6 @@ public class CustomModeController extends GeneratorController {
     }
 
     private void initListeners(){
-        view.getOutputFolder().getDocument().addDocumentListener(new DocumentListener() {
-            @Override
-            public void insertUpdate(DocumentEvent e) {
-                classGenerationAction.setDestDir(view.getOutputDir());
-                getParentController().getProjectController().setDirty(true);
-            }
-            @Override
-            public void removeUpdate(DocumentEvent e) {}
-
-            @Override
-            public void changedUpdate(DocumentEvent e) {}
-        });
-
         view.getPairs().addActionListener(val -> {
             classGenerationAction.setMakePairs(view.getPairs().isSelected());
             getParentController().getProjectController().setDirty(true);
@@ -186,92 +167,19 @@ public class CustomModeController extends GeneratorController {
             classGenerationAction.setUsePkgPath(view.getUsePackagePath().isSelected());
             getParentController().getProjectController().setDirty(true);
         });
-
-        view.getSubclassTemplate().addActionListener(val -> {
-            classGenerationAction.setTemplate(getApplication().getCodeTemplateManager().getTemplatePath(String.valueOf(view.getSubclassTemplate().getSelectedItem())));
-            getParentController().getProjectController().setDirty(true);
-        });
-
-        view.getSuperclassTemplate().addActionListener(val -> {
-            classGenerationAction.setSuperTemplate(getApplication().getCodeTemplateManager().getTemplatePath(String.valueOf(view.getSuperclassTemplate().getSelectedItem())));
-            getParentController().getProjectController().setDirty(true);
-        });
-
-        view.getEmbeddableTemplate().addActionListener(val -> {
-            classGenerationAction.setEmbeddableTemplate(getApplication().getCodeTemplateManager().getTemplatePath(String.valueOf(view.getEmbeddableTemplate().getSelectedItem())));
-            getParentController().getProjectController().setDirty(true);
-        });
-
-        view.getEmbeddableSuperTemplate().addActionListener(val -> {
-            classGenerationAction.setEmbeddableSuperTemplate(getApplication().getCodeTemplateManager().getTemplatePath(String.valueOf(view.getEmbeddableSuperTemplate().getSelectedItem())));
-            getParentController().getProjectController().setDirty(true);
-        });
-
-        view.getGenerationMode().addActionListener(val -> {
-            classGenerationAction.setArtifactsGenerationMode(modesByLabel.get(view.getGenerationMode().getSelectedItem()));
-            getParentController().getProjectController().setDirty(true);
-        });
-
-        view.getOutputPattern().getDocument().addDocumentListener(new DocumentListener() {
-            @Override
-            public void insertUpdate(DocumentEvent e) {
-                classGenerationAction.setOutputPattern(view.getOutputPattern().getText());
-                getParentController().getProjectController().setDirty(true);
-            }
-
-            @Override
-            public void removeUpdate(DocumentEvent e) {}
-
-            @Override
-            public void changedUpdate(DocumentEvent e) {}
-        });
-
-        view.getSuperclassPackage().getDocument().addDocumentListener(new DocumentListener() {
-            @Override
-            public void insertUpdate(DocumentEvent e) {
-                classGenerationAction.setSuperPkg(view.getSuperclassPackage().getText());
-                getParentController().getProjectController().setDirty(true);
-            }
-
-            @Override
-            public void removeUpdate(DocumentEvent e) {}
-
-            @Override
-            public void changedUpdate(DocumentEvent e) {}
-        });
-
-        view.getEncoding().getDocument().addDocumentListener(new DocumentListener() {
-            @Override
-            public void insertUpdate(DocumentEvent e) {
-                classGenerationAction.setEncoding(view.getEncoding().getText());
-                getParentController().getProjectController().setDirty(true);
-            }
-
-            @Override
-            public void removeUpdate(DocumentEvent e) {}
-
-            @Override
-            public void changedUpdate(DocumentEvent e) {}
-        });
     }
 
     public void initForm(ClassGenerationAction classGenerationAction){
         this.classGenerationAction = classGenerationAction;
-        view.setOutputFolder(classGenerationAction.getDir());
-        view.setGenerationMode(labelByMode.get(classGenerationAction.getArtifactsGenerationMode()));
-        view.setTemplate(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getTemplate()));
-        view.setSuperclassTemplate(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getSuperclassTemplate()));
+        view.getOutputFolder().setText(classGenerationAction.getDir());
         view.setDataMapName(classGenerationAction.getDataMap().getName());
-        view.setOutputPattern(classGenerationAction.getOutputPattern());
-        view.setPairs(classGenerationAction.isMakePairs());
-        view.setUsePackagePath(classGenerationAction.isUsePkgPath());
-        view.setOverwrite(classGenerationAction.isOverwrite());
-        view.setCreatePropertyNames(classGenerationAction.isCreatePropertyNames());
-        view.setSuperclassPackage(classGenerationAction.getSuperPkg());
-        view.setEncoding(classGenerationAction.getEncoding());
-        view.setEmbeddableTemplate(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getEmbeddableTemplate()));
-        view.setEmbeddableSuperTemplate(getApplication().getCodeTemplateManager().getNameByPath(classGenerationAction.getEmbeddableSuperTemplate()));
-
-//        getParentController().getProjectController().setDirty(false);
+        view.getOutputPattern().setText(classGenerationAction.getOutputPattern());
+        view.getPairs().setSelected(classGenerationAction.isMakePairs());
+        view.getUsePackagePath().setSelected(classGenerationAction.isUsePkgPath());
+        view.getOverwrite().setSelected(classGenerationAction.isOverwrite());
+        view.getCreatePropertyNames().setSelected(classGenerationAction.isCreatePropertyNames());
+        view.getSuperclassPackage().setText(classGenerationAction.getSuperPkg());
+        view.getEncoding().setText(classGenerationAction.getEncoding());
+        updateComboBoxes();
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java
index e79ef7a..bfadc8a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java
@@ -21,85 +21,179 @@ package org.apache.cayenne.modeler.editor.cgen;
 
 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.util.ComboBoxAdapter;
+import org.apache.cayenne.modeler.util.TextAdapter;
+import org.apache.cayenne.swing.components.JCayenneCheckBox;
 import org.apache.cayenne.swing.control.ActionLink;
+import org.apache.cayenne.validation.ValidationException;
 
 import javax.swing.*;
 import java.awt.*;
 
 public class CustomModePanel extends GeneratorControllerPanel {
 
-    private JComboBox generationMode;
-    private JComboBox subclassTemplate;
-    private JComboBox superclassTemplate;
+    private ComboBoxAdapter generationMode;
+    private ComboBoxAdapter subclassTemplate;
+    private ComboBoxAdapter superclassTemplate;
+    private ComboBoxAdapter embeddableTemplate;
+    private ComboBoxAdapter embeddableSuperTemplate;
+    private ComboBoxAdapter dataMapTemplate;
+    private ComboBoxAdapter dataMapSuperTemplate;
     protected JCheckBox pairs;
     private JCheckBox overwrite;
     private JCheckBox usePackagePath;
-    private JTextField outputPattern;
+    private TextAdapter outputPattern;
     private JCheckBox createPropertyNames;
-    private JTextField superclassPackage;
+    private TextAdapter superclassPackage;
 
-    private JTextField encoding;
-    private JComboBox embeddableTemplate;
-    private JComboBox embeddableSuperTemplate;
-    private JLabel dataMapName;
-
-    private DefaultFormBuilder builder;
-
-    protected ActionLink manageTemplatesLink;
+    private TextAdapter encoding;
 
-    public CustomModePanel() {
+    private JLabel dataMapName;
 
-        this.generationMode = new JComboBox();
-        this.superclassTemplate = new JComboBox();
-        this.subclassTemplate = new JComboBox();
-        this.pairs = new JCheckBox();
-        this.overwrite = new JCheckBox();
-        this.usePackagePath = new JCheckBox();
-        this.outputPattern = new JTextField();
-        this.createPropertyNames = new JCheckBox();
+    private ActionLink manageTemplatesLink;
+
+    CustomModePanel(ProjectController projectController) {
+        super(projectController);
+
+        JComboBox modeField = new JComboBox();
+        this.generationMode = new ComboBoxAdapter(modeField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setArtifactsGenerationMode(CustomModeController.modesByLabel.get(item));
+                projectController.setDirty(true);
+            }
+        };
+
+        JComboBox superclassField = new JComboBox();
+        this.superclassTemplate = new ComboBoxAdapter(superclassField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setSuperTemplate(Application.getInstance().getCodeTemplateManager().getTemplatePath(String.valueOf(item)));
+                projectController.setDirty(true);
+            }
+        };
+
+        JComboBox subclassField = new JComboBox();
+        this.subclassTemplate = new ComboBoxAdapter(subclassField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setTemplate(Application.getInstance().getCodeTemplateManager().getTemplatePath(String.valueOf(item)));
+                projectController.setDirty(true);
+            }
+        };
+
+        JComboBox dataMapField = new JComboBox();
+        this.dataMapTemplate = new ComboBoxAdapter(dataMapField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setQueryTemplate(Application.getInstance().getCodeTemplateManager().getTemplatePath(String.valueOf(item)));
+                projectController.setDirty(true);
+            }
+        };
+
+        JComboBox dataMapSuperField = new JComboBox();
+        this.dataMapSuperTemplate = new ComboBoxAdapter(dataMapSuperField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setQuerySuperTemplate(Application.getInstance().getCodeTemplateManager().getTemplatePath(String.valueOf(item)));
+                projectController.setDirty(true);
+            }
+        };
+
+        this.pairs = new JCayenneCheckBox();
+        this.overwrite = new JCayenneCheckBox();
+        this.usePackagePath = new JCayenneCheckBox();
+
+        JTextField outputPatternField = new JTextField();
+        this.outputPattern = new TextAdapter(outputPatternField) {
+            protected void updateModel(String text) {
+                getCgenByDataMap().setOutputPattern(text);
+                projectController.setDirty(true);
+            }
+        };
+
+        this.createPropertyNames = new JCayenneCheckBox();
         this.manageTemplatesLink = new ActionLink("Customize Templates...");
         this.manageTemplatesLink.setFont(manageTemplatesLink.getFont().deriveFont(10f));
-        this.superclassPackage = new JTextField();
 
-        this.encoding = new JTextField();
-        this.embeddableTemplate = new JComboBox();
-        this.embeddableSuperTemplate = new JComboBox();
+        JTextField superclassPackageField = new JTextField();
+        this.superclassPackage = new TextAdapter(superclassPackageField) {
+            protected void updateModel(String text) {
+                getCgenByDataMap().setSuperPkg(text);
+                projectController.setDirty(true);
+            }
+        };
+
+        JTextField encodingField = new JTextField();
+        this.encoding = new TextAdapter(encodingField) {
+            protected void updateModel(String text) {
+                getCgenByDataMap().setEncoding(text);
+                projectController.setDirty(true);
+            }
+        };
+
+        JComboBox embeddableField = new JComboBox();
+        this.embeddableTemplate = new ComboBoxAdapter(embeddableField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setEmbeddableTemplate(Application.getInstance().getCodeTemplateManager().getTemplatePath(String.valueOf(item)));
+                projectController.setDirty(true);
+            }
+        };
+
+        JComboBox embeddableSuperclassField = new JComboBox();
+        this.embeddableSuperTemplate = new ComboBoxAdapter(embeddableSuperclassField) {
+            @Override
+            protected void updateModel(Object item) throws ValidationException {
+                getCgenByDataMap().setEmbeddableSuperTemplate(Application.getInstance().getCodeTemplateManager().getTemplatePath(String.valueOf(item)));
+                projectController.setDirty(true);
+            }
+        };
+
         this.dataMapName = new JLabel();
         this.dataMapName.setFont(dataMapName.getFont().deriveFont(1));
 
         pairs.addChangeListener(e -> {
-            superclassTemplate.setEnabled(pairs.isSelected());
+           setDisableSuperComboBoxes(pairs.isSelected());
             overwrite.setEnabled(!pairs.isSelected());
         });
 
         // assemble
         FormLayout layout = new FormLayout(
-                "right:77dlu, 3dlu, fill:200:grow, 6dlu, fill:50dlu, 3dlu", "");
-        builder = new DefaultFormBuilder(layout);
+                "right:100dlu, 3dlu, fill:100:grow, 6dlu, fill:50dlu, 3dlu", "");
+        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
         builder.setDefaultDialogBorder();
 
-        builder.append("Output Directory:", outputFolder, selectOutputFolder);
+        builder.append("Output Directory:", outputFolder.getComponent(), selectOutputFolder);
+        builder.nextLine();
+
+        builder.append("Generation Mode:", generationMode.getComboBox());
+        builder.nextLine();
+
+        builder.append("DataMap Template:", dataMapTemplate.getComboBox());
         builder.nextLine();
 
-        builder.append("Generation Mode:", generationMode);
+        builder.append("DataMap Superclass Template", dataMapSuperTemplate.getComboBox());
         builder.nextLine();
 
-        builder.append("Subclass Template:", subclassTemplate);
+        builder.append("Subclass Template:", subclassTemplate.getComboBox());
         builder.nextLine();
 
-        builder.append("Superclass Template:", superclassTemplate);
+        builder.append("Superclass Template:", superclassTemplate.getComboBox());
         builder.nextLine();
 
-        builder.append("Embeddable Template", embeddableTemplate);
+        builder.append("Embeddable Template", embeddableTemplate.getComboBox());
         builder.nextLine();
 
-        builder.append("Embeddable Super Template", embeddableSuperTemplate);
+        builder.append("Embeddable Super Template", embeddableSuperTemplate.getComboBox());
         builder.nextLine();
 
-        builder.append("Output Pattern:", outputPattern);
+        builder.append("Output Pattern:", outputPattern.getComponent());
         builder.nextLine();
 
-        builder.append("Encoding", encoding);
+        builder.append("Encoding", encoding.getComponent());
         builder.nextLine();
 
         builder.append("Make Pairs:", pairs);
@@ -117,7 +211,7 @@ public class CustomModePanel extends GeneratorControllerPanel {
         builder.append(dataMapName);
         builder.nextLine();
 
-        builder.append("Superclass package", superclassPackage);
+        builder.append("Superclass package", superclassPackage.getComponent());
 
         setLayout(new BorderLayout());
         add(builder.getPanel(), BorderLayout.CENTER);
@@ -129,7 +223,13 @@ public class CustomModePanel extends GeneratorControllerPanel {
         add(builder.getPanel(), BorderLayout.CENTER);
     }
 
-    public JComboBox getGenerationMode() {
+    public void setDisableSuperComboBoxes(boolean val){
+        superclassTemplate.getComboBox().setEnabled(val);
+        embeddableSuperTemplate.getComboBox().setEnabled(val);
+        dataMapSuperTemplate.getComboBox().setEnabled(val);
+    }
+
+    public ComboBoxAdapter getGenerationMode() {
         return generationMode;
     }
 
@@ -137,16 +237,20 @@ public class CustomModePanel extends GeneratorControllerPanel {
         return manageTemplatesLink;
     }
 
-    public JComboBox getSubclassTemplate() { return subclassTemplate; }
+    public ComboBoxAdapter getSubclassTemplate() { return subclassTemplate; }
 
-    public JComboBox getEmbeddableTemplate() { return embeddableTemplate; }
+    public ComboBoxAdapter getEmbeddableTemplate() { return embeddableTemplate; }
 
-    public JComboBox getEmbeddableSuperTemplate() { return embeddableSuperTemplate; }
+    public ComboBoxAdapter getEmbeddableSuperTemplate() { return embeddableSuperTemplate; }
 
-    public JComboBox getSuperclassTemplate() {
+    public ComboBoxAdapter getSuperclassTemplate() {
         return superclassTemplate;
     }
 
+    public ComboBoxAdapter getDataMapTemplate() { return dataMapTemplate; }
+
+    public ComboBoxAdapter getDataMapSuperTemplate() { return dataMapSuperTemplate; }
+
     public JCheckBox getOverwrite() {
         return overwrite;
     }
@@ -159,7 +263,7 @@ public class CustomModePanel extends GeneratorControllerPanel {
         return usePackagePath;
     }
 
-    public JTextField getOutputPattern() {
+    public TextAdapter getOutputPattern() {
         return outputPattern;
     }
 
@@ -167,55 +271,13 @@ public class CustomModePanel extends GeneratorControllerPanel {
         return createPropertyNames;
     }
 
-    public JTextField getSuperclassPackage() {
+    public TextAdapter getSuperclassPackage() {
         return superclassPackage;
     }
 
-    public JTextField getEncoding() { return encoding; }
+    public TextAdapter getEncoding() { return encoding; }
 
     public void setDataMapName(String mapName){
         dataMapName.setText(mapName);
     }
-
-    public void setSuperclassPackage(String pack) {
-        superclassPackage.setText(pack);
-    }
-
-    public void setPairs(boolean val){
-        pairs.setSelected(val);
-    }
-
-    public void setOverwrite(boolean val){
-        overwrite.setSelected(val);
-    }
-
-    public void setUsePackagePath(boolean val) {
-        usePackagePath.setSelected(val);
-    }
-
-    public void setCreatePropertyNames(boolean val) {
-        createPropertyNames.setSelected(val);
-    }
-
-    public void setOutputPattern(String pattern){
-        outputPattern.setText(pattern);
-    }
-
-    public void setSuperclassTemplate(String template){
-        superclassTemplate.setSelectedItem(template);
-    }
-
-    public void setTemplate(String template) {
-        subclassTemplate.setSelectedItem(template);
-    }
-
-    public void setGenerationMode(String mode) {
-        generationMode.setSelectedItem(mode);
-    }
-
-    public void setEncoding(String encoding) { this.encoding.setText(encoding); }
-
-    public void setEmbeddableTemplate(String template) { embeddableTemplate.setSelectedItem(template); }
-
-    public void setEmbeddableSuperTemplate(String template) { embeddableSuperTemplate.setSelectedItem(template); }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java
deleted file mode 100644
index 469e594..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor.cgen;
-
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.modeler.pref.DataMapDefaults;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class CustomPreferencesUpdater {
-
-    enum Property {
-        SUBCLASS_TEMPLATE,
-        SUPERCLASS_TEMPLATE,
-        OVERWRITE,
-        PAIRS,
-        USE_PACKAGE_PATH,
-        MODE,
-        OUTPUT_PATTERN,
-        CREATE_PROPERTY_NAMES
-    }
-
-    private static final String OVERWRITE = "overwrite";
-    private static final String PAIRS = "pairs";
-    private static final String USE_PACKAGE_PATH = "usePackagePath";
-    private static final String MODE = "mode";
-    private static final String OUTPUT_PATTERN = "outputPattern";
-    private static final String CREATE_PROPERTY_NAMES = "createPropertyNames";
-
-    private Map<DataMap, DataMapDefaults> mapPreferences;
-
-
-    public CustomPreferencesUpdater(Map<DataMap, DataMapDefaults> mapPreferences) {
-        this.mapPreferences = mapPreferences;
-    }
-
-    public String getMode() {
-        return (String) getProperty(Property.MODE);
-    }
-
-    public void setMode(String mode) {
-        updatePreferences(Property.MODE, mode);
-    }
-
-    public String getSubclassTemplate() {
-        return (String) getProperty(Property.SUBCLASS_TEMPLATE);
-    }
-
-    public void setSubclassTemplate(String subclassTemplate) {
-        updatePreferences(Property.SUBCLASS_TEMPLATE, subclassTemplate);
-    }
-
-    public String getSuperclassTemplate() {
-        return (String) getProperty(Property.SUPERCLASS_TEMPLATE);
-    }
-
-    public void setSuperclassTemplate(String superclassTemplate) {
-        updatePreferences(Property.SUPERCLASS_TEMPLATE, superclassTemplate);
-    }
-
-    public Boolean getOverwrite() {
-        return (Boolean) getProperty(Property.OVERWRITE);
-    }
-
-    public void setOverwrite(Boolean overwrite) {
-        updatePreferences(Property.OVERWRITE, overwrite);
-    }
-
-    public Boolean getPairs() {
-        return (Boolean) getProperty(Property.PAIRS);
-    }
-
-    public void setPairs(Boolean pairs) {
-        updatePreferences(Property.PAIRS, pairs);
-    }
-
-    public Boolean getUsePackagePath() {
-        return (Boolean) getProperty(Property.USE_PACKAGE_PATH);
-    }
-
-    public void setUsePackagePath(Boolean usePackagePath) {
-        updatePreferences(Property.USE_PACKAGE_PATH, usePackagePath);
-    }
-
-    public String getOutputPattern() {
-        return (String) getProperty(Property.OUTPUT_PATTERN);
-    }
-
-    public void setOutputPattern(String outputPattern) {
-        updatePreferences(Property.OUTPUT_PATTERN, outputPattern);
-    }
-
-    public Boolean getCreatePropertyNames() {
-        return (Boolean) getProperty(Property.CREATE_PROPERTY_NAMES);
-    }
-
-    public void setCreatePropertyNames(Boolean createPropertyNames) {
-        updatePreferences(Property.CREATE_PROPERTY_NAMES, createPropertyNames);
-    }
-
-    private Object getProperty(Property property) {
-        Object obj = null;
-
-        Set<Entry<DataMap, DataMapDefaults>> entities = mapPreferences.entrySet();
-        for (Entry<DataMap, DataMapDefaults> entry : entities) {
-
-            switch (property) {
-                case MODE:
-                    obj = entry.getValue().getProperty(MODE);
-                    break;
-                case OUTPUT_PATTERN:
-                    obj = entry.getValue().getProperty(OUTPUT_PATTERN);
-                    break;
-                case SUBCLASS_TEMPLATE:
-                    obj = entry.getValue().getSubclassTemplate();
-                    break;
-                case SUPERCLASS_TEMPLATE:
-                    obj = entry.getValue().getSuperclassTemplate();
-                    break;
-                case OVERWRITE:
-                    obj = entry.getValue().getBooleanProperty(OVERWRITE);
-                    break;
-                case PAIRS:
-                    obj = entry.getValue().getBooleanProperty(PAIRS);
-                    break;
-                case USE_PACKAGE_PATH:
-                    obj = entry.getValue().getBooleanProperty(USE_PACKAGE_PATH);
-                    break;
-                case CREATE_PROPERTY_NAMES:
-                    obj = entry.getValue().getBooleanProperty(CREATE_PROPERTY_NAMES);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Bad type property: " + property);
-            }
-
-        }
-        return obj;
-    }
-
-    private void updatePreferences(Property property, Object value) {
-        Set<Entry<DataMap, DataMapDefaults>> entities = mapPreferences.entrySet();
-        for (Entry<DataMap, DataMapDefaults> entry : entities) {
-
-            switch (property) {
-                case MODE:
-                    entry.getValue().setProperty(MODE, (String) value);
-                    break;
-                case OUTPUT_PATTERN:
-                    entry.getValue().setProperty(OUTPUT_PATTERN, (String) value);
-                    break;
-                case SUBCLASS_TEMPLATE:
-                    entry.getValue().setSubclassTemplate((String) value);
-                    break;
-                case SUPERCLASS_TEMPLATE:
-                    entry.getValue().setSuperclassTemplate((String) value);
-                    break;
-                case OVERWRITE:
-                    entry.getValue().setBooleanProperty(OVERWRITE, (Boolean) value);
-                    break;
-                case PAIRS:
-                    entry.getValue().setBooleanProperty(PAIRS, (Boolean) value);
-                    break;
-                case USE_PACKAGE_PATH:
-                    entry.getValue().setBooleanProperty(USE_PACKAGE_PATH, (Boolean) value);
-                    break;
-                case CREATE_PROPERTY_NAMES:
-                    entry.getValue().setBooleanProperty(CREATE_PROPERTY_NAMES, (Boolean) value);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Bad type property: " + property);
-            }
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java
index 7a62efc..7e8087f 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.modeler.pref.DataMapDefaults;
 import org.apache.cayenne.modeler.pref.FSPath;
 import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.modeler.util.CodeValidationUtil;
+import org.apache.cayenne.modeler.util.TextAdapter;
 import org.apache.cayenne.swing.BindingBuilder;
 import org.apache.cayenne.util.Util;
 import org.apache.cayenne.validation.BeanValidationFailure;
@@ -56,10 +57,6 @@ public abstract class GeneratorController extends CayenneController {
         super(parent);
     }
 
-    public String getOutputPath() {
-        return outputPath;
-    }
-
     public void setOutputPath(String path) {
         String old = this.outputPath;
         this.outputPath = path;
@@ -79,14 +76,6 @@ public abstract class GeneratorController extends CayenneController {
         }
     }
 
-    public void setMapPreferences(Map<DataMap, DataMapDefaults> mapPreferences) {
-        this.mapPreferences = mapPreferences;
-    }
-
-    public Map<DataMap, DataMapDefaults> getMapPreferences() {
-        return this.mapPreferences;
-    }
-
     protected void initBindings(BindingBuilder bindingBuilder) {
         JButton outputSelect = ((GeneratorControllerPanel) getView()).getSelectOutputFolder();
         bindingBuilder.bindToAction(outputSelect, "selectOutputFolderAction()");
@@ -113,8 +102,6 @@ public abstract class GeneratorController extends CayenneController {
         if(generator != null){
             getParentController().addToSelectedEntities(generator.getEntities());
             getParentController().addToSelectedEmbeddables(generator.getEmbeddables());
-            generator.getEntities().clear();
-            generator.getEmbeddables().clear();
             return generator;
         }
 
@@ -451,20 +438,14 @@ public abstract class GeneratorController extends CayenneController {
         }
     }
 
-    public File getOutputDir() {
-        String dir = ((GeneratorControllerPanel) getView()).getOutputFolder().getText();
-        return dir != null ? new File(dir) : new File(System.getProperty("user.dir"));
-    }
-
     /**
      * An action method that pops up a file chooser dialog to pick the
      * generation directory.
      */
     public void selectOutputFolderAction() {
+        TextAdapter outputFolder = ((GeneratorControllerPanel) getView()).getOutputFolder();
 
-        JTextField outputFolder = ((GeneratorControllerPanel) getView()).getOutputFolder();
-
-        String currentDir = outputFolder.getText();
+        String currentDir = outputFolder.getComponent().getText();
 
         JFileChooser chooser = new JFileChooser();
         chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
@@ -484,8 +465,8 @@ public abstract class GeneratorController extends CayenneController {
 
             // update model
             String path = selected.getAbsolutePath();
-            outputFolder.setText(path);
-//            setOutputPath(path);
+            ((GeneratorControllerPanel) getView()).getOutputFolder().setText(path);
+            ((GeneratorControllerPanel) getView()).getOutputFolder().updateModel();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java
index 7f1f689..7536a01 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java
@@ -19,6 +19,11 @@
 
 package org.apache.cayenne.modeler.editor.cgen;
 
+import org.apache.cayenne.gen.ClassGenerationAction;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.util.TextAdapter;
+
 import javax.swing.*;
 import java.io.File;
 
@@ -28,27 +33,32 @@ import java.io.File;
  */
 public class GeneratorControllerPanel extends JPanel {
 
-    protected JTextField outputFolder;
+    protected TextAdapter outputFolder;
     protected JButton selectOutputFolder;
 
-    public GeneratorControllerPanel() {
-        this.outputFolder = new JTextField();
+    ProjectController projectController;
+
+    public GeneratorControllerPanel(ProjectController projectController) {
+        this.projectController = projectController;
+        JTextField outputFolderField = new JTextField();
+        this.outputFolder = new TextAdapter(outputFolderField) {
+            protected void updateModel(String text) {
+                getCgenByDataMap().setDestDir(new File(text));
+                projectController.setDirty(true);
+            }
+        };
         this.selectOutputFolder = new JButton("Select");
     }
 
-    public JTextField getOutputFolder() {
-        return outputFolder;
+    public ClassGenerationAction getCgenByDataMap() {
+        DataMap dataMap = projectController.getCurrentDataMap();
+        return projectController.getApplication().getMetaData().get(dataMap, ClassGenerationAction.class);
     }
-
-    public File getOutputDir(){
-        return new File(outputFolder.getText());
+    public TextAdapter getOutputFolder() {
+        return outputFolder;
     }
 
     public JButton getSelectOutputFolder() {
         return selectOutputFolder;
     }
-
-    public void setOutputFolder(String folder) {
-        this.outputFolder.setText(folder);
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabController.java
index fc3f567..53000da 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabController.java
@@ -20,7 +20,6 @@
 package org.apache.cayenne.modeler.editor.cgen;
 
 import org.apache.cayenne.gen.ClassGenerationAction;
-import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.pref.PreferenceDetail;
 
@@ -43,10 +42,6 @@ public class GeneratorTabController extends CayenneController {
         this.view = new GeneratorTabPanel(customModeController.getView());
     }
 
-    public void startup(DataMap dataMap){
-//        customModeController.startup(dataMap);
-    }
-
     public Component getView() {
         return view;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabPanel.java
index 40249f4..4082f36 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorTabPanel.java
@@ -23,6 +23,7 @@ import javax.swing.*;
 import java.awt.*;
 
 /**
+ * @since 4.1
  */
 public class GeneratorTabPanel extends JPanel {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e19c961/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ComboBoxAdapter.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ComboBoxAdapter.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ComboBoxAdapter.java
new file mode 100644
index 0000000..2a7fd79
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ComboBoxAdapter.java
@@ -0,0 +1,72 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.util;
+
+import org.apache.cayenne.modeler.undo.JComboBoxUndoListener;
+import org.apache.cayenne.validation.ValidationException;
+
+import javax.swing.*;
+import java.awt.event.ActionListener;
+
+/**
+ * @since 4.1
+ */
+public abstract class ComboBoxAdapter {
+
+    private JComboBox comboBox;
+    private ActionListener listener;
+
+    private JComboBoxUndoListener undoListener;
+
+    protected ComboBoxAdapter(JComboBox comboBox) {
+        this.comboBox = comboBox;
+        listener = e -> updateModel();
+
+        undoListener = new JComboBoxUndoListener();
+
+        comboBox.addActionListener(listener);
+        comboBox.addItemListener(undoListener);
+    }
+
+    public void setItem(Object item) {
+        comboBox.removeActionListener(listener);
+        comboBox.removeItemListener(undoListener);
+
+        try{
+            comboBox.setSelectedItem(item);
+        }
+        finally {
+            comboBox.addActionListener(listener);
+            comboBox.addItemListener(undoListener);
+        }
+    }
+
+    public JComboBox getComboBox() {
+        return comboBox;
+    }
+
+    /**
+     * Updates bound model with document text.
+     */
+    protected abstract void updateModel(Object item) throws ValidationException;
+
+    public void updateModel() {
+        updateModel(comboBox.getSelectedItem());
+    }
+}