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/07/25 12:25:24 UTC
[09/16] cayenne git commit: CAY-2335: New XML loading/saving
mechanics with support of plugable handlers - new XML loader for DataMap -
new project version - updated test projects
CAY-2335: New XML loading/saving mechanics with support of plugable handlers
- new XML loader for DataMap
- new project version
- updated test projects
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/c58b6f40
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/c58b6f40
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/c58b6f40
Branch: refs/heads/master
Commit: c58b6f406e81de4d90abe888b763a1292c77feb8
Parents: 2c9896c
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Jul 25 12:35:50 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Tue Jul 25 12:35:50 2017 +0300
----------------------------------------------------------------------
.../upgrade/v6/XMLDataMapLoader_V3_0_0_1.java | 51 -
.../project/upgrade/v8/ProjectUpgrader_V8.java | 42 -
.../configuration/DataChannelDescriptor.java | 46 +-
.../configuration/DataNodeDescriptor.java | 39 +-
.../EmptyConfigurationNodeVisitor.java | 108 ++
.../configuration/SAXNestedTagHandler.java | 131 --
.../XMLDataChannelDescriptorLoader.java | 389 ------
.../cayenne/configuration/XMLDataMapLoader.java | 57 -
.../configuration/server/ServerModule.java | 11 +-
.../xml/DataChannelChildrenHandler.java | 133 ++
.../configuration/xml/DataChannelHandler.java | 78 ++
.../configuration/xml/DataChannelMetaData.java | 64 +
.../configuration/xml/DataMapHandler.java | 142 ++
.../xml/DataMapLoaderListener.java | 31 +
.../xml/DataNodeChildrenHandler.java | 71 +
.../xml/DataSourceChildrenHandler.java | 175 +++
.../configuration/xml/DbEntityHandler.java | 146 ++
.../xml/DbKeyGeneratorHandler.java | 117 ++
.../xml/DbRelationshipHandler.java | 97 ++
.../xml/DefaultDataChannelMetaData.java | 91 ++
.../xml/DefaultHandlerFactory.java | 44 +
.../xml/EmbeddableAttributeHandler.java | 69 +
.../configuration/xml/EmbeddableHandler.java | 75 ++
.../configuration/xml/HandlerFactory.java | 30 +
.../configuration/xml/LoaderContext.java | 63 +
.../xml/NamespaceAwareNestedTagHandler.java | 97 ++
.../xml/NoopDataChannelMetaData.java | 42 +
.../configuration/xml/ObjEntityHandler.java | 210 +++
.../xml/ObjRelationshipHandler.java | 109 ++
.../configuration/xml/ProcedureHandler.java | 114 ++
.../xml/QueryDescriptorHandler.java | 191 +++
.../configuration/xml/RootDataMapHandler.java | 51 +
.../configuration/xml/SAXNestedTagHandler.java | 175 +++
.../xml/XMLDataChannelDescriptorLoader.java | 149 +++
.../configuration/xml/XMLDataMapLoader.java | 102 ++
.../org/apache/cayenne/conn/DataSourceInfo.java | 47 +-
.../java/org/apache/cayenne/exp/Expression.java | 10 +-
.../java/org/apache/cayenne/map/Attribute.java | 4 +-
.../org/apache/cayenne/map/CallbackMap.java | 6 +-
.../java/org/apache/cayenne/map/DataMap.java | 131 +-
.../org/apache/cayenne/map/DbAttribute.java | 32 +-
.../java/org/apache/cayenne/map/DbEntity.java | 33 +-
.../java/org/apache/cayenne/map/DbJoin.java | 24 +-
.../org/apache/cayenne/map/DbKeyGenerator.java | 29 +-
.../org/apache/cayenne/map/DbRelationship.java | 28 +-
.../cayenne/map/EJBQLQueryDescriptor.java | 19 +-
.../java/org/apache/cayenne/map/Embeddable.java | 20 +-
.../apache/cayenne/map/EmbeddableAttribute.java | 26 +-
.../apache/cayenne/map/EmbeddedAttribute.java | 33 +-
.../org/apache/cayenne/map/EntityListener.java | 4 +-
.../java/org/apache/cayenne/map/MapLoader.java | 1261 ------------------
.../org/apache/cayenne/map/ObjAttribute.java | 32 +-
.../java/org/apache/cayenne/map/ObjEntity.java | 86 +-
.../org/apache/cayenne/map/ObjRelationship.java | 49 +-
.../java/org/apache/cayenne/map/Procedure.java | 39 +-
.../apache/cayenne/map/ProcedureParameter.java | 47 +-
.../cayenne/map/ProcedureQueryDescriptor.java | 36 +-
.../org/apache/cayenne/map/QueryDescriptor.java | 58 +-
.../cayenne/map/QueryDescriptorLoader.java | 32 +-
.../cayenne/map/SQLTemplateDescriptor.java | 53 +-
.../cayenne/map/SelectQueryDescriptor.java | 46 +-
.../apache/cayenne/query/BaseQueryMetadata.java | 38 +-
.../org/apache/cayenne/query/EJBQLQuery.java | 25 +-
.../java/org/apache/cayenne/query/Ordering.java | 26 +-
.../apache/cayenne/query/PrefetchTreeNode.java | 34 +-
.../apache/cayenne/query/ProcedureQuery.java | 52 +-
.../org/apache/cayenne/query/SQLTemplate.java | 91 +-
.../org/apache/cayenne/query/SelectQuery.java | 72 +-
.../reflect/LifecycleCallbackEventHandler.java | 19 +-
.../cayenne/remote/IncrementalSelectQuery.java | 5 -
.../org/apache/cayenne/util/XMLEncoder.java | 326 +++--
.../apache/cayenne/util/XMLSerializable.java | 4 +-
.../org/apache/cayenne/schema/10/dbimport.xsd | 106 ++
.../org/apache/cayenne/schema/10/domain.xsd | 130 ++
.../org/apache/cayenne/schema/10/info.xsd | 29 +
.../org/apache/cayenne/schema/10/modelMap.xsd | 356 +++++
.../XMLDataChannelDescriptorLoaderTest.java | 165 ---
.../configuration/xml/BaseHandlerTest.java | 76 ++
.../configuration/xml/DbEntityHandlerTest.java | 82 ++
.../xml/DbKeyGeneratorHandlerTest.java | 51 +
.../xml/DbRelationshipHandlerTest.java | 58 +
.../configuration/xml/ObjEntityHandlerTest.java | 86 ++
.../xml/ObjRelationshipHandlerTest.java | 61 +
.../xml/XMLDataChannelDescriptorLoaderTest.java | 171 +++
.../configuration/xml/XMLDataMapLoaderTest.java | 158 +++
.../org/apache/cayenne/map/DataMapTest.java | 41 +-
.../apache/cayenne/map/MapLoaderLoadTest.java | 175 ---
.../org/apache/cayenne/map/MockAttribute.java | 4 +-
.../java/org/apache/cayenne/map/MockEntity.java | 4 +-
.../apache/cayenne/map/MockRelationship.java | 4 +-
.../apache/cayenne/map/ObjRelationshipIT.java | 6 +-
.../cayenne/map/QueryDescriptorLoaderTest.java | 6 +-
.../org/apache/cayenne/query/EJBQLQueryIT.java | 30 +-
.../cayenne/unit/di/server/DBCleaner.java | 2 +-
.../cayenne/unit/di/server/SchemaBuilder.java | 16 +-
.../unit/di/server/ServerCaseModule.java | 8 +-
.../src/test/resources/array-type.map.xml | 32 +-
.../src/test/resources/binary-pk.map.xml | 64 +-
.../src/test/resources/cay-2032.map.xml | 13 +-
.../test/resources/cay743/cayenne-domain.xml | 2 +-
.../src/test/resources/cay743/map1.map.xml | 6 +-
.../src/test/resources/cay743/map2.map.xml | 6 +-
.../src/test/resources/cayenne-array-type.xml | 5 +-
.../src/test/resources/cayenne-binary-pk.xml | 5 +-
.../src/test/resources/cayenne-cay-2032.xml | 3 +-
.../src/test/resources/cayenne-compound.xml | 5 +-
.../src/test/resources/cayenne-date-time.xml | 5 +-
.../src/test/resources/cayenne-delete-rules.xml | 5 +-
.../src/test/resources/cayenne-embeddable.xml | 5 +-
.../src/test/resources/cayenne-empty.xml | 5 +-
.../src/test/resources/cayenne-enum.xml | 3 +-
.../test/resources/cayenne-extended-type.xml | 5 +-
.../src/test/resources/cayenne-generated.xml | 5 +-
.../src/test/resources/cayenne-generic.xml | 5 +-
.../cayenne-inheritance-single-table1.xml | 3 +-
.../resources/cayenne-inheritance-vertical.xml | 3 +-
.../src/test/resources/cayenne-inheritance.xml | 5 +-
.../cayenne-lifecycle-callbacks-order.xml | 5 +-
.../src/test/resources/cayenne-lifecycles.xml | 5 +-
.../src/test/resources/cayenne-lob.xml | 5 +-
.../src/test/resources/cayenne-locking.xml | 3 +-
.../src/test/resources/cayenne-map-to-many.xml | 5 +-
.../test/resources/cayenne-meaningful-pk.xml | 5 +-
.../src/test/resources/cayenne-misc-types.xml | 5 +-
.../cayenne-mixed-persistence-strategy.xml | 5 +-
.../src/test/resources/cayenne-multi-tier.xml | 3 +-
.../src/test/resources/cayenne-multinode.xml | 3 +-
.../src/test/resources/cayenne-no-pk.xml | 5 +-
.../test/resources/cayenne-numeric-types.xml | 5 +-
.../src/test/resources/cayenne-oneway-rels.xml | 3 +-
...nne.configuration.rop.server.test-config.xml | 4 +-
.../src/test/resources/cayenne-people.xml | 3 +-
.../src/test/resources/cayenne-primitive.xml | 5 +-
.../src/test/resources/cayenne-qualified.xml | 3 +-
.../resources/cayenne-quoted-identifiers.xml | 3 +-
.../src/test/resources/cayenne-reflexive.xml | 5 +-
.../cayenne-relationships-activity.xml | 3 +-
.../cayenne-relationships-child-master.xml | 5 +-
.../resources/cayenne-relationships-clob.xml | 3 +-
...cayenne-relationships-collection-to-many.xml | 5 +-
.../cayenne-relationships-delete-rules.xml | 5 +-
.../cayenne-relationships-flattened.xml | 3 +-
.../cayenne-relationships-set-to-many.xml | 5 +-
.../cayenne-relationships-to-many-fk.xml | 5 +-
.../cayenne-relationships-to-one-fk.xml | 5 +-
.../test/resources/cayenne-relationships.xml | 3 +-
.../src/test/resources/cayenne-return-types.xml | 5 +-
.../src/test/resources/cayenne-soft-delete.xml | 5 +-
.../src/test/resources/cayenne-sus.xml | 3 +-
.../test/resources/cayenne-table-primitives.xml | 5 +-
.../src/test/resources/cayenne-testmap.xml | 2 +-
.../src/test/resources/cayenne-things.xml | 5 +-
.../src/test/resources/cayenne-toone.xml | 5 +-
.../cayenne-unsupported-distinct-types.xml | 3 +-
.../src/test/resources/cayenne-uuid.xml | 5 +-
.../test/resources/cayenne-weighted-sort.xml | 3 +-
.../src/test/resources/compound.map.xml | 124 +-
.../src/test/resources/custom-name-file.xml | 2 +-
.../src/test/resources/date-time.map.xml | 64 +-
.../src/test/resources/delete-rules.map.xml | 124 +-
.../src/test/resources/embeddable.map.xml | 6 +-
cayenne-server/src/test/resources/empty.map.xml | 14 +-
cayenne-server/src/test/resources/enum.map.xml | 6 +-
.../src/test/resources/extended-type.map.xml | 32 +-
.../src/test/resources/generated.map.xml | 180 ++-
.../src/test/resources/generic.map.xml | 8 +-
.../resources/inheritance-single-table1.map.xml | 18 +-
.../test/resources/inheritance-vertical.map.xml | 59 +-
.../src/test/resources/inheritance.map.xml | 86 +-
.../resources/lifecycle-callbacks-order.map.xml | 28 +-
.../src/test/resources/lifecycles.map.xml | 28 +-
cayenne-server/src/test/resources/lob.map.xml | 102 +-
.../src/test/resources/locking.map.xml | 10 +-
.../src/test/resources/map-db1.map.xml | 6 +-
.../src/test/resources/map-db2.map.xml | 10 +-
.../src/test/resources/map-to-many.map.xml | 99 +-
.../src/test/resources/meaningful-pk.map.xml | 74 +-
.../src/test/resources/misc-types.map.xml | 72 +-
.../mixed-persistence-strategy.map.xml | 68 +-
.../src/test/resources/multi-tier.map.xml | 23 +-
cayenne-server/src/test/resources/no-pk.map.xml | 30 +-
.../src/test/resources/numeric-types.map.xml | 154 +--
.../src/test/resources/oneway-rels.map.xml | 17 +-
.../configuration/cayenne-testConfig1.xml | 4 -
.../configuration/cayenne-testConfig2.xml | 4 -
.../configuration/cayenne-testConfig3.xml | 14 -
.../configuration/testConfigMap2.map.xml | 7 -
.../configuration/testConfigMap3_1.map.xml | 7 -
.../configuration/testConfigMap3_2.map.xml | 7 -
.../configuration/xml/DbEntityHandlerTest.xml | 25 +
.../xml/DbKeyGeneratorHandlerTest.xml | 24 +
.../xml/DbRelationshipHandlerTest.xml | 22 +
.../configuration/xml/ObjEntityHandlerTest.xml | 38 +
.../xml/ObjRelationshipHandlerTest.xml | 20 +
.../configuration/xml/cayenne-testConfig1.xml | 4 +
.../configuration/xml/cayenne-testConfig2.xml | 4 +
.../configuration/xml/cayenne-testConfig3.xml | 14 +
.../configuration/xml/testConfigMap2.map.xml | 26 +
.../configuration/xml/testConfigMap3_1.map.xml | 26 +
.../configuration/xml/testConfigMap3_2.map.xml | 26 +
.../configuration/xml/testConfigMap4.map.xml | 314 +++++
.../src/test/resources/people.map.xml | 16 +-
.../src/test/resources/primitive.map.xml | 36 +-
.../src/test/resources/qualified.map.xml | 8 +-
.../test/resources/quoted-identifiers.map.xml | 10 +-
.../src/test/resources/reflexive.map.xml | 46 +-
.../resources/relationships-activity.map.xml | 6 +-
.../relationships-child-master.map.xml | 52 +-
.../test/resources/relationships-clob.map.xml | 8 +-
.../relationships-collection-to-many.map.xml | 46 +-
.../relationships-delete-rules.map.xml | 133 +-
.../resources/relationships-flattened.map.xml | 29 +-
.../resources/relationships-set-to-many.map.xml | 46 +-
.../resources/relationships-to-many-fk.map.xml | 92 +-
.../resources/relationships-to-one-fk.map.xml | 46 +-
.../src/test/resources/relationships.map.xml | 17 +-
.../src/test/resources/return-types.map.xml | 180 +--
.../src/test/resources/soft-delete.map.xml | 32 +-
.../src/test/resources/sus-map.map.xml | 6 +-
.../src/test/resources/table-primitives.map.xml | 32 +-
.../src/test/resources/testmap.map.xml | 39 +-
.../src/test/resources/things.map.xml | 216 +--
cayenne-server/src/test/resources/toone.map.xml | 48 +-
.../unsupported-distinct-types.map.xml | 42 +-
.../resources/url conversion/cayenne-empty.xml | 4 +
.../test/resources/url conversion/empty.map.xml | 9 +
cayenne-server/src/test/resources/uuid.map.xml | 44 +-
.../src/test/resources/weighted-sort.map.xml | 14 +-
228 files changed, 6936 insertions(+), 4946 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v6/XMLDataMapLoader_V3_0_0_1.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v6/XMLDataMapLoader_V3_0_0_1.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v6/XMLDataMapLoader_V3_0_0_1.java
deleted file mode 100644
index 6dc3d52..0000000
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v6/XMLDataMapLoader_V3_0_0_1.java
+++ /dev/null
@@ -1,51 +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.project.upgrade.v6;
-
-import java.io.InputStream;
-import java.net.URL;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.MapLoader;
-import org.apache.cayenne.resource.Resource;
-import org.xml.sax.InputSource;
-
-/**
- * @since 3.1
- */
-class XMLDataMapLoader_V3_0_0_1 {
-
- public DataMap load(Resource configurationResource) throws CayenneRuntimeException {
-
- MapLoader mapLoader = new MapLoader();
- URL url = configurationResource.getURL();
-
- DataMap map;
-
- try (InputStream in = url.openStream();) {
-
- map = mapLoader.loadDataMap(new InputSource(in));
- } catch (Exception e) {
- throw new CayenneRuntimeException("Error loading configuration from %s", e, url);
- }
-
- return map;
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v8/ProjectUpgrader_V8.java
----------------------------------------------------------------------
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v8/ProjectUpgrader_V8.java b/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v8/ProjectUpgrader_V8.java
deleted file mode 100644
index 461d118..0000000
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/upgrade/v8/ProjectUpgrader_V8.java
+++ /dev/null
@@ -1,42 +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.project.upgrade.v8;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.di.Injector;
-import org.apache.cayenne.project.upgrade.ProjectUpgrader;
-import org.apache.cayenne.project.upgrade.UpgradeHandler;
-import org.apache.cayenne.resource.Resource;
-
-/**
- * A ProjectUpgrader that handles project upgrades from version 4.0.M3 and 7
- * to version 8.
- */
-public class ProjectUpgrader_V8 implements ProjectUpgrader {
-
- @Inject
- protected Injector injector;
-
- @Override
- public UpgradeHandler getUpgradeHandler(Resource projectSource) {
- UpgradeHandler_V8 handler = new UpgradeHandler_V8(projectSource);
- injector.injectMembers(handler);
- return handler;
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptor.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptor.java
index bc3929b..92bd8bb 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptor.java
@@ -40,6 +40,11 @@ public class DataChannelDescriptor implements ConfigurationNode, Serializable, X
private static final long serialVersionUID = 6567527544207035602L;
+ /**
+ * The namespace in which the data map XML file will be created.
+ */
+ public static final String SCHEMA_XSD = "http://cayenne.apache.org/schema/10/domain";
+
protected String name;
protected Map<String, String> properties;
protected Collection<DataMap> dataMaps;
@@ -53,58 +58,41 @@ public class DataChannelDescriptor implements ConfigurationNode, Serializable, X
nodeDescriptors = new ArrayList<>(3);
}
- public void encodeAsXML(XMLEncoder encoder) {
+ @Override
+ public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
- encoder.print("<domain");
- encoder.printProjectVersion();
- encoder.println(">");
-
- encoder.indent(1);
- boolean breakNeeded = false;
+ encoder.start("domain")
+ .attribute("xmlns", SCHEMA_XSD)
+ .attribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance", true)
+ .attribute("xsi:schemaLocation", SCHEMA_XSD + " " + SCHEMA_XSD + ".xsd", true)
+ .projectVersion();
if (!properties.isEmpty()) {
- breakNeeded = true;
-
List<String> keys = new ArrayList<>(properties.keySet());
Collections.sort(keys);
for (String key : keys) {
- encoder.printProperty(key, properties.get(key));
+ encoder.property(key, properties.get(key));
}
}
if (!dataMaps.isEmpty()) {
- if (breakNeeded) {
- encoder.println();
- } else {
- breakNeeded = true;
- }
-
List<DataMap> maps = new ArrayList<>(this.dataMaps);
Collections.sort(maps);
for (DataMap dataMap : maps) {
-
- encoder.print("<map");
- encoder.printAttribute("name", dataMap.getName().trim());
- encoder.println("/>");
+ encoder.start("map").attribute("name", dataMap.getName().trim()).end();
}
}
if (!nodeDescriptors.isEmpty()) {
- if (breakNeeded) {
- encoder.println();
- } else {
- breakNeeded = true;
- }
-
List<DataNodeDescriptor> nodes = new ArrayList<>(nodeDescriptors);
Collections.sort(nodes);
- encoder.print(nodes);
+ encoder.nested(nodes, delegate);
}
- encoder.indent(-1);
- encoder.println("</domain>");
+ delegate.visitDataChannelDescriptor(this);
+ encoder.end();
}
public <T> T acceptVisitor(ConfigurationNodeVisitor<T> visitor) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
index 7192d0d..6ece619 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/DataNodeDescriptor.java
@@ -81,57 +81,50 @@ public class DataNodeDescriptor implements ConfigurationNode, XMLSerializable,
this.dataChannelDescriptor = dataChannelDescriptor;
}
+ @Override
public int compareTo(DataNodeDescriptor o) {
String o1 = getName();
String o2 = o.getName();
if (o1 == null) {
return (o2 != null) ? -1 : 0;
- }
- else if (o2 == null) {
+ } else if (o2 == null) {
return 1;
}
- else {
- return o1.compareTo(o2);
- }
+ return o1.compareTo(o2);
}
+ @Override
public <T> T acceptVisitor(ConfigurationNodeVisitor<T> visitor) {
return visitor.visitDataNodeDescriptor(this);
}
- public void encodeAsXML(XMLEncoder encoder) {
- encoder.print("<node");
- encoder.printlnAttribute("name", name);
- encoder.indent(1);
-
- encoder.printlnAttribute("adapter", adapterType);
- encoder.printlnAttribute("factory", dataSourceFactoryType);
+ @Override
+ public void encodeAsXML(XMLEncoder encoder, ConfigurationNodeVisitor delegate) {
+ encoder.start("node")
+ .attribute("name", name, false)
+ .attribute("adapter", adapterType, true)
+ .attribute("factory", dataSourceFactoryType, true);
if (!XMLPoolingDataSourceFactory.class.getName().equals(dataSourceFactoryType)) {
- encoder.printlnAttribute("parameters", parameters);
+ encoder.attribute("parameters", parameters);
}
- encoder.printlnAttribute("schema-update-strategy", schemaUpdateStrategyType);
- encoder.println(">");
+ encoder.attribute("schema-update-strategy", schemaUpdateStrategyType, true);
if (!dataMapNames.isEmpty()) {
-
List<String> names = new ArrayList<>(dataMapNames);
Collections.sort(names);
-
for (String mapName : names) {
- encoder.print("<map-ref");
- encoder.printAttribute("name", mapName);
- encoder.println("/>");
+ encoder.start("map-ref").attribute("name", mapName).end();
}
}
if (dataSourceDescriptor != null && XMLPoolingDataSourceFactory.class.getName().equals(dataSourceFactoryType)) {
- dataSourceDescriptor.encodeAsXML(encoder);
+ dataSourceDescriptor.encodeAsXML(encoder, delegate);
}
- encoder.indent(-1);
- encoder.println("</node>");
+ delegate.visitDataNodeDescriptor(this);
+ encoder.end();
}
public String getName() {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/EmptyConfigurationNodeVisitor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/EmptyConfigurationNodeVisitor.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/EmptyConfigurationNodeVisitor.java
new file mode 100644
index 0000000..84289d2
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/EmptyConfigurationNodeVisitor.java
@@ -0,0 +1,108 @@
+/*****************************************************************
+ * 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;
+
+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 EmptyConfigurationNodeVisitor implements ConfigurationNodeVisitor<Void> {
+ @Override
+ public Void visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+ return null;
+ }
+
+ @Override
+ public Void visitDataNodeDescriptor(DataNodeDescriptor nodeDescriptor) {
+ return null;
+ }
+
+ @Override
+ public Void visitDataMap(DataMap dataMap) {
+ return null;
+ }
+
+ @Override
+ public Void visitObjEntity(ObjEntity entity) {
+ return null;
+ }
+
+ @Override
+ public Void visitDbEntity(DbEntity entity) {
+ return null;
+ }
+
+ @Override
+ public Void visitEmbeddable(Embeddable embeddable) {
+ return null;
+ }
+
+ @Override
+ public Void visitEmbeddableAttribute(EmbeddableAttribute attribute) {
+ return null;
+ }
+
+ @Override
+ public Void visitObjAttribute(ObjAttribute attribute) {
+ return null;
+ }
+
+ @Override
+ public Void visitDbAttribute(DbAttribute attribute) {
+ return null;
+ }
+
+ @Override
+ public Void visitObjRelationship(ObjRelationship relationship) {
+ return null;
+ }
+
+ @Override
+ public Void visitDbRelationship(DbRelationship relationship) {
+ return null;
+ }
+
+ @Override
+ public Void visitProcedure(Procedure procedure) {
+ return null;
+ }
+
+ @Override
+ public Void visitProcedureParameter(ProcedureParameter parameter) {
+ return null;
+ }
+
+ @Override
+ public Void visitQuery(QueryDescriptor query) {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/SAXNestedTagHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/SAXNestedTagHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/SAXNestedTagHandler.java
deleted file mode 100644
index 3891e83..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/SAXNestedTagHandler.java
+++ /dev/null
@@ -1,131 +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.configuration;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * A superclass of nested tag handlers for parsing of XML documents with SAX.
- *
- * @since 3.1
- */
-public class SAXNestedTagHandler extends DefaultHandler {
-
- private final static Locator NOOP_LOCATOR = new Locator() {
-
- public int getColumnNumber() {
- return -1;
- }
-
- public int getLineNumber() {
- return -1;
- }
-
- public String getPublicId() {
- return "<unknown>";
- }
-
- public String getSystemId() {
- return "<unknown>";
- }
- };
-
- protected XMLReader parser;
- protected ContentHandler parentHandler;
- protected Locator locator;
-
- public SAXNestedTagHandler(XMLReader parser, SAXNestedTagHandler parentHandler) {
- this.parentHandler = parentHandler;
- this.parser = parser;
-
- if (parentHandler != null) {
- locator = parentHandler.locator;
- }
-
- if (locator == null) {
- locator = NOOP_LOCATOR;
- }
- }
-
- protected String unexpectedTagMessage(String tagFound, String... tagsExpected) {
-
- List<String> expected = tagsExpected != null
- ? Arrays.asList(tagsExpected)
- : Collections.<String> emptyList();
-
- return String
- .format(
- "tag <%s> is unexpected at [%d,%d]. The following tags are allowed here: %s",
- tagFound,
- locator.getColumnNumber(),
- locator.getLineNumber(),
- expected);
- }
-
- protected ContentHandler createChildTagHandler(
- String namespaceURI,
- String localName,
- String qName,
- Attributes attributes) {
-
- // loose handling of unrecognized tags - just ignore them
- return new SAXNestedTagHandler(parser, this);
- }
-
- protected void stop() {
- // pop self from the handler stack
- parser.setContentHandler(parentHandler);
- }
-
- @Override
- public final void startElement(
- String namespaceURI,
- String localName,
- String qName,
- Attributes attributes) throws SAXException {
-
- // push child handler to the stack...
- ContentHandler childHandler = createChildTagHandler(
- namespaceURI,
- localName,
- qName,
- attributes);
- parser.setContentHandler(childHandler);
- }
-
- @Override
- public void endElement(String namespaceURI, String localName, String qName)
- throws SAXException {
- stop();
- }
-
- @Override
- public void setDocumentLocator(Locator locator) {
- this.locator = locator;
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataChannelDescriptorLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataChannelDescriptorLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataChannelDescriptorLoader.java
deleted file mode 100644
index ad9341a..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataChannelDescriptorLoader.java
+++ /dev/null
@@ -1,389 +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.configuration;
-
-import org.apache.cayenne.ConfigurationException;
-import org.apache.cayenne.conn.DataSourceInfo;
-import org.apache.cayenne.di.AdhocObjectFactory;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.resource.Resource;
-import org.apache.cayenne.util.Util;
-import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.XMLReader;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * @since 3.1
- */
-public class XMLDataChannelDescriptorLoader implements DataChannelDescriptorLoader {
-
- private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
-
- static final String DOMAIN_TAG = "domain";
- static final String MAP_TAG = "map";
- static final String NODE_TAG = "node";
- static final String PROPERTY_TAG = "property";
- static final String MAP_REF_TAG = "map-ref";
- static final String DATA_SOURCE_TAG = "data-source";
-
- /**
- * @deprecated the caller should use password resolving strategy instead of
- * resolving the password on the spot. For one thing this can be
- * used in the Modeler and no password may be available.
- */
- @Deprecated
- private static String passwordFromURL(URL url) {
- InputStream inputStream = null;
- String password = null;
-
- try {
- inputStream = url.openStream();
- password = passwordFromInputStream(inputStream);
- } catch (IOException exception) {
- // Log the error while trying to open the stream. A null
- // password will be returned as a result.
- logger.warn(exception.getMessage(), exception);
- }
-
- return password;
- }
-
- /**
- * @deprecated the caller should use password resolving strategy instead of
- * resolving the password on the spot. For one thing this can be
- * used in the Modeler and no password may be available.
- */
- @Deprecated
- private static String passwordFromInputStream(InputStream inputStream) {
- String password = null;
-
- try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));) {
-
- password = bufferedReader.readLine();
- } catch (IOException exception) {
- logger.warn(exception.getMessage(), exception);
- } finally {
-
- try {
- inputStream.close();
- } catch (IOException exception) {
- }
- }
-
- return password;
- }
-
- @Inject
- protected DataMapLoader dataMapLoader;
-
- @Inject
- protected ConfigurationNameMapper nameMapper;
-
- @Inject
- protected AdhocObjectFactory objectFactory;
-
- @Override
- public ConfigurationTree<DataChannelDescriptor> load(Resource configurationResource) throws ConfigurationException {
-
- if (configurationResource == null) {
- throw new NullPointerException("Null configurationResource");
- }
-
- URL configurationURL = configurationResource.getURL();
-
- logger.info("Loading XML configuration resource from " + configurationURL);
-
- DataChannelDescriptor descriptor = new DataChannelDescriptor();
- descriptor.setConfigurationSource(configurationResource);
- descriptor.setName(nameMapper.configurationNodeName(DataChannelDescriptor.class, configurationResource));
-
- DataChannelHandler rootHandler;
-
- InputStream in = null;
-
- try {
- in = configurationURL.openStream();
- XMLReader parser = Util.createXmlReader();
-
- rootHandler = new DataChannelHandler(descriptor, parser);
- parser.setContentHandler(rootHandler);
- parser.setErrorHandler(rootHandler);
- parser.parse(new InputSource(in));
- } catch (Exception e) {
- throw new ConfigurationException("Error loading configuration from %s", e, configurationURL);
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException ioex) {
- logger.info("failure closing input stream for " + configurationURL + ", ignoring", ioex);
- }
- }
-
- // TODO: andrus 03/10/2010 - actually provide load failures here...
- return new ConfigurationTree<DataChannelDescriptor>(descriptor, null);
- }
-
- final class DataChannelHandler extends SAXNestedTagHandler {
-
- private DataChannelDescriptor descriptor;
-
- DataChannelHandler(DataChannelDescriptor dataChannelDescriptor, XMLReader parser) {
- super(parser, null);
- this.descriptor = dataChannelDescriptor;
- }
-
- @Override
- protected ContentHandler createChildTagHandler(String namespaceURI, String localName, String name,
- Attributes attributes) {
-
- if (localName.equals(DOMAIN_TAG)) {
- return new DataChannelChildrenHandler(parser, this);
- }
-
- logger.info(unexpectedTagMessage(localName, DOMAIN_TAG));
- return super.createChildTagHandler(namespaceURI, localName, name, attributes);
- }
- }
-
- final class DataChannelChildrenHandler extends SAXNestedTagHandler {
-
- private DataChannelDescriptor descriptor;
-
- DataChannelChildrenHandler(XMLReader parser, DataChannelHandler parentHandler) {
- super(parser, parentHandler);
- this.descriptor = parentHandler.descriptor;
- }
-
- @Override
- protected ContentHandler createChildTagHandler(String namespaceURI, String localName, String name,
- Attributes attributes) {
-
- if (localName.equals(PROPERTY_TAG)) {
-
- String key = attributes.getValue("", "name");
- String value = attributes.getValue("", "value");
- if (key != null && value != null) {
- descriptor.getProperties().put(key, value);
- }
- } else if (localName.equals(MAP_TAG)) {
-
- String dataMapName = attributes.getValue("", "name");
- Resource baseResource = descriptor.getConfigurationSource();
-
- String dataMapLocation = nameMapper.configurationLocation(DataMap.class, dataMapName);
-
- Resource dataMapResource = baseResource.getRelativeResource(dataMapLocation);
-
- logger.info("Loading XML DataMap resource from " + dataMapResource.getURL());
-
- DataMap dataMap = dataMapLoader.load(dataMapResource);
- dataMap.setName(dataMapName);
- dataMap.setLocation(dataMapLocation);
- dataMap.setConfigurationSource(dataMapResource);
- dataMap.setDataChannelDescriptor(descriptor);
-
- descriptor.getDataMaps().add(dataMap);
- } else if (localName.equals(NODE_TAG)) {
-
- String nodeName = attributes.getValue("", "name");
- if (nodeName == null) {
- throw new ConfigurationException("Error: <node> without 'name'.");
- }
-
- DataNodeDescriptor nodeDescriptor = new DataNodeDescriptor();
- nodeDescriptor.setConfigurationSource(descriptor.getConfigurationSource());
- descriptor.getNodeDescriptors().add(nodeDescriptor);
-
- nodeDescriptor.setName(nodeName);
- nodeDescriptor.setAdapterType(attributes.getValue("", "adapter"));
-
- String parameters = attributes.getValue("", "parameters");
- nodeDescriptor.setParameters(parameters);
-
- String dataSourceFactory = attributes.getValue("", "factory");
- nodeDescriptor.setDataSourceFactoryType(dataSourceFactory);
- nodeDescriptor.setSchemaUpdateStrategyType(attributes.getValue("", "schema-update-strategy"));
- nodeDescriptor.setDataChannelDescriptor(descriptor);
-
- return new DataNodeChildrenHandler(parser, this, nodeDescriptor);
- }
-
- return super.createChildTagHandler(namespaceURI, localName, name, attributes);
- }
- }
-
- final class DataNodeChildrenHandler extends SAXNestedTagHandler {
-
- private DataNodeDescriptor nodeDescriptor;
-
- DataNodeChildrenHandler(XMLReader parser, SAXNestedTagHandler parentHandler, DataNodeDescriptor nodeDescriptor) {
- super(parser, parentHandler);
- this.nodeDescriptor = nodeDescriptor;
- }
-
- @Override
- protected ContentHandler createChildTagHandler(String namespaceURI, String localName, String name,
- Attributes attributes) {
-
- if (localName.equals(MAP_REF_TAG)) {
-
- String mapName = attributes.getValue("", "name");
- nodeDescriptor.getDataMapNames().add(mapName);
- } else if (localName.equals(DATA_SOURCE_TAG)) {
-
- DataSourceInfo dataSourceDescriptor = new DataSourceInfo();
- nodeDescriptor.setDataSourceDescriptor(dataSourceDescriptor);
- return new DataSourceChildrenHandler(parser, this, dataSourceDescriptor);
- }
-
- return super.createChildTagHandler(namespaceURI, localName, name, attributes);
- }
- }
-
- class DataSourceChildrenHandler extends SAXNestedTagHandler {
-
- private DataSourceInfo dataSourceDescriptor;
-
- DataSourceChildrenHandler(XMLReader parser, DataNodeChildrenHandler parentHandler,
- DataSourceInfo dataSourceDescriptor) {
- super(parser, parentHandler);
- this.dataSourceDescriptor = dataSourceDescriptor;
- }
-
- @Override
- protected ContentHandler createChildTagHandler(String namespaceURI, String localName, String name,
- Attributes attributes) {
-
- if (localName.equals("driver")) {
- String className = attributes.getValue("", "value");
- dataSourceDescriptor.setJdbcDriver(className);
- } else if (localName.equals("login")) {
-
- logger.info("loading user name and password.");
-
- String encoderClass = attributes.getValue("encoderClass");
-
- String encoderKey = attributes.getValue("encoderKey");
- if (encoderKey == null) {
- encoderKey = attributes.getValue("encoderSalt");
- }
-
- String password = attributes.getValue("password");
- String passwordLocation = attributes.getValue("passwordLocation");
- String passwordSource = attributes.getValue("passwordSource");
- if (passwordSource == null) {
- passwordSource = DataSourceInfo.PASSWORD_LOCATION_MODEL;
- }
-
- String username = attributes.getValue("userName");
-
- dataSourceDescriptor.setPasswordEncoderClass(encoderClass);
- dataSourceDescriptor.setPasswordEncoderKey(encoderKey);
- dataSourceDescriptor.setPasswordLocation(passwordLocation);
- dataSourceDescriptor.setPasswordSource(passwordSource);
- dataSourceDescriptor.setUserName(username);
-
- // Replace {} in passwordSource with encoderSalt -- useful for
- // EXECUTABLE
- // & URL options
- if (encoderKey != null) {
- passwordSource = passwordSource.replaceAll("\\{\\}", encoderKey);
- }
-
- String encoderType = dataSourceDescriptor.getPasswordEncoderClass();
- PasswordEncoding passwordEncoder = null;
- if (encoderType != null) {
- passwordEncoder = objectFactory.newInstance(PasswordEncoding.class, encoderType);
- }
-
- if (passwordLocation != null) {
- if (passwordLocation.equals(DataSourceInfo.PASSWORD_LOCATION_CLASSPATH)) {
-
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- URL url = classLoader.getResource(username);
- if (url != null) {
- password = passwordFromURL(url);
- } else {
- logger.error("Could not find resource in CLASSPATH: " + passwordSource);
- }
- } else if (passwordLocation.equals(DataSourceInfo.PASSWORD_LOCATION_URL)) {
- try {
- password = passwordFromURL(new URL(passwordSource));
- } catch (MalformedURLException exception) {
- logger.warn(exception.getMessage(), exception);
- }
- } else if (passwordLocation.equals(DataSourceInfo.PASSWORD_LOCATION_EXECUTABLE)) {
- if (passwordSource != null) {
- try {
- Process process = Runtime.getRuntime().exec(passwordSource);
- password = passwordFromInputStream(process.getInputStream());
- process.waitFor();
- } catch (IOException exception) {
- logger.warn(exception.getMessage(), exception);
- } catch (InterruptedException exception) {
- logger.warn(exception.getMessage(), exception);
- }
- }
- }
- }
-
- if (password != null && passwordEncoder != null) {
- dataSourceDescriptor.setPassword(passwordEncoder.decodePassword(password, encoderKey));
- }
- } else if (localName.equals("url")) {
- dataSourceDescriptor.setDataSourceUrl(attributes.getValue("value"));
- } else if (localName.equals("connectionPool")) {
- String min = attributes.getValue("min");
- if (min != null) {
- try {
- dataSourceDescriptor.setMinConnections(Integer.parseInt(min));
- } catch (NumberFormatException nfex) {
- logger.info("Non-numeric 'min' attribute", nfex);
- throw new ConfigurationException("Non-numeric 'min' attribute '%s'", nfex, min);
- }
- }
-
- String max = attributes.getValue("max");
- if (max != null) {
- try {
- dataSourceDescriptor.setMaxConnections(Integer.parseInt(max));
- } catch (NumberFormatException nfex) {
- logger.info("Non-numeric 'max' attribute", nfex);
- throw new ConfigurationException("Non-numeric 'max' attribute '%s'", nfex, max);
- }
- }
- }
-
- return super.createChildTagHandler(namespaceURI, localName, name, attributes);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataMapLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataMapLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataMapLoader.java
deleted file mode 100644
index d5cce91..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/XMLDataMapLoader.java
+++ /dev/null
@@ -1,57 +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.configuration;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.MapLoader;
-import org.apache.cayenne.resource.Resource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-
-import java.io.InputStream;
-import java.net.URL;
-
-/**
- * @since 3.1
- */
-public class XMLDataMapLoader implements DataMapLoader {
-
- private static Logger logger = LoggerFactory.getLogger(XMLDataMapLoader.class);
-
- public DataMap load(Resource configurationResource) throws CayenneRuntimeException {
-
- // TODO: andrus 11.27.2009 - deprecate MapLoader and implement a loader
- // here. MapLoader is in the wrong place, exposes ContentHandler methods and
- // implements if/else contextless matching of tags... should use something like
- // SAXNestedTagHandler instead.
- MapLoader mapLoader = new MapLoader();
- URL url = configurationResource.getURL();
-
- try (InputStream in = url.openStream()) {
- return mapLoader.loadDataMap(new InputSource(in));
- } catch (Exception e) {
- throw new CayenneRuntimeException(
- "Error loading configuration from %s",
- e,
- url);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/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 962bba9..c86371d 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
@@ -71,8 +71,12 @@ import org.apache.cayenne.configuration.DefaultRuntimeProperties;
import org.apache.cayenne.configuration.ObjectContextFactory;
import org.apache.cayenne.configuration.ObjectStoreFactory;
import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.configuration.XMLDataChannelDescriptorLoader;
-import org.apache.cayenne.configuration.XMLDataMapLoader;
+import org.apache.cayenne.configuration.xml.DataChannelMetaData;
+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.XMLDataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.xml.XMLDataMapLoader;
import org.apache.cayenne.dba.db2.DB2Sniffer;
import org.apache.cayenne.dba.derby.DerbySniffer;
import org.apache.cayenne.dba.firebird.FirebirdSniffer;
@@ -403,5 +407,8 @@ public class ServerModule implements Module {
binder.bind(RowReaderFactory.class).to(DefaultRowReaderFactory.class);
binder.bind(SQLTemplateProcessor.class).to(VelocitySQLTemplateProcessor.class);
+
+ binder.bind(HandlerFactory.class).to(DefaultHandlerFactory.class);
+ binder.bind(DataChannelMetaData.class).to(NoopDataChannelMetaData.class);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/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
new file mode 100644
index 0000000..9dc65af
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelChildrenHandler.java
@@ -0,0 +1,133 @@
+/*****************************************************************
+ * 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.ConfigurationException;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+
+/**
+ * @since 4.1
+ */
+final class DataChannelChildrenHandler extends SAXNestedTagHandler {
+
+ private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
+
+ static final String OLD_MAP_TAG = "map";
+ static final String NODE_TAG = "node";
+ static final String PROPERTY_TAG = "property";
+ static final String DATA_MAP_TAG = "data-map";
+
+
+ private XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader;
+ private DataChannelDescriptor descriptor;
+
+ private DataNodeDescriptor nodeDescriptor;
+
+ DataChannelChildrenHandler(XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader, DataChannelHandler parentHandler) {
+ super(parentHandler);
+ this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
+ this.descriptor = parentHandler.descriptor;
+ }
+
+ @Override
+ protected boolean processElement(String namespaceURI, String localName, Attributes attributes) {
+ switch (localName) {
+ case PROPERTY_TAG:
+ addProperty(attributes);
+ return true;
+
+ case OLD_MAP_TAG:
+ addMap(attributes);
+ return true;
+
+ case NODE_TAG:
+ addNode(attributes);
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected ContentHandler createChildTagHandler(String namespaceURI, String localName,
+ String name, Attributes attributes) {
+ if (NODE_TAG.equals(localName)) {
+ nodeDescriptor = new DataNodeDescriptor();
+ return new DataNodeChildrenHandler(xmlDataChannelDescriptorLoader, this, nodeDescriptor);
+ }
+
+ if (DATA_MAP_TAG.equals(localName)) {
+ return new DataMapHandler(loaderContext);
+ }
+
+ return super.createChildTagHandler(namespaceURI, localName, name, attributes);
+ }
+
+ private void addProperty(Attributes attributes) {
+ String key = attributes.getValue("name");
+ String value = attributes.getValue("value");
+ if (key != null && value != null) {
+ descriptor.getProperties().put(key, value);
+ }
+ }
+
+ private void addMap(Attributes attributes) {
+ String dataMapName = attributes.getValue("name");
+ Resource baseResource = descriptor.getConfigurationSource();
+
+ String dataMapLocation = xmlDataChannelDescriptorLoader.nameMapper.configurationLocation(DataMap.class, dataMapName);
+
+ Resource dataMapResource = baseResource.getRelativeResource(dataMapLocation);
+
+ logger.info("Loading XML DataMap resource from " + dataMapResource.getURL());
+
+ DataMap dataMap = xmlDataChannelDescriptorLoader.dataMapLoader.load(dataMapResource);
+ dataMap.setName(dataMapName);
+ dataMap.setLocation(dataMapLocation);
+ dataMap.setConfigurationSource(dataMapResource);
+ dataMap.setDataChannelDescriptor(descriptor);
+
+ descriptor.getDataMaps().add(dataMap);
+ }
+
+ private void addNode(Attributes attributes) {
+ String nodeName = attributes.getValue("name");
+ if (nodeName == null) {
+ throw new ConfigurationException("Error: <node> without 'name'.");
+ }
+
+ nodeDescriptor.setConfigurationSource(descriptor.getConfigurationSource());
+ nodeDescriptor.setName(nodeName);
+ nodeDescriptor.setAdapterType(attributes.getValue("adapter"));
+ nodeDescriptor.setParameters(attributes.getValue("parameters"));
+ nodeDescriptor.setDataSourceFactoryType(attributes.getValue("factory"));
+ nodeDescriptor.setSchemaUpdateStrategyType(attributes.getValue("schema-update-strategy"));
+ nodeDescriptor.setDataChannelDescriptor(descriptor);
+
+ descriptor.getNodeDescriptors().add(nodeDescriptor);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/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
new file mode 100644
index 0000000..e5e4c71
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelHandler.java
@@ -0,0 +1,78 @@
+/*****************************************************************
+ * 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.CayenneRuntimeException;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.util.LocalizedStringsHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * @since 4.1
+ */
+final class DataChannelHandler extends SAXNestedTagHandler {
+
+ private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
+
+ static final String DOMAIN_TAG = "domain";
+
+ private XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader;
+ DataChannelDescriptor descriptor;
+
+ DataChannelHandler(XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader, DataChannelDescriptor dataChannelDescriptor, LoaderContext loaderContext) {
+ super(loaderContext);
+ this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
+ this.descriptor = dataChannelDescriptor;
+ }
+
+ @Override
+ protected boolean processElement(String namespaceURI, String localName, Attributes attributes) throws SAXException {
+ switch (localName) {
+ case DOMAIN_TAG:
+ validateVersion(attributes);
+ return true;
+ }
+ return super.processElement(namespaceURI, localName, attributes);
+ }
+
+ protected void validateVersion(Attributes attributes) {
+ String version = attributes.getValue("project-version");
+ if(!XMLDataChannelDescriptorLoader.CURRENT_PROJECT_VERSION.equals(version)) {
+ throw new CayenneRuntimeException("Unsupported project version: %s, please upgrade project using Modeler v%s",
+ version, LocalizedStringsHandler.getString("cayenne.version"));
+ }
+ }
+
+ @Override
+ protected ContentHandler createChildTagHandler(String namespaceURI, String localName,
+ String name, Attributes attributes) {
+
+ if (localName.equals(DOMAIN_TAG)) {
+ return new DataChannelChildrenHandler(xmlDataChannelDescriptorLoader, this);
+ }
+
+ logger.info(unexpectedTagMessage(localName, DOMAIN_TAG));
+ return super.createChildTagHandler(namespaceURI, localName, name, attributes);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java
new file mode 100644
index 0000000..3e0cd20
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.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.configuration.xml;
+
+import org.apache.cayenne.configuration.ConfigurationNode;
+
+/**
+ * <p>
+ * Storage for all kind of meta data that is not required for runtime.
+ * </p>
+ * <p>
+ * Currently used by Modeler and cli tools (e.g. Maven, Ant and Gradle) to store project extra data.
+ * </p>
+ *
+ * <p>
+ * Usage: <pre>
+ * // attach custom information to data map
+ * metaData.add(dataMap, myObject);
+ *
+ * // read data
+ * MyObject obj = metaData.get(dataMap, MyObject.class);
+ * </pre>
+ * </p>
+ *
+ * @since 4.1
+ */
+public interface DataChannelMetaData {
+
+ /**
+ * Store data for object.
+ *
+ * @param key object for which we want to store data
+ * @param value data to store
+ */
+ void add(ConfigurationNode key, Object value);
+
+ /**
+ *
+ * Get meta data for object
+ *
+ * @param key object for wich we want meta data
+ * @param type meta data type class
+ * @param <T> meta data type
+ * @return value or {@code null} if no data available
+ */
+ <T> T get(ConfigurationNode key, Class<T> type);
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapHandler.java
new file mode 100644
index 0000000..ea508f5
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapHandler.java
@@ -0,0 +1,142 @@
+/*****************************************************************
+ * 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 java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.cayenne.map.DataMap;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * @since 4.1
+ */
+public class DataMapHandler extends NamespaceAwareNestedTagHandler {
+
+ /* This constants must be in sync with dataMap.xsd schema */
+ private static final String DATA_MAP_TAG = "data-map";
+ private static final String PROPERTY_TAG = "property";
+ private static final String DB_ENTITY_TAG = "db-entity";
+ private static final String OBJ_ENTITY_TAG = "obj-entity";
+ private static final String DB_RELATIONSHIP_TAG = "db-relationship";
+ private static final String OBJ_RELATIONSHIP_TAG = "obj-relationship";
+ private static final String EMBEDDABLE_TAG = "embeddable";
+ private static final String PROCEDURE_TAG = "procedure";
+ private static final String QUERY_TAG = "query";
+
+ public static final String TRUE = "true";
+
+ private DataMap dataMap;
+
+ private Map<String, Object> mapProperties;
+
+ public DataMapHandler(NamespaceAwareNestedTagHandler parentHandler) {
+ super(parentHandler);
+ }
+
+ public DataMapHandler(LoaderContext loaderContext) {
+ super(loaderContext);
+ setTargetNamespace(DataMap.SCHEMA_XSD);
+ }
+
+ @Override
+ protected boolean processElement(String namespaceURI, String localName,
+ Attributes attributes) throws SAXException {
+ switch (localName) {
+ case PROPERTY_TAG:
+ addProperty(attributes);
+ return true;
+
+ case DATA_MAP_TAG:
+ this.dataMap = new DataMap();
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected ContentHandler createChildTagHandler(String namespaceURI, String localName,
+ String qName, Attributes attributes) {
+
+ if(namespaceURI.equals(targetNamespace)) {
+ switch (localName) {
+ case DB_ENTITY_TAG:
+ return new DbEntityHandler(this, dataMap);
+
+ case OBJ_ENTITY_TAG:
+ return new ObjEntityHandler(this, dataMap);
+
+ case DB_RELATIONSHIP_TAG:
+ return new DbRelationshipHandler(this, dataMap);
+
+ case OBJ_RELATIONSHIP_TAG:
+ return new ObjRelationshipHandler(this, dataMap);
+
+ case PROCEDURE_TAG:
+ return new ProcedureHandler(this, dataMap);
+
+ case QUERY_TAG:
+ return new QueryDescriptorHandler(this, dataMap);
+
+ case EMBEDDABLE_TAG:
+ return new EmbeddableHandler(this, dataMap);
+ }
+ }
+
+ return super.createChildTagHandler(namespaceURI, localName, qName, attributes);
+ }
+
+ @Override
+ protected void beforeScopeEnd() {
+ dataMap.initWithProperties(mapProperties);
+ loaderContext.dataMapLoaded(dataMap);
+ }
+
+ private void addProperty(Attributes attributes) throws SAXException {
+ String name = attributes.getValue("name");
+ if (null == name) {
+ throw new SAXException("MapLoader::processStartDataMapProperty(), no property name.");
+ }
+
+ String value = attributes.getValue("value");
+ if (null == value) {
+ throw new SAXException("MapLoader::processStartDataMapProperty(), no property value.");
+ }
+
+ // special meaning for <property name="name" .../>
+ if("name".equals(name)) {
+ dataMap.setName(value);
+ return;
+ }
+
+ if (mapProperties == null) {
+ mapProperties = new TreeMap<>();
+ }
+
+ mapProperties.put(name, value);
+ }
+
+ public DataMap getDataMap() {
+ return dataMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapLoaderListener.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapLoaderListener.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapLoaderListener.java
new file mode 100644
index 0000000..c9f4ccd
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataMapLoaderListener.java
@@ -0,0 +1,31 @@
+/*****************************************************************
+ * 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.map.DataMap;
+
+/**
+ * @since 4.1
+ */
+public interface DataMapLoaderListener {
+
+ void onDataMapLoaded(DataMap dataMap);
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/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
new file mode 100644
index 0000000..b98bd73
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataNodeChildrenHandler.java
@@ -0,0 +1,71 @@
+/*****************************************************************
+ * 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.DataNodeDescriptor;
+import org.apache.cayenne.conn.DataSourceInfo;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+
+/**
+ * @since 4.1
+ */
+final class DataNodeChildrenHandler extends SAXNestedTagHandler {
+
+ static final String DATA_SOURCE_TAG = "data-source";
+ static final String MAP_REF_TAG = "map-ref";
+
+ private XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader;
+ private DataNodeDescriptor nodeDescriptor;
+
+ private DataSourceInfo dataSourceDescriptor;
+
+ DataNodeChildrenHandler(XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader, SAXNestedTagHandler parentHandler, DataNodeDescriptor nodeDescriptor) {
+ super(parentHandler);
+ this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
+ this.nodeDescriptor = nodeDescriptor;
+ }
+
+ @Override
+ protected boolean processElement(String namespaceURI, String localName, Attributes attributes) {
+ switch (localName) {
+ case MAP_REF_TAG:
+ nodeDescriptor.getDataMapNames().add(attributes.getValue("name"));
+ return true;
+
+ case DATA_SOURCE_TAG:
+ nodeDescriptor.setDataSourceDescriptor(dataSourceDescriptor);
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected ContentHandler createChildTagHandler(String namespaceURI, String localName,
+ String name, Attributes attributes) {
+ if (DATA_SOURCE_TAG.equals(localName)) {
+ dataSourceDescriptor = new DataSourceInfo();
+ return new DataSourceChildrenHandler(xmlDataChannelDescriptorLoader, this, dataSourceDescriptor);
+ }
+
+ return super.createChildTagHandler(namespaceURI, localName, name, attributes);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/c58b6f40/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
new file mode 100644
index 0000000..b860b1f
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataSourceChildrenHandler.java
@@ -0,0 +1,175 @@
+/*****************************************************************
+ * 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 java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.cayenne.ConfigurationException;
+import org.apache.cayenne.configuration.PasswordEncoding;
+import org.apache.cayenne.conn.DataSourceInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+
+/**
+ * @since 4.1
+ */
+class DataSourceChildrenHandler extends SAXNestedTagHandler {
+
+ private static Logger logger = LoggerFactory.getLogger(XMLDataChannelDescriptorLoader.class);
+
+ static final String DRIVER_TAG = "driver";
+ static final String LOGIN_TAG = "login";
+ static final String URL_TAG = "url";
+ static final String CONNECTION_POOL_TAG = "connectionPool";
+
+
+ private XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader;
+ private DataSourceInfo dataSourceDescriptor;
+
+ DataSourceChildrenHandler(XMLDataChannelDescriptorLoader xmlDataChannelDescriptorLoader,
+ DataNodeChildrenHandler parentHandler,
+ DataSourceInfo dataSourceDescriptor) {
+ super(parentHandler);
+ this.xmlDataChannelDescriptorLoader = xmlDataChannelDescriptorLoader;
+ this.dataSourceDescriptor = dataSourceDescriptor;
+ }
+
+ @Override
+ protected boolean processElement(String namespaceURI, String localName, Attributes attributes) {
+ switch (localName) {
+ case DRIVER_TAG:
+ dataSourceDescriptor.setJdbcDriver(attributes.getValue("value"));
+ return true;
+
+ case LOGIN_TAG:
+ configureCredentials(attributes);
+ return true;
+
+ case URL_TAG:
+ dataSourceDescriptor.setDataSourceUrl(attributes.getValue("value"));
+ return true;
+
+ case CONNECTION_POOL_TAG:
+ configureConnectionPool(attributes);
+ return true;
+ }
+
+ return false;
+ }
+
+ void configureCredentials(Attributes attributes) {
+ logger.info("loading user name and password.");
+
+ String encoderClass = attributes.getValue("encoderClass");
+
+ String encoderKey = attributes.getValue("encoderKey");
+ if (encoderKey == null) {
+ encoderKey = attributes.getValue("encoderSalt");
+ }
+
+ String password = attributes.getValue("password");
+ String passwordLocation = attributes.getValue("passwordLocation");
+ String passwordSource = attributes.getValue("passwordSource");
+ if (passwordSource == null) {
+ passwordSource = DataSourceInfo.PASSWORD_LOCATION_MODEL;
+ }
+
+ String username = attributes.getValue("userName");
+
+ dataSourceDescriptor.setPasswordEncoderClass(encoderClass);
+ dataSourceDescriptor.setPasswordEncoderKey(encoderKey);
+ dataSourceDescriptor.setPasswordLocation(passwordLocation);
+ dataSourceDescriptor.setPasswordSource(passwordSource);
+ dataSourceDescriptor.setUserName(username);
+
+ // Replace {} in passwordSource with encoderSalt -- useful for EXECUTABLE & URL options
+ if (encoderKey != null) {
+ passwordSource = passwordSource.replaceAll("\\{\\}", encoderKey);
+ }
+
+ String encoderType = dataSourceDescriptor.getPasswordEncoderClass();
+ PasswordEncoding passwordEncoder = null;
+ if (encoderType != null) {
+ passwordEncoder = xmlDataChannelDescriptorLoader.objectFactory.newInstance(PasswordEncoding.class, encoderType);
+ }
+
+ if (passwordLocation != null) {
+ switch (passwordLocation) {
+ case DataSourceInfo.PASSWORD_LOCATION_CLASSPATH:
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ URL url = classLoader.getResource(username);
+ if (url != null) {
+ password = XMLDataChannelDescriptorLoader.passwordFromURL(url);
+ } else {
+ logger.error("Could not find resource in CLASSPATH: " + passwordSource);
+ }
+ break;
+ case DataSourceInfo.PASSWORD_LOCATION_URL:
+ try {
+ password = XMLDataChannelDescriptorLoader.passwordFromURL(new URL(passwordSource));
+ } catch (MalformedURLException exception) {
+ logger.warn(exception.getMessage(), exception);
+ }
+ break;
+ case DataSourceInfo.PASSWORD_LOCATION_EXECUTABLE:
+ if (passwordSource != null) {
+ try {
+ Process process = Runtime.getRuntime().exec(passwordSource);
+ password = XMLDataChannelDescriptorLoader.passwordFromInputStream(process.getInputStream());
+ process.waitFor();
+ } catch (IOException | InterruptedException exception) {
+ logger.warn(exception.getMessage(), exception);
+ }
+ }
+ break;
+ }
+ }
+
+ if (password != null && passwordEncoder != null) {
+ dataSourceDescriptor.setPassword(passwordEncoder.decodePassword(password, encoderKey));
+ }
+ }
+
+ void configureConnectionPool(Attributes attributes) {
+ String min = attributes.getValue("min");
+ if (min != null) {
+ try {
+ dataSourceDescriptor.setMinConnections(Integer.parseInt(min));
+ } catch (NumberFormatException nfex) {
+ logger.info("Non-numeric 'min' attribute", nfex);
+ throw new ConfigurationException("Non-numeric 'min' attribute '%s'", nfex, min);
+ }
+ }
+
+ String max = attributes.getValue("max");
+ if (max != null) {
+ try {
+ dataSourceDescriptor.setMaxConnections(Integer.parseInt(max));
+ } catch (NumberFormatException nfex) {
+ logger.info("Non-numeric 'max' attribute", nfex);
+ throw new ConfigurationException("Non-numeric 'max' attribute '%s'", nfex, max);
+ }
+ }
+ }
+}