You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/08/03 07:59:52 UTC

[1/5] cayenne git commit: CAY-2340 Save additional metadata as separate files optional support for XInclude in XML reader

Repository: cayenne
Updated Branches:
  refs/heads/master 78b0a653b -> caaeb99bf


CAY-2340 Save additional metadata as separate files
   optional support for XInclude in XML reader


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

Branch: refs/heads/master
Commit: f16810a20a3afbb7b4b3230f6c81890d62efe0c2
Parents: c1ec144
Author: Nikita Timofeev <st...@gmail.com>
Authored: Wed Aug 2 16:09:10 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Aug 2 16:23:56 2017 +0300

----------------------------------------------------------------------
 .../reverse/configuration/ToolsModule.java      |  3 ++
 .../dbimport/ManyToManyCandidateEntityTest.java |  3 ++
 ...patibilityDataChannelDescriptorLoaderIT.java |  3 ++
 .../project/DataChannelProjectLoaderTest.java   |  3 ++
 .../project/DataChannelProjectSaverTest.java    |  4 ++
 .../configuration/server/ServerModule.java      |  3 ++
 .../xml/XMLDataChannelDescriptorLoader.java     |  7 ++-
 .../configuration/xml/XMLDataMapLoader.java     |  7 ++-
 .../configuration/xml/XMLReaderProvider.java    | 53 ++++++++++++++++++++
 .../xml/XMLDataChannelDescriptorLoaderTest.java |  3 +-
 .../configuration/xml/XMLDataMapLoaderTest.java |  2 +
 .../cayenne/unit/di/server/SchemaBuilder.java   |  7 +--
 .../unit/di/server/ServerCaseModule.java        |  4 ++
 .../modeler/init/CayenneModelerModule.java      |  3 ++
 14 files changed, 97 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
index bd6ae66..8e3673d 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
@@ -35,6 +35,7 @@ import org.apache.cayenne.configuration.xml.DataChannelMetaData;
 import org.apache.cayenne.configuration.xml.DefaultDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.dba.db2.DB2Sniffer;
 import org.apache.cayenne.dba.derby.DerbySniffer;
 import org.apache.cayenne.dba.firebird.FirebirdSniffer;
@@ -63,6 +64,7 @@ import org.apache.cayenne.project.extension.ExtensionAwareHandlerFactory;
 import org.apache.cayenne.resource.ClassLoaderResourceLocator;
 import org.apache.cayenne.resource.ResourceLocator;
 import org.slf4j.Logger;
+import org.xml.sax.XMLReader;
 
 /**
  * A DI module to bootstrap DI container for Cayenne Ant tasks and Maven
@@ -117,6 +119,7 @@ public class ToolsModule implements Module {
         binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
         binder.bind(HandlerFactory.class).to(ExtensionAwareHandlerFactory.class);
         binder.bind(DataChannelMetaData.class).to(DefaultDataChannelMetaData.class);
+        binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(true)).withoutScope();
 
         ProjectModule.contributeExtensions(binder);
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntityTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntityTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntityTest.java
index 3d064e5..574ebed 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntityTest.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntityTest.java
@@ -30,6 +30,7 @@ import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator;
 import org.apache.cayenne.dbsync.naming.NoStemStemmer;
 import org.apache.cayenne.di.AdhocObjectFactory;
@@ -46,6 +47,7 @@ import org.apache.cayenne.map.Relationship;
 import org.apache.cayenne.resource.URLResource;
 import org.junit.Before;
 import org.junit.Test;
+import org.xml.sax.XMLReader;
 
 import java.net.URL;
 import java.util.ArrayList;
@@ -69,6 +71,7 @@ public class ManyToManyCandidateEntityTest {
                 binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
                 binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
                 binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
----------------------------------------------------------------------
diff --git a/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
index acc31d7c..79c1d54 100644
--- a/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
+++ b/cayenne-project-compatibility/src/test/java/org/apache/cayenne/configuration/xml/CompatibilityDataChannelDescriptorLoaderIT.java
@@ -49,6 +49,7 @@ import org.apache.cayenne.project.upgrade.handlers.UpgradeHandler_V9;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.resource.URLResource;
 import org.junit.Test;
+import org.xml.sax.XMLReader;
 
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.mock;
@@ -80,6 +81,8 @@ public class CompatibilityDataChannelDescriptorLoaderIT {
                         .add(UpgradeHandler_V10.class);
 
                 binder.bind(ProjectSaver.class).toInstance(mock(ProjectSaver.class));
+
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         });
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectLoaderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectLoaderTest.java b/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectLoaderTest.java
index 9e136f8..1274732 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectLoaderTest.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectLoaderTest.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.ClassLoaderManager;
@@ -40,6 +41,7 @@ import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.resource.URLResource;
 import org.junit.Test;
+import org.xml.sax.XMLReader;
 
 import java.net.URL;
 
@@ -66,6 +68,7 @@ public class DataChannelProjectLoaderTest {
                 binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
                 binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
                 binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectSaverTest.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectSaverTest.java b/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectSaverTest.java
index 5e55221..0908d0d 100644
--- a/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectSaverTest.java
+++ b/cayenne-project/src/test/java/org/apache/cayenne/project/DataChannelProjectSaverTest.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.ClassLoaderManager;
@@ -42,6 +43,7 @@ import org.apache.cayenne.project.unit.Project2Case;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.resource.URLResource;
 import org.junit.Test;
+import org.xml.sax.XMLReader;
 
 import java.io.File;
 import java.io.PrintWriter;
@@ -72,6 +74,7 @@ public class DataChannelProjectSaverTest extends Project2Case {
                 binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
                 binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
                 binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         };
 
@@ -126,6 +129,7 @@ public class DataChannelProjectSaverTest extends Project2Case {
                 binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
                 binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
                 binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
index c86371d..8bf1d6a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
@@ -77,6 +77,7 @@ import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.XMLDataChannelDescriptorLoader;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.dba.db2.DB2Sniffer;
 import org.apache.cayenne.dba.derby.DerbySniffer;
 import org.apache.cayenne.dba.firebird.FirebirdSniffer;
@@ -116,6 +117,7 @@ import org.apache.cayenne.tx.TransactionFactory;
 import org.apache.cayenne.tx.TransactionFilter;
 import org.apache.cayenne.tx.TransactionManager;
 import org.apache.cayenne.velocity.VelocitySQLTemplateProcessor;
+import org.xml.sax.XMLReader;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
@@ -410,5 +412,6 @@ public class ServerModule implements Module {
 
         binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
         binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
+        binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
index 0682bb2..2558b65 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
@@ -26,6 +26,7 @@ import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
 import org.apache.cayenne.configuration.DataMapLoader;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.util.Util;
@@ -98,6 +99,9 @@ public class XMLDataChannelDescriptorLoader implements DataChannelDescriptorLoad
 	}
 
 	@Inject
+	protected Provider<XMLReader> xmlReaderProvider;
+
+	@Inject
 	protected DataMapLoader dataMapLoader;
 
 	@Inject
@@ -125,8 +129,7 @@ public class XMLDataChannelDescriptorLoader implements DataChannelDescriptorLoad
 		descriptor.setName(nameMapper.configurationNodeName(DataChannelDescriptor.class, configurationResource));
 
 		try(InputStream in = configurationURL.openStream()) {
-			XMLReader parser = Util.createXmlReader();
-			parser.setFeature("http://apache.org/xml/features/xinclude", true);
+			XMLReader parser = xmlReaderProvider.get();
 			LoaderContext loaderContext = new LoaderContext(parser, handlerFactory);
 			loaderContext.addDataMapListener(new DataMapLoaderListener() {
 				@Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
index 37fe689..0e50471 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
@@ -21,6 +21,7 @@ package org.apache.cayenne.configuration.xml;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.DataMapLoader;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.util.Util;
@@ -40,12 +41,14 @@ public class XMLDataMapLoader implements DataMapLoader {
     @Inject
     protected HandlerFactory handlerFactory;
 
+    @Inject
+    protected Provider<XMLReader> xmlReaderProvider;
+
     DataMap map;
 
     public synchronized DataMap load(Resource configurationResource) throws CayenneRuntimeException {
         try(InputStream in = configurationResource.getURL().openStream()) {
-            XMLReader parser = Util.createXmlReader();
-            parser.setFeature("http://apache.org/xml/features/xinclude", true);
+            XMLReader parser = xmlReaderProvider.get();
             LoaderContext loaderContext = new LoaderContext(parser, handlerFactory);
             loaderContext.addDataMapListener(new DataMapLoaderListener() {
                 @Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLReaderProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLReaderProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLReaderProvider.java
new file mode 100644
index 0000000..267bb87
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLReaderProvider.java
@@ -0,0 +1,53 @@
+/*****************************************************************
+ *   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.configuration.xml;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.cayenne.di.DIRuntimeException;
+import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.util.Util;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * @since 4.1
+ */
+public class XMLReaderProvider implements Provider<XMLReader> {
+
+    private final boolean supportInclude;
+
+    public XMLReaderProvider(boolean supportInclude) {
+        this.supportInclude = supportInclude;
+    }
+
+    @Override
+    public XMLReader get() throws DIRuntimeException {
+        try {
+            XMLReader reader = Util.createXmlReader();
+            if(supportInclude) {
+                reader.setFeature("http://apache.org/xml/features/xinclude", true);
+            }
+            return reader;
+        } catch (SAXException | ParserConfigurationException ex) {
+            throw new DIRuntimeException("Unable to create XMLReader", ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoaderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoaderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoaderTest.java
index fab4129..020c015 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoaderTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoaderTest.java
@@ -37,6 +37,7 @@ import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.resource.URLResource;
 import org.junit.Before;
 import org.junit.Test;
+import org.xml.sax.XMLReader;
 
 import java.net.URL;
 import java.util.Collection;
@@ -59,7 +60,7 @@ public class XMLDataChannelDescriptorLoaderTest {
                 binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
                 binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
                 binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
-
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataMapLoaderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataMapLoaderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataMapLoaderTest.java
index e416774..a0cffd5 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataMapLoaderTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/xml/XMLDataMapLoaderTest.java
@@ -38,6 +38,7 @@ import org.apache.cayenne.map.SQLTemplateDescriptor;
 import org.apache.cayenne.resource.URLResource;
 import org.junit.Before;
 import org.junit.Test;
+import org.xml.sax.XMLReader;
 
 import static org.junit.Assert.*;
 
@@ -58,6 +59,7 @@ public class XMLDataMapLoaderTest {
                 binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
                 binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
                 binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
+                binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
index a8d6ad0..5101bd5 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/SchemaBuilder.java
@@ -28,6 +28,7 @@ import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory;
 import org.apache.cayenne.access.translator.select.DefaultSelectTranslatorFactory;
 import org.apache.cayenne.ashwood.AshwoodEntitySorter;
 import org.apache.cayenne.cache.MapQueryCache;
+import org.apache.cayenne.configuration.DataMapLoader;
 import org.apache.cayenne.configuration.xml.DefaultHandlerFactory;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
 import org.apache.cayenne.dba.DbAdapter;
@@ -93,6 +94,9 @@ public class SchemaBuilder {
 	private DataDomain domain;
 	private JdbcEventLogger jdbcEventLogger;
 
+	@Inject
+	DataMapLoader loader;
+
 	public SchemaBuilder(@Inject ServerCaseDataSourceFactory dataSourceFactory, @Inject UnitDbAdapter unitDbAdapter,
 			@Inject DbAdapter dbAdapter, @Inject JdbcEventLogger jdbcEventLogger) {
 		this.dataSourceFactory = dataSourceFactory;
@@ -115,10 +119,7 @@ public class SchemaBuilder {
 
 		for (int i = 0; i < maps.length; i++) {
 			URL mapURL = getClass().getClassLoader().getResource(MAPS_REQUIRING_SCHEMA_SETUP[i]);
-			XMLDataMapLoader loader = new XMLDataMapLoader();
-			loader.setHandlerFactory(new DefaultHandlerFactory());
 			maps[i] = loader.load(new URLResource(mapURL));
-
 		}
 
 		this.domain = new DataDomain("temp");

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
index 3386c1b..3fa74dc 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
@@ -60,6 +60,7 @@ import org.apache.cayenne.configuration.xml.DefaultHandlerFactory;
 import org.apache.cayenne.configuration.xml.HandlerFactory;
 import org.apache.cayenne.configuration.xml.NoopDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.JdbcAdapter;
@@ -110,6 +111,7 @@ import org.apache.cayenne.unit.UnitDbAdapter;
 import org.apache.cayenne.unit.di.DataChannelInterceptor;
 import org.apache.cayenne.unit.di.UnitTestLifecycleManager;
 import org.apache.cayenne.unit.util.SQLTemplateCustomizer;
+import org.xml.sax.XMLReader;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
@@ -205,6 +207,8 @@ public class ServerCaseModule implements Module {
         binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
         binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
 
+        binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(false)).withoutScope();
+
         // test-scoped objects
         binder.bind(EntityResolver.class).toProvider(ServerCaseEntityResolverProvider.class).in(testScope);
         binder.bind(DataNode.class).toProvider(ServerCaseDataNodeProvider.class).in(testScope);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/f16810a2/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
index 1062bf3..30ea25d 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
@@ -21,6 +21,7 @@ package org.apache.cayenne.modeler.init;
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
 import org.apache.cayenne.configuration.xml.DefaultDataChannelMetaData;
 import org.apache.cayenne.configuration.xml.HandlerFactory;
+import org.apache.cayenne.configuration.xml.XMLReaderProvider;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.modeler.Application;
@@ -34,6 +35,7 @@ import org.apache.cayenne.modeler.util.WidgetFactory;
 import org.apache.cayenne.project.ProjectModule;
 import org.apache.cayenne.project.extension.ExtensionAwareHandlerFactory;
 import org.apache.cayenne.project.extension.info.InfoExtension;
+import org.xml.sax.XMLReader;
 
 /**
  * A DI module for bootstrapping CayenneModeler services.
@@ -48,6 +50,7 @@ public class CayenneModelerModule implements Module {
         binder.bind(WidgetFactory.class).to(DefaultWidgetFactory.class);
         binder.bind(HandlerFactory.class).to(ExtensionAwareHandlerFactory.class);
         binder.bind(DataChannelMetaData.class).to(DefaultDataChannelMetaData.class);
+        binder.bind(XMLReader.class).toProviderInstance(new XMLReaderProvider(true)).withoutScope();
 
         ProjectModule.contributeExtensions(binder)
                 .add(InfoExtension.class)


[2/5] cayenne git commit: CAY-2344 Modeler: Save ER-Graph and class diagram

Posted by nt...@apache.org.
CAY-2344 Modeler: Save ER-Graph and class diagram


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

Branch: refs/heads/master
Commit: c1ec14440169ca72d086332d8cc783cbf91ea268
Parents: 13ead3f
Author: Nikita Timofeev <st...@gmail.com>
Authored: Wed Aug 2 12:39:55 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Aug 2 16:23:56 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/schema/10/graph.xsd      |  55 +++++++++
 .../cayenne/modeler/graph/BaseGraphBuilder.java |  83 +++++++-------
 .../modeler/graph/DataDomainGraphTab.java       |   9 +-
 .../cayenne/modeler/graph/GraphBuilder.java     |   7 +-
 .../cayenne/modeler/graph/GraphLoader.java      | 114 -------------------
 .../apache/cayenne/modeler/graph/GraphMap.java  |  28 +----
 .../cayenne/modeler/graph/GraphRegistry.java    |   4 +
 .../cayenne/modeler/graph/ObjGraphBuilder.java  |  15 +--
 .../modeler/graph/extension/EntityHandler.java  |  64 +++++++++++
 .../modeler/graph/extension/GraphExtension.java |  62 ++++++++++
 .../modeler/graph/extension/GraphHandler.java   | 112 ++++++++++++++++++
 .../graph/extension/GraphLoaderDelegate.java    |  49 ++++++++
 .../graph/extension/GraphSaverDelegate.java     |  72 ++++++++++++
 .../graph/extension/GraphsRootHandler.java      |  59 ++++++++++
 .../modeler/init/CayenneModelerModule.java      |   5 +-
 15 files changed, 539 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/cayenne-server/src/main/resources/org/apache/cayenne/schema/10/graph.xsd
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/resources/org/apache/cayenne/schema/10/graph.xsd b/cayenne-server/src/main/resources/org/apache/cayenne/schema/10/graph.xsd
new file mode 100644
index 0000000..761a7ae
--- /dev/null
+++ b/cayenne-server/src/main/resources/org/apache/cayenne/schema/10/graph.xsd
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied.  See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<xs:schema targetNamespace="http://cayenne.apache.org/schema/10/graph"
+           elementFormDefault="qualified" version="10"
+           xmlns:cay="http://cayenne.apache.org/schema/10/graph"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+    <xs:element name="graphs">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cay:graph"/>
+            </xs:sequence>
+            <xs:attribute name="selected" type="xs:string" />
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="graph">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cay:entity"/>
+            </xs:sequence>
+            <xs:attribute name="type" type="xs:string" />
+            <xs:attribute name="scale" type="xs:double" />
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="entity">
+        <xs:complexType>
+            <xs:attribute name="name" type="xs:string" />
+            <xs:attribute name="x" type="xs:double" />
+            <xs:attribute name="y" type="xs:double" />
+            <xs:attribute name="width" type="xs:double" />
+            <xs:attribute name="height" type="xs:double" />
+        </xs:complexType>
+    </xs:element>
+
+</xs:schema>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/BaseGraphBuilder.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/BaseGraphBuilder.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/BaseGraphBuilder.java
index ce89df2..6f3b94a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/BaseGraphBuilder.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/BaseGraphBuilder.java
@@ -57,6 +57,7 @@ import org.apache.cayenne.modeler.graph.action.EntityDisplayAction;
 import org.apache.cayenne.modeler.graph.action.RemoveEntityAction;
 import org.apache.cayenne.util.XMLEncoder;
 import org.jgraph.JGraph;
+import org.jgraph.graph.AttributeMap;
 import org.jgraph.graph.DefaultCellViewFactory;
 import org.jgraph.graph.DefaultEdge;
 import org.jgraph.graph.DefaultGraphCell;
@@ -73,7 +74,7 @@ import com.jgraph.layout.organic.JGraphOrganicLayout;
  */
 abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
 
-    static final Font EDGE_FONT = new Font("Verdana", 0, 10);
+    static final Font EDGE_FONT = new Font("Verdana", Font.PLAIN, 10);
 
     /**
      * Graph
@@ -113,6 +114,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
 
     boolean undoEventsDisabled;
 
+    @Override
     public void buildGraph(ProjectController mediator, DataChannelDescriptor domain, boolean doLayout) {
         if (graph != null) {
             // graph already built, exiting silently
@@ -130,7 +132,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         graph.setGraphLayoutCache(view);
 
         graph.addMouseListener(new MouseAdapter() {
-
+            @Override
             public void mouseReleased(MouseEvent e) {
                 if (e.isPopupTrigger()) {
                     Object selected = graph.getSelectionCell();
@@ -145,7 +147,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         });
 
         graph.addMouseWheelListener(new MouseWheelListener() {
-
+            @Override
             public void mouseWheelMoved(MouseWheelEvent e) {
                 // limit scale
                 double scale = graph.getScale() / Math.pow(ZOOM_FACTOR, e.getWheelRotation());
@@ -163,7 +165,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
          * an array for entities that are not connected to anyone. We add them
          * separately so that layout doesn't touch them
          */
-        List<DefaultGraphCell> isolatedObjects = new ArrayList<DefaultGraphCell>();
+        List<DefaultGraphCell> isolatedObjects = new ArrayList<>();
 
         /*
          * 1. Add all entities
@@ -213,14 +215,11 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
 
             // JGraphSimpleLayout layout = new JGraphSimpleLayout(JGraphSimpleLayout.TYPE_TILT, 4000, 2000);
             layout.run(facade);
-            Map nested = facade.createNestedMap(true, true); // Obtain a map of
-                                                             // the
-                                                             // resulting
-                                                             // attribute
-                                                             // changes from the
-                                                             // facade
-
-            edit(nested); // Apply the results to the actual graph
+            // Obtain a map of the resulting attribute changes from the facade
+            Map nested = facade.createNestedMap(true, true);
+
+            // Apply the results to the actual graph
+            edit(nested);
         }
 
         /*
@@ -275,6 +274,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         return cell;
     }
 
+    @Override
     public DefaultGraphCell getEntityCell(String entityName) {
         return entityCells.get(entityName);
     }
@@ -343,6 +343,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         popup.show(graph, p.x, p.y);
     }
 
+    @Override
     public Entity getSelectedEntity() {
         return selectedEntity;
     }
@@ -373,7 +374,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
             GraphConstants.setValue(cell.getAttributes(), getCellMetadata(e));
             GraphConstants.setResize(cell.getAttributes(), true);
 
-            Map nested = new HashMap();
+            Map<DefaultGraphCell, AttributeMap> nested = new HashMap<>();
             nested.put(cell, cell.getAttributes());
 
             edit(nested);
@@ -386,7 +387,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
             if (edge != null) {
                 updateRelationshipLabels(edge, rel, rel.getReverseRelationship());
 
-                Map nested = new HashMap();
+                Map<DefaultEdge, AttributeMap> nested = new HashMap<>();
                 nested.put(edge, edge.getAttributes());
                 edit(nested);
             } else {
@@ -399,7 +400,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         final DefaultGraphCell cell = entityCells.get(e.getName());
         if (cell != null) {
             runWithUndoDisabled(new Runnable() {
-
+                @Override
                 public void run() {
                     graph.getGraphLayoutCache().remove(new Object[] { cell }, true, true);
                 }
@@ -412,7 +413,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         final DefaultEdge edge = relCells.get(getQualifiedName(rel));
         if (edge != null) {
             runWithUndoDisabled(new Runnable() {
-
+                @Override
                 public void run() {
                     graph.getGraphLayoutCache().remove(new Object[] { edge });
                 }
@@ -482,21 +483,27 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
                 reverse == null ? "" : reverse.getName() + " " + getRelationshipLabel(reverse) };
         GraphConstants.setExtraLabels(edge.getAttributes(), labels);
 
-        Point2D[] labelPositions = { new Point2D.Double(GraphConstants.PERMILLE * (0.1 + 0.2 * Math.random()), 10),
-                new Point2D.Double(GraphConstants.PERMILLE * (0.9 - 0.2 * Math.random()), -10) };
+        Point2D[] labelPositions = {
+                new Point2D.Double(GraphConstants.PERMILLE * (0.1 + 0.2 * Math.random()), 10),
+                new Point2D.Double(GraphConstants.PERMILLE * (0.9 - 0.2 * Math.random()), -10)
+        };
         GraphConstants.setExtraLabelPositions(edge.getAttributes(), labelPositions);
     }
 
+    @Override
     public JGraph getGraph() {
         return graph;
     }
 
+    @Override
     public void dataMapAdded(DataMapEvent e) {
     }
 
+    @Override
     public void dataMapChanged(DataMapEvent e) {
     }
 
+    @Override
     public void dataMapRemoved(DataMapEvent e) {
         for (Entity entity : getEntities(e.getDataMap())) {
             removeEntityCell(entity);
@@ -513,10 +520,12 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         this.domain = domain;
     }
 
+    @Override
     public DataChannelDescriptor getDataDomain() {
         return domain;
     }
 
+    @Override
     public void destroy() {
         mediator.removeDataMapListener(this);
     }
@@ -550,34 +559,23 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
 
     @Override
     public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
-        encoder.print("<graph type=\"");
-        encoder.print(getType().toString());
-        encoder.print("\" scale=\"");
-        encoder.print(String.valueOf(graph.getScale()));
-        encoder.println("\">");
-        encoder.indent(1);
+        encoder.start("graph")
+                .attribute("type", getType().toString())
+                .attribute("scale", String.valueOf(graph.getScale()));
 
         for (Entry<String, DefaultGraphCell> entry : entityCells.entrySet()) {
-            encoder.print("<entity name=\"");
-            encoder.print(entry.getKey());
-            encoder.print("\" ");
-
-            DefaultGraphCell cell = entry.getValue();
-            Rectangle2D rect = graph.getCellBounds(cell);
-            encodeRecangle(encoder, rect);
-            encoder.println("/>");
+            Rectangle2D rect = graph.getCellBounds(entry.getValue());
+
+            encoder.start("entity")
+                    .attribute("name", entry.getKey())
+                    .attribute("x", String.valueOf(Math.round(100 * rect.getX()) / 100.0))
+                    .attribute("y", String.valueOf(Math.round(100 * rect.getY()) / 100.0))
+                    .attribute("width", String.valueOf(rect.getWidth()))
+                    .attribute("height", String.valueOf(rect.getHeight()))
+                    .end();
         }
 
-        encoder.indent(-1);
-        encoder.println("</graph>");
-    }
-
-    private void encodeRecangle(XMLEncoder encoder, Rectangle2D rect) {
-        encoder.print("x=\"");
-        encoder.print(rect.getX() + "\" y=\"");
-        encoder.print(rect.getY() + "\" width=\"");
-        encoder.print(rect.getWidth() + "\" height=\"");
-        encoder.print(rect.getHeight() + "\" ");
+        encoder.end();
     }
 
     private void edit(final Map map) {
@@ -607,6 +605,7 @@ abstract class BaseGraphBuilder implements GraphBuilder, DataMapListener {
         }
     }
 
+    @Override
     public void undoableEditHappened(UndoableEditEvent e) {
         if (!undoEventsDisabled) {
             // graph has been modified

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/DataDomainGraphTab.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/DataDomainGraphTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/DataDomainGraphTab.java
index 51e9148..2f62918 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/DataDomainGraphTab.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/DataDomainGraphTab.java
@@ -88,7 +88,6 @@ public class DataDomainGraphTab extends JPanel implements DomainDisplayListener,
     }
 
     private void initView() {
-        graphRegistry = new GraphRegistry();
         needRebuild = true;
         mediator.addDomainDisplayListener(this);
 
@@ -177,7 +176,7 @@ public class DataDomainGraphTab extends JPanel implements DomainDisplayListener,
             dialog.setVisible(true);
 
             if (pane.getValue().equals(JOptionPane.YES_OPTION)) {
-                graphRegistry.getGraphMap(domain).remove(getSelectedType());
+                getGraphRegistry().getGraphMap(domain).remove(getSelectedType());
                 itemStateChanged(null);
             }
         }
@@ -193,10 +192,12 @@ public class DataDomainGraphTab extends JPanel implements DomainDisplayListener,
     }
 
     GraphRegistry getGraphRegistry() {
-
+        graphRegistry = mediator.getApplication().getMetaData().get(domain, GraphRegistry.class);
         if (graphRegistry == null) {
-            this.graphRegistry = new GraphRegistry();
+            graphRegistry = new GraphRegistry();
+            mediator.getApplication().getMetaData().add(domain, graphRegistry);
         }
+
         return graphRegistry;
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphBuilder.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphBuilder.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphBuilder.java
index 665ed86..0c88097 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphBuilder.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphBuilder.java
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.modeler.graph;
 
-import java.io.Serializable;
-
 import javax.swing.event.UndoableEditListener;
 
 import org.apache.cayenne.configuration.DataChannelDescriptor;
@@ -30,9 +28,10 @@ import org.jgraph.JGraph;
 import org.jgraph.graph.DefaultGraphCell;
 
 /**
- * Interface for building graphs which represent some prespective of a domain
+ * Interface for building graphs which represent some perspective of a domain
  */
-public interface GraphBuilder extends Serializable, XMLSerializable, UndoableEditListener {
+public interface GraphBuilder extends XMLSerializable, UndoableEditListener {
+
     double ZOOM_FACTOR = 1.3;
     
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphLoader.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphLoader.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphLoader.java
deleted file mode 100644
index 79408a8..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphLoader.java
+++ /dev/null
@@ -1,114 +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.graph;
-
-import java.awt.geom.Rectangle2D;
-import java.util.Hashtable;
-import java.util.Map;
-
-import javax.swing.undo.UndoableEdit;
-
-import org.apache.cayenne.util.Util;
-import org.jgraph.graph.DefaultGraphCell;
-import org.jgraph.graph.GraphConstants;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Class to load graph from XML
- */
-public class GraphLoader extends DefaultHandler {
-    static final String GRAPH_TAG = "graph";
-    
-    static final String ENTITY_TAG = "entity";
-    
-    /**
-     * Map graphs will be loaded into
-     */
-    GraphMap map;
-    
-    /**
-     * Current builder
-     */
-    GraphBuilder builder;
-    
-    /**
-     * Changed properties for every builder
-     */
-    Map<DefaultGraphCell, Map<String, ?>> propertiesMap;
-            
-    public GraphLoader(GraphMap map) {
-        this.map = map;
-    }
-    
-    @Override
-    public void startElement(
-            String uri,
-            String localName,
-            String qName,
-            Attributes attributes) throws SAXException {
-        if (GRAPH_TAG.equalsIgnoreCase(localName)) {
-            String type = attributes.getValue("", "type");
-            if (Util.isEmptyString(type)) {
-                throw new SAXException("Graph type not specified");
-            }
-            
-            GraphType graphType = GraphType.valueOf(type);
-            if (graphType == null) {
-                throw new SAXException("Graph type " + type + " not supported");
-            }
-            
-            builder = map.createGraphBuilder(graphType, false);
-            builder.getGraph().setScale(getAsDouble(attributes, "scale"));
-            
-            propertiesMap = new Hashtable<DefaultGraphCell, Map<String,?>>();
-        }
-        else if (ENTITY_TAG.equalsIgnoreCase(localName)) {
-            String name = attributes.getValue("", "name");
-            DefaultGraphCell cell = builder.getEntityCell(name);
-            if (cell != null) {
-                Map<String, Object> props = new Hashtable<String, Object>();
-                GraphConstants.setBounds(props, 
-                        new Rectangle2D.Double(
-                            getAsDouble(attributes, "x"),
-                            getAsDouble(attributes, "y"),
-                            getAsDouble(attributes, "width"),
-                            getAsDouble(attributes, "height")
-                        ));
-                propertiesMap.put(cell, props);
-            }
-        }
-    }
-    
-    @Override
-    public void endElement(String uri, String localName, String qName)
-            throws SAXException {
-        if (GRAPH_TAG.equalsIgnoreCase(localName)) {
-            //apply changes
-            builder.getGraph().getGraphLayoutCache().getModel().removeUndoableEditListener(builder);
-            builder.getGraph().getGraphLayoutCache().edit(propertiesMap, null, null, new UndoableEdit[0]);
-            builder.getGraph().getGraphLayoutCache().getModel().addUndoableEditListener(builder);
-        }
-    }
-    
-    private double getAsDouble(Attributes atts, String key) {
-        return Double.valueOf(atts.getValue("", key));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphMap.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphMap.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphMap.java
index 3ed6d65..ff85ae6 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphMap.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphMap.java
@@ -21,18 +21,15 @@ package org.apache.cayenne.modeler.graph;
 import java.util.HashMap;
 
 import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.util.XMLEncoder;
-import org.apache.cayenne.util.XMLSerializable;
 
 /**
  * Map that stores graph builders <b>for a single domain</b> by their type 
  * and has additional methods to set currently selected graph and serialize to XML
  */
-public class GraphMap extends HashMap<GraphType, GraphBuilder> implements XMLSerializable {
+public class GraphMap extends HashMap<GraphType, GraphBuilder> {
     /**
      * type that is currently selected
      */
@@ -67,23 +64,6 @@ public class GraphMap extends HashMap<GraphType, GraphBuilder> implements XMLSer
     public void setSelectedType(GraphType selectedType) {
         this.selectedType = selectedType;
     }
-
-    @Override
-    public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
-        encoder.print("<graphs");
-//        if (selectedType != null) {
-//            encoder.print(" selected=\"" + selectedType + "\"");
-//        }
-        encoder.println(">");
-        encoder.indent(1);
-        
-        for (GraphBuilder builder : values()) {
-            builder.encodeAsXML(encoder, delegate);
-        }
-        
-        encoder.indent(-1);
-        encoder.println("</graphs>");
-    }
     
     public GraphBuilder createGraphBuilder(GraphType type, boolean doLayout) {
         try {
@@ -92,13 +72,11 @@ public class GraphMap extends HashMap<GraphType, GraphBuilder> implements XMLSer
             put(type, builder);
             
             return builder;
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             throw new CayenneRuntimeException("Could not instantiate GraphBuilder", e);
         }
     }
-    
-    //TODO do not use static context
+
     private ProjectController getProjectController() {
         return Application.getInstance().getFrameController().getProjectController();
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphRegistry.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphRegistry.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphRegistry.java
index 75ffc9a..6fdf821 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphRegistry.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/GraphRegistry.java
@@ -79,6 +79,10 @@ public class GraphRegistry implements DomainListener {
         return map;
     }
 
+    public void addGraphMap(DataChannelDescriptor domain, GraphMap map) {
+        graphMaps.put(domain, map);
+    }
+
     public void domainChanged(DomainEvent e) {
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/ObjGraphBuilder.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/ObjGraphBuilder.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/ObjGraphBuilder.java
index d793f01..7c975bc 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/ObjGraphBuilder.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/ObjGraphBuilder.java
@@ -31,9 +31,11 @@ import org.apache.cayenne.map.event.ObjEntityListener;
 import org.apache.cayenne.map.event.ObjRelationshipListener;
 import org.apache.cayenne.map.event.RelationshipEvent;
 import org.apache.cayenne.modeler.ProjectController;
+import org.jgraph.graph.AttributeMap;
 import org.jgraph.graph.DefaultEdge;
 import org.jgraph.graph.DefaultGraphCell;
 import org.jgraph.graph.GraphConstants;
+import org.slf4j.LoggerFactory;
 
 import java.awt.*;
 import java.util.Collection;
@@ -70,14 +72,9 @@ class ObjGraphBuilder extends BaseGraphBuilder implements ObjEntityListener,
             return false;
         }
 
-        // TODO: andrus 05/30/2010 - reindexing all DataMaps every time may be VERY slow
-        // on large projects
-        EntityResolver resolver = new EntityResolver(((DataChannelDescriptor) mediator
-                .getProject()
-                .getRootNode()).getDataMaps());
-
-        EntityInheritanceTree inheritanceTree = resolver.lookupInheritanceTree(entity
-                .getName());
+        // TODO: andrus 05/30/2010 - reindexing all DataMaps every time may be VERY slow on large projects
+        EntityResolver resolver = new EntityResolver(domain.getDataMaps());
+        EntityInheritanceTree inheritanceTree = resolver.getInheritanceTree(entity.getName());
         return inheritanceTree == null || inheritanceTree.getChildren().isEmpty();
     }
 
@@ -166,7 +163,7 @@ class ObjGraphBuilder extends BaseGraphBuilder implements ObjEntityListener,
                 inheritanceEdge.setTarget(entityCells.get(
                         entity.getSuperEntity().getName()).getChildAt(0));
 
-                Map nested = new HashMap();
+                Map<DefaultEdge, AttributeMap> nested = new HashMap<>();
                 nested.put(inheritanceEdge, inheritanceEdge.getAttributes());
 
                 graph.getGraphLayoutCache().edit(nested);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/EntityHandler.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/EntityHandler.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/EntityHandler.java
new file mode 100644
index 0000000..fbb6a28
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/EntityHandler.java
@@ -0,0 +1,64 @@
+/*****************************************************************
+ *   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.graph.extension;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
+import org.jgraph.graph.DefaultGraphCell;
+import org.jgraph.graph.GraphConstants;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * @since 4.1
+ */
+public class EntityHandler extends NamespaceAwareNestedTagHandler {
+
+    static final String ENTITY_TAG = "entity";
+
+    GraphHandler graphHandler;
+
+    public EntityHandler(GraphHandler parentHandler) {
+        super(parentHandler);
+        this.graphHandler = parentHandler;
+    }
+
+    @Override
+    protected boolean processElement(String namespaceURI, String localName, Attributes attributes) throws SAXException {
+        switch (localName) {
+            case ENTITY_TAG:
+                String name = attributes.getValue("name");
+                Map<String, Object> props = new Hashtable<>();
+                GraphConstants.setBounds(props,
+                        new Rectangle2D.Double(
+                                Double.valueOf(attributes.getValue("x")),
+                                Double.valueOf(attributes.getValue("y")),
+                                Double.valueOf(attributes.getValue("width")),
+                                Double.valueOf(attributes.getValue("height"))
+                        ));
+                graphHandler.propertiesMap.put(name, props);
+                return true;
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
new file mode 100644
index 0000000..74e129a
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
@@ -0,0 +1,62 @@
+/*****************************************************************
+ *   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.graph.extension;
+
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.project.Project;
+import org.apache.cayenne.project.extension.BaseNamingDelegate;
+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 GraphExtension implements ProjectExtension {
+
+    static final String NAMESPACE = "http://cayenne.apache.org/schema/" + Project.VERSION + "/graph";
+
+    @Inject
+    protected Provider<Application> applicationProvider;
+
+    @Override
+    public LoaderDelegate createLoaderDelegate() {
+        return new GraphLoaderDelegate(applicationProvider.get());
+    }
+
+    @Override
+    public SaverDelegate createSaverDelegate() {
+        return new GraphSaverDelegate(applicationProvider.get().getMetaData());
+    }
+
+    @Override
+    public ConfigurationNodeVisitor<String> createNamingDelegate() {
+        return new BaseNamingDelegate() {
+            @Override
+            public String visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+                return channelDescriptor.getName() + ".graph.xml";
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphHandler.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphHandler.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphHandler.java
new file mode 100644
index 0000000..7eaae4f
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphHandler.java
@@ -0,0 +1,112 @@
+/*****************************************************************
+ *   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.graph.extension;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.undo.UndoableEdit;
+
+import com.sun.corba.se.impl.orbutil.graph.Graph;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.xml.DataChannelLoaderListener;
+import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.graph.GraphBuilder;
+import org.apache.cayenne.modeler.graph.GraphMap;
+import org.apache.cayenne.modeler.graph.GraphRegistry;
+import org.apache.cayenne.modeler.graph.GraphType;
+import org.apache.cayenne.util.Util;
+import org.jgraph.graph.DefaultGraphCell;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Class to load graph from XML
+ */
+public class GraphHandler extends NamespaceAwareNestedTagHandler {
+
+    static final String GRAPH_TAG = "graph";
+
+    static final String ENTITY_TAG = "entity";
+
+    Map<String, Map<String, ?>> propertiesMap;
+
+    GraphType graphType;
+
+    double scale;
+            
+    public GraphHandler(NamespaceAwareNestedTagHandler parent, final Application application) {
+        super(parent);
+        loaderContext.addDataChannelListener(new DataChannelLoaderListener() {
+            @Override
+            public void onDataChannelLoaded(DataChannelDescriptor dataChannelDescriptor) {
+                GraphRegistry registry = application.getMetaData().get(dataChannelDescriptor, GraphRegistry.class);
+                if(registry == null) {
+                    registry = new GraphRegistry();
+                    application.getMetaData().add(dataChannelDescriptor, registry);
+                }
+
+                GraphMap map = registry.getGraphMap(dataChannelDescriptor);
+                //apply changes
+                GraphBuilder builder = map.createGraphBuilder(graphType, false);
+                builder.getGraph().setScale(scale);
+
+                // lookup
+                Map<DefaultGraphCell, Map<String, ?>> propertiesMap = new HashMap<>();
+                for(Map.Entry<String, Map<String, ?>> entry : GraphHandler.this.propertiesMap.entrySet()) {
+                    DefaultGraphCell cell = builder.getEntityCell(entry.getKey());
+                    propertiesMap.put(cell, entry.getValue());
+                }
+
+                builder.getGraph().getGraphLayoutCache().getModel().removeUndoableEditListener(builder);
+                builder.getGraph().getGraphLayoutCache().edit(propertiesMap, null, null, new UndoableEdit[0]);
+                builder.getGraph().getGraphLayoutCache().getModel().addUndoableEditListener(builder);
+            }
+        });
+    }
+
+    @Override
+    protected boolean processElement(String namespaceURI, String localName, Attributes attributes) throws SAXException {
+        switch (localName) {
+            case GRAPH_TAG:
+                String type = attributes.getValue("type");
+                if (Util.isEmptyString(type)) {
+                    throw new SAXException("Graph type not specified");
+                }
+
+                graphType = GraphType.valueOf(type);
+                scale = Double.valueOf(attributes.getValue("scale"));
+                propertiesMap = new HashMap<>();
+                return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    protected ContentHandler createChildTagHandler(String namespaceURI, String localName, String qName, Attributes attributes) {
+        switch (localName) {
+            case ENTITY_TAG:
+                return new EntityHandler(this);
+        }
+        return super.createChildTagHandler(namespaceURI, localName, qName, attributes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphLoaderDelegate.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphLoaderDelegate.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphLoaderDelegate.java
new file mode 100644
index 0000000..176f736
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphLoaderDelegate.java
@@ -0,0 +1,49 @@
+/*****************************************************************
+ *   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.graph.extension;
+
+import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.project.extension.LoaderDelegate;
+
+/**
+ * @since 4.1
+ */
+class GraphLoaderDelegate implements LoaderDelegate {
+
+    Application application;
+
+    GraphLoaderDelegate(Application application) {
+        this.application = application;
+    }
+
+    @Override
+    public String getTargetNamespace() {
+        return GraphExtension.NAMESPACE;
+    }
+
+    @Override
+    public NamespaceAwareNestedTagHandler createHandler(NamespaceAwareNestedTagHandler parent, String tag) {
+        if(GraphsRootHandler.GRAPHS_TAG.equals(tag)) {
+            return new GraphsRootHandler(parent, application);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java
new file mode 100644
index 0000000..b5e5d52
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.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.graph.extension;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.xml.DataChannelMetaData;
+import org.apache.cayenne.modeler.graph.GraphMap;
+import org.apache.cayenne.modeler.graph.GraphRegistry;
+import org.apache.cayenne.project.extension.BaseSaverDelegate;
+
+/**
+ * @since 4.1
+ */
+class GraphSaverDelegate extends BaseSaverDelegate {
+
+    DataChannelMetaData metaData;
+
+    GraphSaverDelegate(DataChannelMetaData metaData) {
+        this.metaData = metaData;
+    }
+
+    @Override
+    public Void visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+        if(isStandalone()) {
+            printGraphs(channelDescriptor);
+        } else {
+            printInclude(channelDescriptor);
+        }
+
+        return null;
+    }
+
+    private void printGraphs(DataChannelDescriptor channelDescriptor) {
+        GraphRegistry registry = metaData.get(channelDescriptor, GraphRegistry.class);
+        if (registry == null) {
+            return;
+        }
+
+        GraphMap map = registry.getGraphMap(channelDescriptor);
+        encoder.start("graphs")
+                .attribute("xmlns", GraphExtension.NAMESPACE)
+                .attribute("selected", map.getSelectedType().toString())
+                .nested(map, getParentDelegate())
+                .end();
+    }
+
+    private void printInclude(DataChannelDescriptor channelDescriptor) {
+        encoder.start("xi:include")
+                .attribute("xmlns:xi", "http://www.w3.org/2001/XInclude")
+                .attribute("href", channelDescriptor.getName() + ".graph.xml")
+                .end();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphsRootHandler.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphsRootHandler.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphsRootHandler.java
new file mode 100644
index 0000000..f67689f
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphsRootHandler.java
@@ -0,0 +1,59 @@
+/*****************************************************************
+ *   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.graph.extension;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.xml.DataChannelLoaderListener;
+import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.graph.GraphMap;
+import org.apache.cayenne.modeler.graph.GraphRegistry;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * @since 4.1
+ */
+public class GraphsRootHandler extends NamespaceAwareNestedTagHandler {
+
+    static final String GRAPHS_TAG = "graphs";
+
+    Application application;
+
+    public GraphsRootHandler(NamespaceAwareNestedTagHandler parentHandler, Application application) {
+        super(parentHandler);
+        setTargetNamespace(GraphExtension.NAMESPACE);
+        this.application = application;
+    }
+
+    @Override
+    protected boolean processElement(String namespaceURI, String localName, Attributes attributes) throws SAXException {
+        return GRAPHS_TAG.equals(localName);
+    }
+
+    @Override
+    protected ContentHandler createChildTagHandler(String namespaceURI, String localName, String qName, Attributes attributes) {
+        if(GraphHandler.GRAPH_TAG.equals(localName)) {
+            return new GraphHandler(this, application);
+        }
+        return super.createChildTagHandler(namespaceURI, localName, qName, attributes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c1ec1444/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
index f255b1f..1062bf3 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/init/CayenneModelerModule.java
@@ -26,6 +26,7 @@ import org.apache.cayenne.di.Module;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.action.ActionManager;
 import org.apache.cayenne.modeler.action.DefaultActionManager;
+import org.apache.cayenne.modeler.graph.extension.GraphExtension;
 import org.apache.cayenne.modeler.init.platform.GenericPlatformInitializer;
 import org.apache.cayenne.modeler.init.platform.PlatformInitializer;
 import org.apache.cayenne.modeler.util.DefaultWidgetFactory;
@@ -48,6 +49,8 @@ public class CayenneModelerModule implements Module {
         binder.bind(HandlerFactory.class).to(ExtensionAwareHandlerFactory.class);
         binder.bind(DataChannelMetaData.class).to(DefaultDataChannelMetaData.class);
 
-        ProjectModule.contributeExtensions(binder).add(InfoExtension.class);
+        ProjectModule.contributeExtensions(binder)
+                .add(InfoExtension.class)
+                .add(GraphExtension.class);
     }
 }


[3/5] cayenne git commit: CAY-2340 Save additional metadata as separate files

Posted by nt...@apache.org.
CAY-2340 Save additional metadata as separate files


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

Branch: refs/heads/master
Commit: 3939efe42ab7fd8a3745a45e0d6721b9b789e519
Parents: 78b0a65
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Aug 1 17:02:33 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Aug 2 16:23:56 2017 +0300

----------------------------------------------------------------------
 cayenne-joda/pom.xml                            |   7 ++
 .../cayenne/project/FileProjectSaver.java       |  49 ++++++--
 .../project/extension/BaseNamingDelegate.java   | 112 +++++++++++++++++++
 .../project/extension/BaseSaverDelegate.java    |   4 +
 .../project/extension/ProjectExtension.java     |   5 +
 .../project/extension/info/InfoExtension.java   |   7 ++
 cayenne-server/pom.xml                          |   7 ++
 .../xml/XMLDataChannelDescriptorLoader.java     |   5 +-
 .../configuration/xml/XMLDataMapLoader.java     |   5 +-
 modeler/cayenne-modeler/pom.xml                 |   7 ++
 10 files changed, 196 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-joda/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-joda/pom.xml b/cayenne-joda/pom.xml
index 2dbad8a..8cde877 100644
--- a/cayenne-joda/pom.xml
+++ b/cayenne-joda/pom.xml
@@ -76,6 +76,13 @@
 			<groupId>com.mockrunner</groupId>
 			<artifactId>mockrunner-jdbc</artifactId>
 			<scope>test</scope>
+			<exclusions>
+				<exclusion>
+					<!-- this one have old Xerces dependency that clashes with JDK's one -->
+					<groupId>nekohtml</groupId>
+					<artifactId>nekohtml</artifactId>
+				</exclusion>
+			</exclusions>
 		</dependency>
 		<dependency>
 			<groupId>org.hsqldb</groupId>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
index fe01162..e76022a 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
@@ -28,6 +28,7 @@ import org.apache.cayenne.project.extension.SaverDelegate;
 import org.apache.cayenne.resource.Resource;
 import org.apache.cayenne.resource.URLResource;
 import org.apache.cayenne.util.Util;
+import org.apache.cayenne.util.XMLEncoder;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -56,7 +57,8 @@ public class FileProjectSaver implements ProjectSaver {
 	protected ConfigurationNodeVisitor<Collection<ConfigurationNode>> saveableNodesGetter;
 	protected String fileEncoding;
 
-	protected Collection<SaverDelegate> saverDelegates;
+	protected Collection<ProjectExtension> extensions;
+	protected SaverDelegate delegate;
 
 	public FileProjectSaver(@Inject List<ProjectExtension> extensions) {
 		resourceGetter = new ConfigurationSourceGetter();
@@ -65,21 +67,25 @@ public class FileProjectSaver implements ProjectSaver {
 		// this is not configurable yet... probably doesn't have to be
 		fileEncoding = "UTF-8";
 
-		saverDelegates = new ArrayList<>(extensions.size());
+		this.extensions = extensions;
+		Collection<SaverDelegate> delegates = new ArrayList<>(extensions.size());
 		for(ProjectExtension extension : extensions) {
-			SaverDelegate delegate = extension.createSaverDelegate();
-			saverDelegates.add(delegate);
+			delegates.add(extension.createSaverDelegate());
 		}
+		delegate = new CompoundSaverDelegate(delegates);
 	}
 
+	@Override
 	public String getSupportedVersion() {
 		return String.valueOf(Project.VERSION);
 	}
 
+	@Override
 	public void save(Project project) {
 		save(project, project.getConfigurationResource(), true);
 	}
 
+	@Override
 	public void saveAs(Project project, Resource baseDirectory) {
 		if (baseDirectory == null) {
 			throw new NullPointerException("Null 'baseDirectory'");
@@ -91,8 +97,21 @@ public class FileProjectSaver implements ProjectSaver {
 		Collection<ConfigurationNode> nodes = project.getRootNode().acceptVisitor(saveableNodesGetter);
 		Collection<SaveUnit> units = new ArrayList<>(nodes.size());
 
-		for (ConfigurationNode node : nodes) {
-			units.add(createSaveUnit(node, baseResource));
+		for(ConfigurationNode node : nodes) {
+			String targetLocation = nameMapper.configurationLocation(node);
+			Resource targetResource = baseResource.getRelativeResource(targetLocation);
+			units.add(createSaveUnit(node, targetResource, null));
+
+			for(ProjectExtension extension : extensions) {
+				ConfigurationNodeVisitor<String> namingDelegate = extension.createNamingDelegate();
+				SaverDelegate unitSaverDelegate = extension.createSaverDelegate();
+				String fileName = node.acceptVisitor(namingDelegate);
+				if(fileName != null) {
+					// not null means that this should go to a separate file
+					targetResource = baseResource.getRelativeResource(fileName);
+					units.add(createSaveUnit(node, targetResource, unitSaverDelegate));
+				}
+			}
 		}
 
 		checkAccess(units);
@@ -123,10 +142,11 @@ public class FileProjectSaver implements ProjectSaver {
 		project.getUnusedResources().clear();
 	}
 
-	SaveUnit createSaveUnit(ConfigurationNode node, Resource baseResource) {
+	SaveUnit createSaveUnit(ConfigurationNode node, Resource baseResource, SaverDelegate delegate) {
 
 		SaveUnit unit = new SaveUnit();
 		unit.node = node;
+		unit.delegate = delegate;
 		unit.sourceConfiguration = node.acceptVisitor(resourceGetter);
 
 		String targetLocation = nameMapper.configurationLocation(node);
@@ -209,9 +229,17 @@ public class FileProjectSaver implements ProjectSaver {
 	}
 
 	void saveToTempFile(SaveUnit unit, PrintWriter printWriter) {
-		unit.node.acceptVisitor(
-				new ConfigurationSaver(printWriter, getSupportedVersion(), new CompoundSaverDelegate(saverDelegates))
-		);
+		ConfigurationNodeVisitor<?> visitor;
+		if(unit.delegate == null) {
+			visitor = new ConfigurationSaver(printWriter, getSupportedVersion(), delegate);
+		} else {
+			XMLEncoder encoder = new XMLEncoder(printWriter, "\t", getSupportedVersion());
+			encoder.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+			unit.delegate.setXMLEncoder(encoder);
+			visitor = unit.delegate;
+		}
+
+		unit.node.acceptVisitor(visitor);
 	}
 
 	void saveCommit(Collection<SaveUnit> units) {
@@ -330,6 +358,7 @@ public class FileProjectSaver implements ProjectSaver {
 	class SaveUnit {
 
 		private ConfigurationNode node;
+		private SaverDelegate delegate;
 
 		// source can be an abstract resource, but target is always a file...
 		private Resource sourceConfiguration;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseNamingDelegate.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseNamingDelegate.java b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseNamingDelegate.java
new file mode 100644
index 0000000..bbc4cd7
--- /dev/null
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseNamingDelegate.java
@@ -0,0 +1,112 @@
+/*****************************************************************
+ *   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.project.extension;
+
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.map.QueryDescriptor;
+
+/**
+ * @since 4.1
+ */
+public class BaseNamingDelegate implements ConfigurationNodeVisitor<String> {
+
+    @Override
+    public String visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+        return null;
+    }
+
+    @Override
+    public String visitDataNodeDescriptor(DataNodeDescriptor nodeDescriptor) {
+        return null;
+    }
+
+    @Override
+    public String visitDataMap(DataMap dataMap) {
+        return null;
+    }
+
+    @Override
+    public String visitObjEntity(ObjEntity entity) {
+        return null;
+    }
+
+    @Override
+    public String visitDbEntity(DbEntity entity) {
+        return null;
+    }
+
+    @Override
+    public String visitEmbeddable(Embeddable embeddable) {
+        return null;
+    }
+
+    @Override
+    public String visitEmbeddableAttribute(EmbeddableAttribute attribute) {
+        return null;
+    }
+
+    @Override
+    public String visitObjAttribute(ObjAttribute attribute) {
+        return null;
+    }
+
+    @Override
+    public String visitDbAttribute(DbAttribute attribute) {
+        return null;
+    }
+
+    @Override
+    public String visitObjRelationship(ObjRelationship relationship) {
+        return null;
+    }
+
+    @Override
+    public String visitDbRelationship(DbRelationship relationship) {
+        return null;
+    }
+
+    @Override
+    public String visitProcedure(Procedure procedure) {
+        return null;
+    }
+
+    @Override
+    public String visitProcedureParameter(ProcedureParameter parameter) {
+        return null;
+    }
+
+    @Override
+    public String visitQuery(QueryDescriptor query) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseSaverDelegate.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseSaverDelegate.java b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseSaverDelegate.java
index 08565b2..a9f45f2 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseSaverDelegate.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/BaseSaverDelegate.java
@@ -130,4 +130,8 @@ public class BaseSaverDelegate implements SaverDelegate {
     public SaverDelegate getParentDelegate() {
         return parentDelegate;
     }
+
+    protected boolean isStandalone() {
+        return parentDelegate == null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
index cf0a182..319ebe1 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/ProjectExtension.java
@@ -19,6 +19,8 @@
 
 package org.apache.cayenne.project.extension;
 
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+
 /**
  * <p>DataMap XML file extension mechanics.</p>
  * <p>
@@ -45,4 +47,7 @@ public interface ProjectExtension {
      */
     SaverDelegate createSaverDelegate();
 
+
+    ConfigurationNodeVisitor<String> createNamingDelegate();
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
index ecbf8f1..0915638 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/extension/info/InfoExtension.java
@@ -19,9 +19,11 @@
 
 package org.apache.cayenne.project.extension.info;
 
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.project.Project;
+import org.apache.cayenne.project.extension.BaseNamingDelegate;
 import org.apache.cayenne.project.extension.LoaderDelegate;
 import org.apache.cayenne.project.extension.ProjectExtension;
 import org.apache.cayenne.project.extension.SaverDelegate;
@@ -49,4 +51,9 @@ public class InfoExtension implements ProjectExtension {
     public SaverDelegate createSaverDelegate() {
         return new InfoSaverDelegate(metaData);
     }
+
+    @Override
+    public ConfigurationNodeVisitor<String> createNamingDelegate() {
+        return new BaseNamingDelegate();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index 233c580..d5d604d 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -112,6 +112,13 @@
 			<groupId>com.mockrunner</groupId>
 			<artifactId>mockrunner-jdbc</artifactId>
 			<scope>test</scope>
+			<exclusions>
+				<exclusion>
+					<!-- this one have old Xerces dependency that clashes with JDK's one -->
+					<groupId>nekohtml</groupId>
+					<artifactId>nekohtml</artifactId>
+				</exclusion>
+			</exclusions>
 		</dependency>
 		<dependency>
 			<groupId>com.mockrunner</groupId>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
index e9d104e..a1de6c6 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
@@ -126,6 +126,7 @@ public class XMLDataChannelDescriptorLoader implements DataChannelDescriptorLoad
 
 		try(InputStream in = configurationURL.openStream()) {
 			XMLReader parser = Util.createXmlReader();
+			parser.setFeature("http://apache.org/xml/features/xinclude", true);
 			LoaderContext loaderContext = new LoaderContext(parser, handlerFactory);
 			loaderContext.addDataMapListener(new DataMapLoaderListener() {
 				@Override
@@ -137,7 +138,9 @@ public class XMLDataChannelDescriptorLoader implements DataChannelDescriptorLoad
 			DataChannelHandler rootHandler = new DataChannelHandler(this, descriptor, loaderContext);
 			parser.setContentHandler(rootHandler);
 			parser.setErrorHandler(rootHandler);
-			parser.parse(new InputSource(in));
+			InputSource input = new InputSource(in);
+			input.setSystemId(configurationURL.toString());
+			parser.parse(input);
 		} catch (Exception e) {
 			throw new ConfigurationException("Error loading configuration from %s", e, configurationURL);
 		}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
index 68b236d..37fe689 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataMapLoader.java
@@ -45,6 +45,7 @@ public class XMLDataMapLoader implements DataMapLoader {
     public synchronized DataMap load(Resource configurationResource) throws CayenneRuntimeException {
         try(InputStream in = configurationResource.getURL().openStream()) {
             XMLReader parser = Util.createXmlReader();
+            parser.setFeature("http://apache.org/xml/features/xinclude", true);
             LoaderContext loaderContext = new LoaderContext(parser, handlerFactory);
             loaderContext.addDataMapListener(new DataMapLoaderListener() {
                 @Override
@@ -56,7 +57,9 @@ public class XMLDataMapLoader implements DataMapLoader {
 
             parser.setContentHandler(rootHandler);
             parser.setErrorHandler(rootHandler);
-            parser.parse(new InputSource(in));
+            InputSource input = new InputSource(in);
+            input.setSystemId(configurationResource.getURL().toString());
+            parser.parse(input);
         } catch (Exception e) {
             throw new CayenneRuntimeException("Error loading configuration from %s", e, configurationResource.getURL());
         }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/3939efe4/modeler/cayenne-modeler/pom.xml
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/pom.xml b/modeler/cayenne-modeler/pom.xml
index 107340d..6f9fc2e 100644
--- a/modeler/cayenne-modeler/pom.xml
+++ b/modeler/cayenne-modeler/pom.xml
@@ -95,6 +95,13 @@
 		<dependency>
 			<groupId>com.mockrunner</groupId>
 			<artifactId>mockrunner-jdbc</artifactId>
+			<exclusions>
+				<exclusion>
+					<!-- this one have old Xerces dependency that clashes with JDK's one -->
+					<groupId>nekohtml</groupId>
+					<artifactId>nekohtml</artifactId>
+				</exclusion>
+			</exclusions>
 		</dependency>
 
 		<dependency>


[4/5] cayenne git commit: CAY-2340 Save additional metadata as separate files Support namespace-aware loading in DataChannelHandlers

Posted by nt...@apache.org.
CAY-2340 Save additional metadata as separate files
   Support namespace-aware loading in DataChannelHandlers


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

Branch: refs/heads/master
Commit: 13ead3f8180d213dd28b079fb29c11335425aa44
Parents: 3939efe
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Aug 1 18:26:02 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Aug 2 16:23:56 2017 +0300

----------------------------------------------------------------------
 .../src/test/resources/cayenne-lifecycle.xml    |  3 +-
 .../cayenne-relationship-optimisation.xml       |  3 +-
 .../cayenne/project/FileProjectSaver.java       |  9 +++---
 .../xml/DataChannelChildrenHandler.java         |  2 +-
 .../configuration/xml/DataChannelHandler.java   |  5 ++--
 .../xml/DataChannelLoaderListener.java          | 29 ++++++++++++++++++++
 .../xml/DataNodeChildrenHandler.java            |  4 +--
 .../xml/DataSourceChildrenHandler.java          |  2 +-
 .../configuration/xml/LoaderContext.java        | 19 +++++++++++--
 .../xml/XMLDataChannelDescriptorLoader.java     |  2 ++
 .../test/resources/cay743/cayenne-domain.xml    |  2 +-
 .../src/test/resources/cayenne-testmap.xml      |  3 +-
 .../configuration/xml/cayenne-testConfig1.xml   |  2 +-
 .../configuration/xml/cayenne-testConfig2.xml   |  2 +-
 .../configuration/xml/cayenne-testConfig3.xml   |  2 +-
 15 files changed, 69 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-cache-invalidation/src/test/resources/cayenne-lifecycle.xml
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/test/resources/cayenne-lifecycle.xml b/cayenne-cache-invalidation/src/test/resources/cayenne-lifecycle.xml
index 98ab346..6bbecc7 100644
--- a/cayenne-cache-invalidation/src/test/resources/cayenne-lifecycle.xml
+++ b/cayenne-cache-invalidation/src/test/resources/cayenne-lifecycle.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+	project-version="10">
 	<map name="lifecycle-map"/>
 
 	<node name="lifecycle-db"

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-dbsync/src/test/resources/org/apache/cayenne/dbsync/reverse/dbimport/cayenne-relationship-optimisation.xml
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/resources/org/apache/cayenne/dbsync/reverse/dbimport/cayenne-relationship-optimisation.xml b/cayenne-dbsync/src/test/resources/org/apache/cayenne/dbsync/reverse/dbimport/cayenne-relationship-optimisation.xml
index 166a67d..25f988a 100644
--- a/cayenne-dbsync/src/test/resources/org/apache/cayenne/dbsync/reverse/dbimport/cayenne-relationship-optimisation.xml
+++ b/cayenne-dbsync/src/test/resources/org/apache/cayenne/dbsync/reverse/dbimport/cayenne-relationship-optimisation.xml
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+	project-version="10">
 	<map name="relationship-optimisation"/>
 </domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
index e76022a..0d6af44 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/FileProjectSaver.java
@@ -142,16 +142,13 @@ public class FileProjectSaver implements ProjectSaver {
 		project.getUnusedResources().clear();
 	}
 
-	SaveUnit createSaveUnit(ConfigurationNode node, Resource baseResource, SaverDelegate delegate) {
+	SaveUnit createSaveUnit(ConfigurationNode node, Resource targetResource, SaverDelegate delegate) {
 
 		SaveUnit unit = new SaveUnit();
 		unit.node = node;
 		unit.delegate = delegate;
 		unit.sourceConfiguration = node.acceptVisitor(resourceGetter);
 
-		String targetLocation = nameMapper.configurationLocation(node);
-		Resource targetResource = baseResource.getRelativeResource(targetLocation);
-
 		if (unit.sourceConfiguration == null) {
 			unit.sourceConfiguration = targetResource;
 		}
@@ -267,7 +264,9 @@ public class FileProjectSaver implements ProjectSaver {
 
 			unit.targetTempFile = null;
 			try {
-				unit.node.acceptVisitor(new ConfigurationSourceSetter(new URLResource(targetFile.toURI().toURL())));
+				if(unit.delegate == null) {
+					unit.node.acceptVisitor(new ConfigurationSourceSetter(new URLResource(targetFile.toURI().toURL())));
+				}
 			} catch (MalformedURLException e) {
 				throw new CayenneRuntimeException("Malformed URL for file '%s'", e, targetFile.getAbsolutePath());
 			}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelChildrenHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelChildrenHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelChildrenHandler.java
index 9dc65af..ddca060 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelChildrenHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelChildrenHandler.java
@@ -32,7 +32,7 @@ import org.xml.sax.ContentHandler;
 /**
  * @since 4.1
  */
-final class DataChannelChildrenHandler extends SAXNestedTagHandler {
+final class DataChannelChildrenHandler extends NamespaceAwareNestedTagHandler {
 
     private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelHandler.java
index e5e4c71..476bb9c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelHandler.java
@@ -31,7 +31,7 @@ import org.xml.sax.SAXException;
 /**
  * @since 4.1
  */
-final class DataChannelHandler extends SAXNestedTagHandler {
+final class DataChannelHandler extends NamespaceAwareNestedTagHandler {
 
     private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
 
@@ -44,6 +44,7 @@ final class DataChannelHandler extends SAXNestedTagHandler {
         super(loaderContext);
         this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
         this.descriptor = dataChannelDescriptor;
+        setTargetNamespace(DataChannelDescriptor.SCHEMA_XSD);
     }
 
     @Override
@@ -53,7 +54,7 @@ final class DataChannelHandler extends SAXNestedTagHandler {
                 validateVersion(attributes);
                 return true;
         }
-        return super.processElement(namespaceURI, localName, attributes);
+        return false;
     }
 
     protected void validateVersion(Attributes attributes) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelLoaderListener.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelLoaderListener.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelLoaderListener.java
new file mode 100644
index 0000000..065bc1f
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelLoaderListener.java
@@ -0,0 +1,29 @@
+/*****************************************************************
+ *   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.configuration.xml;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+
+/**
+ * @since 4.1
+ */
+public interface DataChannelLoaderListener {
+    void onDataChannelLoaded(DataChannelDescriptor dataChannelDescriptor);
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
index b98bd73..f6e2d1d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
@@ -27,7 +27,7 @@ import org.xml.sax.ContentHandler;
 /**
  * @since 4.1
  */
-final class DataNodeChildrenHandler extends SAXNestedTagHandler {
+final class DataNodeChildrenHandler extends NamespaceAwareNestedTagHandler {
 
     static final String DATA_SOURCE_TAG = "data-source";
     static final String MAP_REF_TAG = "map-ref";
@@ -37,7 +37,7 @@ final class DataNodeChildrenHandler extends SAXNestedTagHandler {
 
     private DataSourceInfo dataSourceDescriptor;
 
-    DataNodeChildrenHandler(XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader, SAXNestedTagHandler parentHandler, DataNodeDescriptor nodeDescriptor) {
+    DataNodeChildrenHandler(XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader, NamespaceAwareNestedTagHandler parentHandler, DataNodeDescriptor nodeDescriptor) {
         super(parentHandler);
         this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
         this.nodeDescriptor = nodeDescriptor;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
index b860b1f..066dd31 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
@@ -33,7 +33,7 @@ import org.xml.sax.Attributes;
 /**
  * @since 4.1
  */
-class DataSourceChildrenHandler extends SAXNestedTagHandler {
+class DataSourceChildrenHandler extends NamespaceAwareNestedTagHandler {
 
     private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/LoaderContext.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/LoaderContext.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/LoaderContext.java
index 9507e4f..4e70cf4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/LoaderContext.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/LoaderContext.java
@@ -22,6 +22,8 @@ package org.apache.cayenne.configuration.xml;
 import java.util.ArrayList;
 import java.util.Collection;
 
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
 import org.apache.cayenne.map.DataMap;
 import org.xml.sax.XMLReader;
 
@@ -32,6 +34,8 @@ public class LoaderContext {
 
     Collection<DataMapLoaderListener> dataMapListeners;
 
+    Collection<DataChannelLoaderListener> dataChannelListeners;
+
     private XMLReader xmlReader;
 
     private HandlerFactory factory;
@@ -40,6 +44,7 @@ public class LoaderContext {
         this.xmlReader = reader;
         this.factory = factory;
         dataMapListeners = new ArrayList<>();
+        dataChannelListeners = new ArrayList<>();
     }
 
     public HandlerFactory getFactory() {
@@ -50,8 +55,8 @@ public class LoaderContext {
         return xmlReader;
     }
 
-    public void addDataMapListener(DataMapLoaderListener dataMapLoaderListener) {
-        dataMapListeners.add(dataMapLoaderListener);
+    public void addDataMapListener(DataMapLoaderListener listener) {
+        dataMapListeners.add(listener);
     }
 
     public void dataMapLoaded(DataMap dataMap) {
@@ -60,4 +65,14 @@ public class LoaderContext {
         }
     }
 
+    public void addDataChannelListener(DataChannelLoaderListener listener) {
+        dataChannelListeners.add(listener);
+    }
+
+    public void dataChannelLoaded(DataChannelDescriptor descriptor) {
+        for(DataChannelLoaderListener listener : dataChannelListeners) {
+            listener.onDataChannelLoaded(descriptor);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
index a1de6c6..0682bb2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/XMLDataChannelDescriptorLoader.java
@@ -141,6 +141,8 @@ public class XMLDataChannelDescriptorLoader implements DataChannelDescriptorLoad
 			InputSource input = new InputSource(in);
 			input.setSystemId(configurationURL.toString());
 			parser.parse(input);
+
+            loaderContext.dataChannelLoaded(descriptor);
 		} catch (Exception e) {
 			throw new ConfigurationException("Error loading configuration from %s", e, configurationURL);
 		}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/test/resources/cay743/cayenne-domain.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/cay743/cayenne-domain.xml b/cayenne-server/src/test/resources/cay743/cayenne-domain.xml
index b69e50c..be87528 100644
--- a/cayenne-server/src/test/resources/cay743/cayenne-domain.xml
+++ b/cayenne-server/src/test/resources/cay743/cayenne-domain.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain project-version="10" xmlns="http://cayenne.apache.org/schema/10/domain">
 	<map name="map1"/>
 	<map name="map2"/>
 </domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/test/resources/cayenne-testmap.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/cayenne-testmap.xml b/cayenne-server/src/test/resources/cayenne-testmap.xml
index 9d8918c..3f269c0 100644
--- a/cayenne-server/src/test/resources/cayenne-testmap.xml
+++ b/cayenne-server/src/test/resources/cayenne-testmap.xml
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+	project-version="10">
 	<map name="testmap"/>
 </domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig1.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig1.xml b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig1.xml
index 0171ef2..e081f4c 100644
--- a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig1.xml
+++ b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig1.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain project-version="10" xmlns="http://cayenne.apache.org/schema/10/domain">
 	
 </domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig2.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig2.xml b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig2.xml
index 8d841a5..bf4d451 100644
--- a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig2.xml
+++ b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig2.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain project-version="10" xmlns="http://cayenne.apache.org/schema/10/domain">
 	<map name="testConfigMap2" location="testConfigMap2.map.xml"/>
 </domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13ead3f8/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig3.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig3.xml b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig3.xml
index 71f687a..9b626ce 100644
--- a/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig3.xml
+++ b/cayenne-server/src/test/resources/org/apache/cayenne/configuration/xml/cayenne-testConfig3.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<domain project-version="10">
+<domain project-version="10" xmlns="http://cayenne.apache.org/schema/10/domain">
 	<map name="testConfigMap3_1" location="testConfigMap3_1.map.xml" />
 	<map name="testConfigMap3_2" location="testConfigMap3_2.map.xml" />
 


[5/5] cayenne git commit: CAY-2344 Modeler: Save ER-Graph and class diagram minor cleanup

Posted by nt...@apache.org.
CAY-2344 Modeler: Save ER-Graph and class diagram
   minor cleanup


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

Branch: refs/heads/master
Commit: caaeb99bf75fcc1fa50ade5d14d43c3e1aa642c1
Parents: f16810a
Author: Nikita Timofeev <st...@gmail.com>
Authored: Wed Aug 2 16:46:02 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Aug 2 16:46:02 2017 +0300

----------------------------------------------------------------------
 .../cayenne/modeler/graph/extension/GraphExtension.java  | 11 ++++++++++-
 .../modeler/graph/extension/GraphSaverDelegate.java      | 11 ++++++-----
 2 files changed, 16 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/caaeb99b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
index 74e129a..a09917e 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphExtension.java
@@ -24,6 +24,7 @@ import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Provider;
 import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.graph.GraphRegistry;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.project.extension.BaseNamingDelegate;
 import org.apache.cayenne.project.extension.LoaderDelegate;
@@ -37,6 +38,8 @@ public class GraphExtension implements ProjectExtension {
 
     static final String NAMESPACE = "http://cayenne.apache.org/schema/" + Project.VERSION + "/graph";
 
+    static final String GRAPH_SUFFIX = ".graph.xml";
+
     @Inject
     protected Provider<Application> applicationProvider;
 
@@ -55,7 +58,13 @@ public class GraphExtension implements ProjectExtension {
         return new BaseNamingDelegate() {
             @Override
             public String visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
-                return channelDescriptor.getName() + ".graph.xml";
+                // if there is no registry, than there is no need to save anything
+                GraphRegistry registry = applicationProvider.get().getMetaData()
+                        .get(channelDescriptor, GraphRegistry.class);
+                if (registry == null) {
+                    return null;
+                }
+                return channelDescriptor.getName() + GRAPH_SUFFIX;
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/caaeb99b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java
index b5e5d52..b821f31 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/graph/extension/GraphSaverDelegate.java
@@ -38,6 +38,11 @@ class GraphSaverDelegate extends BaseSaverDelegate {
 
     @Override
     public Void visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+        GraphRegistry registry = metaData.get(channelDescriptor, GraphRegistry.class);
+        if (registry == null) {
+            return null;
+        }
+
         if(isStandalone()) {
             printGraphs(channelDescriptor);
         } else {
@@ -49,10 +54,6 @@ class GraphSaverDelegate extends BaseSaverDelegate {
 
     private void printGraphs(DataChannelDescriptor channelDescriptor) {
         GraphRegistry registry = metaData.get(channelDescriptor, GraphRegistry.class);
-        if (registry == null) {
-            return;
-        }
-
         GraphMap map = registry.getGraphMap(channelDescriptor);
         encoder.start("graphs")
                 .attribute("xmlns", GraphExtension.NAMESPACE)
@@ -64,7 +65,7 @@ class GraphSaverDelegate extends BaseSaverDelegate {
     private void printInclude(DataChannelDescriptor channelDescriptor) {
         encoder.start("xi:include")
                 .attribute("xmlns:xi", "http://www.w3.org/2001/XInclude")
-                .attribute("href", channelDescriptor.getName() + ".graph.xml")
+                .attribute("href", channelDescriptor.getName() + GraphExtension.GRAPH_SUFFIX)
                 .end();
     }