Author: tfischer
Date: Wed Sep 3 19:26:19 2014
New Revision: 1622323
URL: http://svn.apache.org/r1622323
Log:
TORQUE-324 allow access to parent element in generator via ..
Added:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePathPointer.java
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/ControllerState.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/ApplyAction.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/TraverseAllAction.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/ModelPropertyPointer.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodeIterator.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodePointer.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePath.java
db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/SourcePathTest.java
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java
Wed Sep 3 19:26:19 2014
@@ -54,8 +54,10 @@ import org.apache.torque.generator.outle
import org.apache.torque.generator.processor.string.StringProcessor;
import org.apache.torque.generator.source.PostprocessorDefinition;
import org.apache.torque.generator.source.Source;
+import org.apache.torque.generator.source.SourceElement;
import org.apache.torque.generator.source.SourceException;
import org.apache.torque.generator.source.SourcePath;
+import org.apache.torque.generator.source.SourcePathPointer;
import org.apache.torque.generator.source.SourceProcessConfiguration;
import org.apache.torque.generator.source.SourceProvider;
import org.apache.torque.generator.source.SourceTransformerDefinition;
@@ -334,7 +336,9 @@ public class Controller
final String startElementsPath
= sourceProcessConfiguration.getStartElementsPath();
- final Iterator<?> iterator = SourcePath.iterate(
+ final Iterator<SourcePathPointer> iterator = SourcePath.iteratePointer(
+ null,
+ null,
modelRoot,
startElementsPath);
if (!iterator.hasNext())
@@ -344,7 +348,27 @@ public class Controller
}
while (iterator.hasNext())
{
- final Object model = iterator.next();
+ final SourcePathPointer pointer = iterator.next();
+ final Object model = pointer.getValue();
+ String path = pointer.getPath();
+ if (model instanceof SourceElement)
+ {
+ // remove root node from path because the root node
+ // is no part of the xpath for sourceElements
+ if (path.startsWith("/"))
+ {
+ int slashIndex = path.indexOf('/', 1);
+ if (slashIndex != -1)
+ {
+ path = path.substring(slashIndex + 1);
+ }
+ else
+ {
+ path = "/";
+ }
+ }
+ }
+ controllerState.setModel(model, path);
processModel(
model,
output,
@@ -453,7 +477,6 @@ public class Controller
+ "of output file "
+ output);
}
- controllerState.setModel(model);
log.debug("Processing new model " + model);
ExistingTargetStrategy existingTargetStrategy = null;
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/ControllerState.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/ControllerState.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/ControllerState.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/ControllerState.java
Wed Sep 3 19:26:19 2014
@@ -23,6 +23,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.lang.StringUtils;
import org.apache.torque.generator.configuration.UnitConfiguration;
import org.apache.torque.generator.configuration.controller.OutletReference;
import org.apache.torque.generator.configuration.controller.Output;
@@ -32,6 +33,7 @@ import org.apache.torque.generator.optio
import org.apache.torque.generator.outlet.Outlet;
import org.apache.torque.generator.qname.Namespace;
import org.apache.torque.generator.qname.QualifiedName;
+import org.apache.torque.generator.source.SourceElement;
import org.apache.torque.generator.source.SourceProvider;
import org.apache.torque.generator.variable.VariableStore;
@@ -67,6 +69,11 @@ public class ControllerState
private Object model;
/**
+ * The path from the model root to the current model.
+ */
+ private String pathToModel = "/";
+
+ /**
* The generation unit which is currently processed.
*/
private UnitConfiguration unitConfiguration;
@@ -213,11 +220,68 @@ public class ControllerState
* Sets the current source model object.
*
* @param sourceElement the new current source model object, or null
- * to remove the current source mdoel object.
+ * to remove the current source model object.
+ * @param newPathToModel the path from root
+ * to the new model, or null to leave the path unchanged.
*/
- public void setModel(final Object model)
+ public void setModel(final Object model, String newPathToModel)
{
this.model = model;
+ if (newPathToModel != null)
+ {
+ if (model instanceof SourceElement)
+ {
+ // In source element, the root node precedes the path.
+ // For a correct relative path, the root node
+ // of the relative path must be removed.
+ if (newPathToModel.startsWith("/"))
+ {
+ int slashIndex = newPathToModel.indexOf('/', 1);
+ if (slashIndex != -1)
+ {
+ newPathToModel = newPathToModel.substring(slashIndex +
1);
+ }
+ else
+ {
+ newPathToModel = "/";
+ }
+ }
+ }
+
+ if (StringUtils.isEmpty(newPathToModel))
+ {
+ this.pathToModel = "/";
+ }
+ else
+ {
+ this.pathToModel = newPathToModel;
+ }
+ }
+ }
+
+ /**
+ * Returns the path from the model root to the current model.
+ *
+ * @return the path from the model root to the current model, not null.
+ */
+ public String getPathToModel()
+ {
+ return pathToModel;
+ }
+
+ /**
+ * Sets the path from the model root to the current model.
+ *
+ * @param pathToModel the path from the model root to the current model,
+ * not null.
+ */
+ public void setPathToModel(final String pathToModel)
+ {
+ if (pathToModel == null)
+ {
+ throw new NullPointerException("pathToModel must not be null");
+ }
+ this.pathToModel = pathToModel;
}
/**
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/ApplyAction.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/ApplyAction.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/ApplyAction.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/ApplyAction.java
Wed Sep 3 19:26:19 2014
@@ -29,6 +29,7 @@ import org.apache.torque.generator.outle
import org.apache.torque.generator.qname.Namespace;
import org.apache.torque.generator.qname.QualifiedName;
import org.apache.torque.generator.source.SourcePath;
+import org.apache.torque.generator.source.SourcePathPointer;
/**
* Applies an outlet to the matching element.
@@ -61,7 +62,7 @@ public class ApplyAction implements Merg
* matches the given path, true if an error should be thrown in
* such a case. null means true.
*/
- public ApplyAction(String path, String outletName, Boolean acceptNotSet)
+ public ApplyAction(final String path, final String outletName, final
Boolean acceptNotSet)
{
if (path == null)
{
@@ -89,7 +90,7 @@ public class ApplyAction implements Merg
* The output of the outlet is appended to the output.
* ${...} Tokens are replaced within outletName and path.
*/
- public OutletResult execute(ControllerState controllerState)
+ public OutletResult execute(final ControllerState controllerState)
throws GeneratorException
{
TokenReplacer tokenReplacer = new TokenReplacer(controllerState);
@@ -108,10 +109,15 @@ public class ApplyAction implements Merg
}
Object model = controllerState.getModel();
+ String pathToModel = controllerState.getPathToModel();
String detokenizedPath = tokenReplacer.process(path);
- Iterator<?> selectedObjectsIt
- = SourcePath.iterate(model, detokenizedPath);
+ Iterator<SourcePathPointer> selectedObjectsIt
+ = SourcePath.iteratePointer(
+ controllerState.getModelRoot(),
+ pathToModel,
+ model,
+ detokenizedPath);
if (!selectedObjectsIt.hasNext())
{
if (!acceptNotSet)
@@ -124,7 +130,8 @@ public class ApplyAction implements Merg
}
return new OutletResult("");
}
- Object selectedObject = selectedObjectsIt.next();
+ SourcePathPointer pointer = selectedObjectsIt.next();
+ Object selectedObject = pointer.getValue();
if (selectedObjectsIt.hasNext())
{
throw new GeneratorException(
@@ -133,11 +140,13 @@ public class ApplyAction implements Merg
+ " contains more than one element");
}
- controllerState.setModel(selectedObject);
+ String oldPathToModel = controllerState.getPathToModel();
+ controllerState.setModel(selectedObject, pointer.getPath());
outlet.beforeExecute(controllerState);
OutletResult result = outlet.execute(controllerState);
outlet.afterExecute(controllerState);
- controllerState.setModel(model);
+ controllerState.setModel(model, null);
+ controllerState.setPathToModel(oldPathToModel);
return result;
}
@@ -167,7 +176,7 @@ public class ApplyAction implements Merg
}
@Override
- public boolean equals(Object obj)
+ public boolean equals(final Object obj)
{
if (this == obj)
{
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/TraverseAllAction.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/TraverseAllAction.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/TraverseAllAction.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/action/TraverseAllAction.java
Wed Sep 3 19:26:19 2014
@@ -32,6 +32,7 @@ import org.apache.torque.generator.outle
import org.apache.torque.generator.qname.Namespace;
import org.apache.torque.generator.qname.QualifiedName;
import org.apache.torque.generator.source.SourcePath;
+import org.apache.torque.generator.source.SourcePathPointer;
/**
* Traverses all matching elements, and applies a outlet to each matching
@@ -124,10 +125,12 @@ public class TraverseAllAction implement
= tokenReplacer.process(elementsToTraverseName);
final Object currentModel = controllerState.getModel();
- final Iterator<?> toTraverseIt
- = SourcePath.iterate(
- currentModel,
- detokenizedElementToTraverseName);
+ final Iterator<SourcePathPointer> toTraverseIt
+ = SourcePath.iteratePointer(
+ controllerState.getModelRoot(),
+ controllerState.getPathToModel(),
+ currentModel,
+ detokenizedElementToTraverseName);
if (!acceptEmpty && toTraverseIt.hasNext())
{
throw new GeneratorException(
@@ -136,17 +139,23 @@ public class TraverseAllAction implement
+ " does not exist and acceptEmpty was set to false");
}
- final List<OutletResult> resultList
- = new ArrayList<OutletResult>();
+ final List<OutletResult> resultList = new ArrayList<OutletResult>();
+ String oldPathToModel = controllerState.getPathToModel();
while (toTraverseIt.hasNext())
{
- final Object model = toTraverseIt.next();
- controllerState.setModel(model);
+ final SourcePathPointer pointer = toTraverseIt.next();
+ final Object model = pointer.getValue();
+ String path = pointer.getPath();
+ controllerState.setModel(
+ model,
+ path);
outlet.beforeExecute(controllerState);
resultList.add(outlet.execute(controllerState));
outlet.afterExecute(controllerState);
+ controllerState.setPathToModel(oldPathToModel);
}
- controllerState.setModel(currentModel);
+ controllerState.setModel(currentModel, null);
+
if (resultList.isEmpty())
{
return new OutletResult("");
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/ModelPropertyPointer.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/ModelPropertyPointer.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/ModelPropertyPointer.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/ModelPropertyPointer.java
Wed Sep 3 19:26:19 2014
@@ -108,7 +108,7 @@ public class ModelPropertyPointer extend
{
return 0;
}
- return getPropertyDescriptors().length;
+ return getPropertyNames().length;
}
/**
@@ -255,7 +255,7 @@ public class ModelPropertyPointer extend
@Override
protected boolean isActualProperty()
{
- return getPropertyDescriptor() != null;
+ return getPropertyDescriptor() != null || getField() != null;
}
@Override
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodeIterator.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodeIterator.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodeIterator.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodeIterator.java
Wed Sep 3 19:26:19 2014
@@ -81,7 +81,13 @@ public class SourceElementNodeIterator i
{
setPosition(1);
}
- return child == null ? null : new SourceElementNodePointer(parent,
child);
+ if (child != null)
+ {
+ NodePointer result = new SourceElementNodePointer(parent, child);
+ result.setIndex(position - 1);
+ return result;
+ }
+ return null;
}
public int getPosition()
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodePointer.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodePointer.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodePointer.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourceElementNodePointer.java
Wed Sep 3 19:26:19 2014
@@ -70,13 +70,22 @@ public class SourceElementNodePointer ex
@Override
public boolean isCollection()
{
- return false;
+ return true;
}
@Override
public int getLength()
{
- return 1;
+ // get parent in path, which is not necessarily
+ // the primary parent of the source element
+ NodePointer parentPointer = getParent();
+ if (parentPointer == null)
+ {
+ return 1;
+ }
+ SourceElement parentInPath
+ = ((SourceElement) getParent().getBaseValue());
+ return parentInPath.getChildren(sourceElement.getName()).size();
}
@Override
@@ -184,7 +193,7 @@ public class SourceElementNodePointer ex
{
if (((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE)
{
- return true;
+ return true;
}
return false;
}
Modified:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePath.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePath.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePath.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePath.java
Wed Sep 3 19:26:19 2014
@@ -20,7 +20,6 @@ package org.apache.torque.generator.sour
*/
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -29,6 +28,8 @@ import java.util.Set;
import java.util.StringTokenizer;
import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.JXPathException;
+import org.apache.commons.jxpath.Pointer;
import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
import org.apache.torque.generator.GeneratorException;
@@ -302,7 +303,14 @@ public final class SourcePath
/**
* Gets the elements which can be reached from the start element by a given
* path.
+ * If the model root is null, only objects which are children of base
+ * can be retrieved.
*
+ * @param root the model root, or null if no model root exists
+ * (in the latter case, no elements only reachable via base's parent
+ * can be accessed)
+ * @param pathToBase the path from root to base, must be not null
+ * if root is not null, is disregarded if root is null.
* @param base the base object, not null.
* @param path the path to use, or null (which refers base).
*
@@ -310,7 +318,11 @@ public final class SourcePath
*
* @see <a href="http://www.w3.org/TR/xpath#axes">xpath axes</a>
*/
- public static Iterator<?> iterate(final Object base, final String path)
+ public static Iterator<SourcePathPointer> iteratePointer(
+ final Object root,
+ String pathToBase,
+ final Object base,
+ String path)
{
if (base == null)
{
@@ -318,14 +330,70 @@ public final class SourcePath
}
if (path == null)
{
- return Arrays.asList(new Object[] {base}).iterator();
+ path = ".";
}
- final JXPathContext context = JXPathContext.newContext(base);
+ final JXPathContext context;
+ if (root != null)
+ {
+ final JXPathContext rootContext = JXPathContext.newContext(root);
+ if (root instanceof SourceElement)
+ {
+ // In source element, the root node precedes the path.
+ // For a correct relative path, the root node
+ // of the relative path must be removed.
+ if (pathToBase.startsWith("/"))
+ {
+ int slashIndex = pathToBase.indexOf('/', 1);
+ if (slashIndex != -1)
+ {
+ pathToBase = pathToBase.substring(slashIndex + 1);
+ }
+ else
+ {
+ pathToBase = "/";
+ }
+ }
+ }
+
+ try
+ {
+ context = rootContext.getRelativeContext(
+ rootContext.getPointer(pathToBase));
+ }
+ catch (JXPathException e)
+ {
+ throw new IllegalArgumentException(
+ "The pathToBase " + pathToBase
+ + " is not found in root " + root,
+ e);
+ }
+
+ Object pathValue = context.getValue(".");
+ if (pathValue != base)
+ {
+ throw new IllegalArgumentException(
+ "The pathToBase " + pathToBase
+ + " does not evaluate to base " + base
+ + " from root " + root);
+ }
+ // seems to be a bug in realtiveContext . evaluation in JXPath
+ if (".".equals(path))
+ {
+ return new SourcePathPointerIterator(
+ JXPathContext.newContext(root)
+ .iteratePointers(pathToBase));
+ }
+ }
+ else
+ {
+ context = JXPathContext.newContext(base);
+ }
context.setLenient(true);
- final Iterator<?> iterator = context.iterate(path);
- return iterator;
+
+ final Iterator<?> jxpathPointerIterator =
context.iteratePointers(path);
+ return new SourcePathPointerIterator(jxpathPointerIterator);
}
/**
@@ -454,6 +522,11 @@ public final class SourcePath
* Gets a single source element which can be reached from the start element
* by a given path.
*
+ * @param root the model root, or null if no model root exists
+ * (in the latter case, no elements only reachable via base's parent
+ * can be accessed)
+ * @param pathToBase the path from root to base, must be not null
+ * if root is not null, is disregarded if root is null.
* @param sourceElement the start element, not null.
* @param path the path to use, not null.
* @param acceptEmpty whether no match is an error(acceptEmpty=false)
@@ -467,12 +540,15 @@ public final class SourcePath
* @see <a href="http://www.w3.org/TR/xpath#axes">xpath axes</a>
*/
public static Object getObject(
+ final SourceElement root,
+ final String pathToBase,
final SourceElement sourceElement,
final String path,
final boolean acceptEmpty)
throws GeneratorException
{
- final Iterator<?> sourceElementIt = iterate(sourceElement, path);
+ final Iterator<SourcePathPointer> sourceElementIt
+ = iteratePointer(root, pathToBase, sourceElement, path);
if (!sourceElementIt.hasNext())
{
if (acceptEmpty)
@@ -488,7 +564,7 @@ public final class SourcePath
+ sourceElement.getName());
}
}
- final Object result = sourceElementIt.next();
+ final SourcePathPointer sourcePathPointer = sourceElementIt.next();
if (sourceElementIt.hasNext())
{
throw new GeneratorException(
@@ -497,7 +573,7 @@ public final class SourcePath
+ " selects more than a single element on source element "
+ sourceElement.getName());
}
- return result;
+ return sourcePathPointer.getValue();
}
/**
@@ -602,4 +678,48 @@ public final class SourcePath
alreadyProcessed.add(parent);
getParentPath(parent, alreadyProcessed, result);
}
+
+ /**
+ * An iterator of SourcePathPointers wrapping a Iterator of jxpath
pointers.
+ */
+ private static final class SourcePathPointerIterator
+ implements Iterator<SourcePathPointer>
+ {
+ /** The wrapped pointer, not null. */
+ private final Iterator<?> jxpathPointerIterator;
+
+ /**
+ * Constructor.
+ *
+ * @param jxpathPointerIterator the wrapped iterator, must iterate
+ * over org.apache.commons.jxpath.Pointer elements.
+ */
+ public SourcePathPointerIterator(
+ final Iterator<?> jxpathPointerIterator)
+ {
+ if (jxpathPointerIterator == null)
+ {
+ throw new NullPointerException(
+ "jxpathPointerIterator must not be null");
+ }
+ this.jxpathPointerIterator = jxpathPointerIterator;
+ }
+
+ public boolean hasNext()
+ {
+ return jxpathPointerIterator.hasNext();
+ }
+
+ public SourcePathPointer next()
+ {
+ Pointer pointer = (Pointer) jxpathPointerIterator.next();
+ return new SourcePathPointer(pointer.getNode(), pointer.asPath());
+ }
+
+ public void remove()
+ {
+ jxpathPointerIterator.remove();
+ }
+
+ }
}
Added:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePathPointer.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePathPointer.java?rev=1622323&view=auto
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePathPointer.java
(added)
+++
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/SourcePathPointer.java
Wed Sep 3 19:26:19 2014
@@ -0,0 +1,104 @@
+package org.apache.torque.generator.source;
+
+/*
+ * 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.
+ */
+/**
+ * A class containing the value and the path to an object in a model graph
+ */
+public class SourcePathPointer
+{
+ /** The value of the object. */
+ private final Object value;
+
+ /** The path to the object. */
+ private final String path;
+
+ public SourcePathPointer(final Object value, final String path)
+ {
+ this.value = value;
+ this.path = path;
+ }
+
+ public Object getValue()
+ {
+ return value;
+ }
+
+ public String getPath()
+ {
+ return path;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((path == null) ? 0 : path.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ SourcePathPointer other = (SourcePathPointer) obj;
+ if (path == null)
+ {
+ if (other.path != null)
+ {
+ return false;
+ }
+ }
+ else if (!path.equals(other.path))
+ {
+ return false;
+ }
+ if (value == null)
+ {
+ if (other.value != null)
+ {
+ return false;
+ }
+ }
+ else if (!value.equals(other.value))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "SourcePathPointer [value=" + value + ", path=" + path + "]";
+ }
+}
Modified:
db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/SourcePathTest.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/SourcePathTest.java?rev=1622323&r1=1622322&r2=1622323&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/SourcePathTest.java
(original)
+++
db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/SourcePathTest.java
Wed Sep 3 19:26:19 2014
@@ -21,6 +21,8 @@ package org.apache.torque.generator.sour
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -64,8 +66,8 @@ public class SourcePathTest
firstLevel2.getChildren().add(secondLevelb);
modelRoot = new Root();
- modelRoot.childList.add(new Child("child1"));
- modelRoot.childList.add(new Child("child2"));
+ modelRoot.childList.add(new Child("child1", null));
+ modelRoot.childList.add(new Child("child2", null));
modelRoot.stringList.add("string1");
modelRoot.stringList.add("string2");
modelRoot.getPropertyList().add("propertyString1");
@@ -74,6 +76,8 @@ public class SourcePathTest
modelRoot.setPropertyValue("propertyValue");
modelRoot.setValue("setterValue");
modelRoot.value = "fieldValue";
+ modelRoot.child = new Child("child3", new Child("subchildValue",
null));
+
}
@Test
@@ -219,110 +223,385 @@ public class SourcePathTest
}
@Test
- public void testIterateGetRoot()
+ public void testIteratePointerGetRoot()
{
- final Iterator<?> resultIt = SourcePath.iterate(root, "/");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ root,
+ "/",
+ root,
+ "/");
assertTrue(resultIt.hasNext());
- assertSame(root, resultIt.next());
+ assertSamePointer(
+ new SourcePathPointer(root, "/root[1]"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateGetChild()
+ public void testIteratePointerGetRootBaseNull()
{
- final Iterator<?> resultIt = SourcePath.iterate(root, "firstLevel1");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ root,
+ "/");
assertTrue(resultIt.hasNext());
- assertSame(firstLevel1, resultIt.next());
+ assertSamePointer(
+ new SourcePathPointer(root, "/root[1]"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateSeveralMatches()
+ public void testIteratePointerGetChildRootSameAsBase()
{
- final Iterator<?> resultIt = SourcePath.iterate(root,
"firstLevel2/secondLevel");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ root,
+ "/",
+ root,
+ "firstLevel1");
assertTrue(resultIt.hasNext());
- assertSame(secondLevel, resultIt.next());
+ assertSamePointer(
+ new SourcePathPointer(firstLevel1, "/root[1]/firstLevel1[1]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerGetChildRootNull()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ root,
+ "firstLevel1");
assertTrue(resultIt.hasNext());
- assertSame(secondLevela, resultIt.next());
+ assertSamePointer(
+ new SourcePathPointer(firstLevel1, "/root[1]/firstLevel1[1]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerSeveralMatches()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ root,
+ "/firstLevel2/secondLevel");
assertTrue(resultIt.hasNext());
- assertSame(secondLevelb, resultIt.next());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevel,
+ "/root[1]/firstLevel2[1]/secondLevel[1]"),
+ resultIt.next());
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevela,
+ "/root[1]/firstLevel2[1]/secondLevel[2]"),
+ resultIt.next());
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevelb,
+ "/root[1]/firstLevel2[1]/secondLevel[3]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerSeveralMatchesintermediateBase()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ root,
+ "/root/firstLevel2",
+ firstLevel2,
+ "secondLevel");
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevel,
+ "/root/firstLevel2[1]/secondLevel[1]"),
+ resultIt.next());
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevela,
+ "/root/firstLevel2[1]/secondLevel[2]"),
+ resultIt.next());
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevelb,
+ "/root/firstLevel2[1]/secondLevel[3]"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
/**
* Test that we can iterate over path where the parent element
- * of the mathcing elements is not the primary parent element.
+ * of the matching elements is not the primary parent element.
*/
@Test
- public void testIterateNotDefaultParent()
+ public void testIteratePointerNotDefaultParent()
{
firstLevel1.getChildren().add(secondLevela);
firstLevel1.getChildren().add(secondLevel);
- final Iterator<?> resultIt = SourcePath.iterate(root,
"firstLevel1/secondLevel");
- assertTrue(resultIt.hasNext());
- assertSame(secondLevela, resultIt.next());
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ root,
+ "firstLevel1/secondLevel");
assertTrue(resultIt.hasNext());
- assertSame(secondLevel, resultIt.next());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevela,
+ "/root[1]/firstLevel1[1]/secondLevel[1]"),
+ resultIt.next());
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ secondLevel,
+ "/root[1]/firstLevel1[1]/secondLevel[2]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ /**
+ * Test that we can iterate over the parent element.
+ */
+ @Test
+ public void testIteratePointerGetParent()
+ {
+ firstLevel1.getChildren().add(secondLevela);
+ firstLevel1.getChildren().add(secondLevel);
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ root,
+ "firstLevel1/secondLevel[2]",
+ secondLevel,
+ "..");
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(
+ firstLevel1,
+ "/root/firstLevel1[1]"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateModelStringField()
+ public void testIteratePointerModelStringSelf()
{
- final Iterator<?> resultIt = SourcePath.iterate(modelRoot,
"fieldValue");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ root,
+ ".");
assertTrue(resultIt.hasNext());
- assertEquals("fieldValue", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ root,
+ "/root[1]"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateModelStringGetter()
+ public void testIteratePointerModelStringField()
{
- final Iterator<?> resultIt = SourcePath.iterate(modelRoot,
"propertyValue");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ modelRoot,
+ "/",
+ modelRoot,
+ "fieldValue");
assertTrue(resultIt.hasNext());
- assertEquals("propertyValue", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "fieldValue",
+ "/fieldValue"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateModelStringFieldAndGetter()
+ public void testIteratePointerModelStringFieldRootNull()
{
- final Iterator<?> resultIt = SourcePath.iterate(modelRoot, "value");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "fieldValue");
assertTrue(resultIt.hasNext());
- assertEquals("setterValue", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "fieldValue",
+ "/fieldValue"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateModelListField()
+ public void testIteratePointerModelStringGetter()
{
- final Iterator<?> resultIt = SourcePath.iterate(modelRoot,
"stringList");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "propertyValue");
assertTrue(resultIt.hasNext());
- assertEquals("string1", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "propertyValue",
+ "/propertyValue"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerModelStringFieldAndGetter()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "value");
assertTrue(resultIt.hasNext());
- assertEquals("string2", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "setterValue",
+ "/value"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateModelListProperty()
+ public void testIteratePointerModelListField()
{
- final Iterator<?> resultIt = SourcePath.iterate(modelRoot,
"propertyList");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "stringList");
assertTrue(resultIt.hasNext());
- assertEquals("propertyString1", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "string1",
+ "/stringList[1]"),
+ resultIt.next());
assertTrue(resultIt.hasNext());
- assertEquals("propertyString2", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "string2",
+ "/stringList[2]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerModelListDotWithBaseField()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ modelRoot,
+ "/childList[1]",
+ modelRoot.childList.get(0),
+ ".");
+ assertTrue(resultIt.hasNext());
+ assertEquals(
+ new SourcePathPointer(
+ modelRoot.childList.get(0),
+ "/childList[1]"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@Test
- public void testIterateModelListChainedAttribute()
+ public void testIteratePointerModelListProperty()
{
- final Iterator<?> resultIt = SourcePath.iterate(modelRoot,
"childList/value");
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "propertyList");
+ assertTrue(resultIt.hasNext());
+ assertEquals(
+ new SourcePathPointer(
+ "propertyString1",
+ "/propertyList[1]"),
+ resultIt.next());
assertTrue(resultIt.hasNext());
- assertEquals("child1", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "propertyString2",
+ "/propertyList[2]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerModelListPropertyWithIndex()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "propertyList[2]");
assertTrue(resultIt.hasNext());
- assertEquals("child2", resultIt.next());
+ assertEquals(
+ new SourcePathPointer(
+ "propertyString2",
+ "/propertyList[2]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerModelListChainedAttribute()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "childList/value");
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer("child1", "/childList[1]/value"),
+ resultIt.next());
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer("child2", "/childList[2]/value"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerModelPublicListWithIndex()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ null,
+ null,
+ modelRoot,
+ "/childList[1]");
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer(modelRoot.childList.get(0),
"/childList[1]"),
+ resultIt.next());
+ assertFalse(resultIt.hasNext());
+ }
+
+ @Test
+ public void testIteratePointerModelListChainedAttributeIntermediateBase()
+ {
+ final Iterator<SourcePathPointer> resultIt = SourcePath.iteratePointer(
+ modelRoot,
+ "child",
+ modelRoot.child,
+ "/child/subchild/value");
+ assertTrue(resultIt.hasNext());
+ assertSamePointer(
+ new SourcePathPointer("subchildValue",
"/child/subchild/value"),
+ resultIt.next());
assertFalse(resultIt.hasNext());
}
@@ -342,6 +621,8 @@ public class SourcePathTest
private String propertyValue;
+ private Child child;
+
public List<String> getPropertyList()
{
return propertyList;
@@ -366,15 +647,44 @@ public class SourcePathTest
{
this.setterValue = v;
}
+
+ public Child getChild()
+ {
+ return child;
+ }
+
+ public void setChild(final Child child)
+ {
+ this.child = child;
+ }
}
public static class Child
{
- public Child(final String value)
+ public Child(final String value, final Child subchild)
{
this.value = value;
+ this.subchild = subchild;
}
public String value;
+
+ public Child subchild;
+ }
+
+ public static void assertSamePointer(
+ final SourcePathPointer expected,
+ final SourcePathPointer actual)
+ {
+ if (expected == null)
+ {
+ assertNull(actual);
+ }
+ else
+ {
+ assertNotNull(actual);
+ assertSame(expected.getValue(), actual.getValue());
+ assertEquals(expected.getPath(), actual.getPath());
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]