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: torque-dev-unsubscr...@db.apache.org For additional commands, e-mail: torque-dev-h...@db.apache.org