dmitri 2002/11/27 17:01:30 Added: jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic DynamicPropertyPointer.java DynamicPropertyIterator.java DynamicPointerFactory.java DynamicPointer.java DynamicAttributeIterator.java jxpath/src/test/org/apache/commons/jxpath/ri/model/dynamic DynamicPropertiesModelTest.java Removed: jxpath/src/java/org/apache/commons/jxpath/ri/model/beans DynamicPropertyPointer.java DynamicPointerFactory.java DynamicPointer.java jxpath/src/test/org/apache/commons/jxpath/ri/model/beans DynamicPropertiesModelTest.java Log: Encapsulated dynamic properties into a package of their own Revision Changes Path 1.1 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPropertyPointer.java Index: DynamicPropertyPointer.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPropertyPointer.java,v 1.1 2002/11/28 01:01:30 dmitri Exp $ * $Revision: 1.1 $ * $Date: 2002/11/28 01:01:30 $ * * ==================================================================== * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2001, Plotnix, Inc, * <http://www.plotnix.com/>. * For more information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model.dynamic; import java.util.Arrays; import org.apache.commons.jxpath.*; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.model.NodePointer; import org.apache.commons.jxpath.ri.model.beans.PropertyPointer; import org.apache.commons.jxpath.util.ValueUtils; /** * Pointer pointing to a property of an object with dynamic properties. * * @author Dmitri Plotnikov * @version $Revision: 1.1 $ $Date: 2002/11/28 01:01:30 $ */ public class DynamicPropertyPointer extends PropertyPointer { private DynamicPropertyHandler handler; private String name; private String[] names; private String requiredPropertyName; public DynamicPropertyPointer( NodePointer parent, DynamicPropertyHandler handler) { super(parent); this.handler = handler; } /** * This type of node is auxiliary. */ public boolean isContainer(){ return true; } /** * Number of the DP object's properties. */ public int getPropertyCount(){ return getPropertyNames().length; } /** * Names of all properties, sorted alphabetically */ public String[] getPropertyNames(){ if (names == null){ String allNames[] = handler.getPropertyNames(getBean()); names = new String[allNames.length]; for (int i = 0; i < names.length; i++){ names[i] = allNames[i]; } Arrays.sort(names); if (requiredPropertyName != null){ int inx = Arrays.binarySearch(names, requiredPropertyName); if (inx < 0){ allNames = names; names = new String[allNames.length + 1]; names[0] = requiredPropertyName; System.arraycopy(allNames, 0, names, 1, allNames.length); Arrays.sort(names); } } } return names; } /** * Returns the name of the currently selected property or "*" * if none has been selected. */ public String getPropertyName(){ if (name == null){ String names[] = getPropertyNames(); if (propertyIndex >=0 && propertyIndex < names.length){ name = names[propertyIndex]; } else { name = "*"; } } return name; } /** * Select a property by name. If the supplied name is * not one of the object's existing properties, it implicitly * adds this name to the object's property name list. It does not * set the property value though. In order to set the property * value, call setValue(). */ public void setPropertyName(String propertyName){ setPropertyIndex(UNSPECIFIED_PROPERTY); this.name = propertyName; requiredPropertyName = propertyName; if (names != null && Arrays.binarySearch(names, propertyName) < 0){ names = null; } } /** * Index of the currently selected property in the list of all * properties sorted alphabetically. */ public int getPropertyIndex(){ if (propertyIndex == UNSPECIFIED_PROPERTY){ String names[] = getPropertyNames(); for (int i = 0; i < names.length; i++){ if (names[i].equals(name)){ setPropertyIndex(i); break; } } } return super.getPropertyIndex(); } /** * Index a property by its index in the list of all * properties sorted alphabetically. */ public void setPropertyIndex(int index){ if (propertyIndex != index){ super.setPropertyIndex(index); name = null; } } /** * Returns the value of the property, not an element of the collection * represented by the property, if any. */ public Object getBaseValue(){ return handler.getProperty(getBean(), getPropertyName()); } /** * If index == WHOLE_COLLECTION, the value of the property, otherwise * the value of the index'th element of the collection represented by the * property. If the property is not a collection, index should be zero * and the value will be the property itself. */ public Object getImmediateNode(){ Object value; if (index == WHOLE_COLLECTION) { value = handler.getProperty(getBean(), getPropertyName()); } else { value = ValueUtils.getValue( handler.getProperty(getBean(), getPropertyName()), index); } return value; } /** * A dynamic property is always considered actual - all keys are apparently * existing with possibly the value of null. */ protected boolean isActualProperty(){ return true; } /** * If index == WHOLE_COLLECTION, change the value of the property, otherwise * change the value of the index'th element of the collection * represented by the property. */ public void setValue(Object value){ if (index == WHOLE_COLLECTION) { handler.setProperty(getBean(), getPropertyName(), value); } else { ValueUtils.setValue( handler.getProperty(getBean(), getPropertyName()), index, value); } } public NodePointer createPath(JXPathContext context, Object value){ return createChild(context, getName(), index, value); } public NodePointer createChild(JXPathContext context, QName name, int index, Object value){ // Ignore the name passed to us, use our own data if (index == WHOLE_COLLECTION) { handler.setProperty(getBean(), getPropertyName(), value); } else { Object collection = getBaseValue(); if (collection == null) { AbstractFactory factory = getAbstractFactory(context); if (!factory .createObject( context, this, getBean(), getPropertyName(), 0)) { throw new JXPathException( "Factory could not create an object for path: " + asPath()); } collection = getBaseValue(); } if (index < 0) { throw new JXPathException("Index is less than 1: " + asPath()); } if (index >= getLength()) { collection = ValueUtils.expandCollection(collection, index + 1); handler.setProperty(getBean(), getPropertyName(), collection); } ValueUtils.setValue(collection, index, value); } NodePointer ptr = (NodePointer) clone(); ptr.setIndex(index); return ptr; } public NodePointer createChild(JXPathContext context, QName name, int index){ // Ignore the name passed to us, use our own data Object collection = getBaseValue(); if (collection == null) { AbstractFactory factory = getAbstractFactory(context); if (!factory .createObject(context, this, getBean(), getPropertyName(), 0)) { throw new JXPathException( "Factory could not create an object for path: " + asPath()); } collection = getBaseValue(); } if (index < 0) { throw new JXPathException("Index is less than 1: " + asPath()); } if (index >= getLength()) { collection = ValueUtils.expandCollection(collection, index + 1); handler.setProperty(getBean(), getPropertyName(), collection); } DynamicPropertyPointer pointer = (DynamicPropertyPointer) this.clone(); pointer.setIndex(index); return pointer; } public NodePointer createPath(JXPathContext context){ if (getNode() == null) { AbstractFactory factory = getAbstractFactory(context); int inx = (index == WHOLE_COLLECTION ? 0 : index); if (!factory .createObject( context, this, getBean(), getPropertyName(), inx)) { throw new JXPathException( "Factory could not create an object for path: " + asPath()); } } return this; } public void remove(){ if (index == WHOLE_COLLECTION) { handler.setProperty(getBean(), getPropertyName(), null); } else if (isCollection()) { Object collection = ValueUtils.remove(getBaseValue(), index); handler.setProperty(getBean(), getPropertyName(), collection); } else if (index == 0) { handler.setProperty(getBean(), getPropertyName(), null); } } public String asPath(){ StringBuffer buffer = new StringBuffer(); buffer.append(getParent().asPath()); if (buffer.length() == 0) { buffer.append("/."); } else if (buffer.charAt(buffer.length() - 1) == '/') { buffer.append('.'); } buffer.append("[@name='"); buffer.append(escape(getPropertyName())); buffer.append("']"); if (index != WHOLE_COLLECTION && isCollection()) { buffer.append('[').append(index + 1).append(']'); } return buffer.toString(); } private String escape(String string){ int index = string.indexOf('\''); while (index != -1){ string = string.substring(0, index) + "'" + string.substring(index + 1); index = string.indexOf('\''); } index = string.indexOf('\"'); while (index != -1){ string = string.substring(0, index) + """ + string.substring(index + 1); index = string.indexOf('\"'); } return string; } private AbstractFactory getAbstractFactory(JXPathContext context){ AbstractFactory factory = context.getFactory(); if (factory == null){ throw new JXPathException("Factory is not set on the JXPathContext - cannot create path: " + asPath()); } return factory; } } 1.1 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPropertyIterator.java Index: DynamicPropertyIterator.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model.dynamic; import org.apache.commons.jxpath.ri.model.NodePointer; import org.apache.commons.jxpath.ri.model.beans.PropertyIterator; import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer; /** * <code>DynamicPropertyIterator</code> is different from a regular * <code>PropertyIterator</code> in that given a property name it * will always find that property (albeit with a null value). * * @author <a href="mailto:[EMAIL PROTECTED]">Dmitri Plotnikov</a> * @version $Id: DynamicPropertyIterator.java,v 1.1 2002/11/28 01:01:30 dmitri Exp $ */ public class DynamicPropertyIterator extends PropertyIterator { public DynamicPropertyIterator( PropertyOwnerPointer pointer, String name, boolean reverse, NodePointer startWith) { super(pointer, name, reverse, startWith); } protected void prepareForIndividualProperty(String name){ ((DynamicPropertyPointer)getPropertyPointer()).setPropertyName(name); super.prepareForIndividualProperty(name); } } 1.1 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPointerFactory.java Index: DynamicPointerFactory.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPointerFactory.java,v 1.1 2002/11/28 01:01:30 dmitri Exp $ * $Revision: 1.1 $ * $Date: 2002/11/28 01:01:30 $ * * ==================================================================== * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2001, Plotnix, Inc, * <http://www.plotnix.com/>. * For more information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model.dynamic; import java.util.Locale; import org.apache.commons.jxpath.DynamicPropertyHandler; import org.apache.commons.jxpath.JXPathBeanInfo; import org.apache.commons.jxpath.JXPathIntrospector; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.model.NodePointer; import org.apache.commons.jxpath.ri.model.NodePointerFactory; import org.apache.commons.jxpath.ri.model.beans.NullPointer; import org.apache.commons.jxpath.util.ValueUtils; /** * Implements NodePointerFactory for Dynamic classes like Map. * * @author Dmitri Plotnikov * @version $Revision: 1.1 $ $Date: 2002/11/28 01:01:30 $ */ public class DynamicPointerFactory implements NodePointerFactory { public static final int DYNAMIC_POINTER_FACTORY_ORDER = 800; public int getOrder(){ return DYNAMIC_POINTER_FACTORY_ORDER; } public NodePointer createNodePointer(QName name, Object bean, Locale locale){ JXPathBeanInfo bi = JXPathIntrospector.getBeanInfo(bean.getClass()); if (bi.isDynamic()){ DynamicPropertyHandler handler = ValueUtils.getDynamicPropertyHandler(bi.getDynamicPropertyHandlerClass()); return new DynamicPointer(name, bean, handler, locale); } return null; } public NodePointer createNodePointer(NodePointer parent, QName name, Object bean){ if (bean == null){ return new NullPointer(parent, name); } JXPathBeanInfo bi = JXPathIntrospector.getBeanInfo(bean.getClass()); if (bi.isDynamic()){ DynamicPropertyHandler handler = ValueUtils.getDynamicPropertyHandler(bi.getDynamicPropertyHandlerClass()); return new DynamicPointer(parent, name, bean, handler); } return null; } } 1.1 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPointer.java Index: DynamicPointer.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicPointer.java,v 1.1 2002/11/28 01:01:30 dmitri Exp $ * $Revision: 1.1 $ * $Date: 2002/11/28 01:01:30 $ * * ==================================================================== * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2001, Plotnix, Inc, * <http://www.plotnix.com/>. * For more information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model.dynamic; import java.util.Locale; import org.apache.commons.jxpath.DynamicPropertyHandler; import org.apache.commons.jxpath.JXPathIntrospector; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.model.NodeIterator; import org.apache.commons.jxpath.ri.model.NodePointer; import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer; import org.apache.commons.jxpath.ri.model.beans.PropertyPointer; /** * A Pointer that points to an object with Dynamic Properties. It is used * for the first element of a path; following elements will by of type PropertyPointer. * * @author Dmitri Plotnikov * @version $Revision: 1.1 $ $Date: 2002/11/28 01:01:30 $ */ public class DynamicPointer extends PropertyOwnerPointer { private QName name; private Object bean; private DynamicPropertyHandler handler; private String[] names; public DynamicPointer(QName name, Object bean, DynamicPropertyHandler handler, Locale locale) { super(null, locale); this.name = name; this.bean = bean; this.handler = handler; } public DynamicPointer(NodePointer parent, QName name, Object bean, DynamicPropertyHandler handler) { super(parent); this.name = name; this.bean = bean; this.handler = handler; } public PropertyPointer getPropertyPointer(){ return new DynamicPropertyPointer(this, handler); } public NodeIterator createNodeIterator( String property, boolean reverse, NodePointer startWith) { return new DynamicPropertyIterator(this, property, reverse, startWith); } public NodeIterator attributeIterator(QName name){ return new DynamicAttributeIterator(this, name); } public QName getName(){ return name; } /** * Returns the DP object iself. */ public Object getBaseValue(){ return bean; } public boolean isLeaf() { Object value = getNode(); return value == null || JXPathIntrospector.getBeanInfo(value.getClass()).isAtomic(); } public boolean isCollection(){ return false; } /** * Returns 1. */ public int getLength(){ return 1; } public String asPath(){ if (parent != null){ return super.asPath(); } return "/"; } public int hashCode(){ return System.identityHashCode(bean) + name.hashCode(); } public boolean equals(Object object){ if (object == this){ return true; } if (!(object instanceof DynamicPointer)){ return false; } DynamicPointer other = (DynamicPointer)object; return bean == other.bean && name.equals(other.name); } } 1.1 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dynamic/DynamicAttributeIterator.java Index: DynamicAttributeIterator.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model.dynamic; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.model.beans.BeanAttributeIterator; import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer; /** * <code>DynamicAttributeIterator</code> is different from a regular * <code>BeanAttributeIterator</code> in that given a property name it * will always find that property (albeit with a null value). * * @author <a href="mailto:[EMAIL PROTECTED]">Dmitri Plotnikov</a> * @version $Id: DynamicAttributeIterator.java,v 1.1 2002/11/28 01:01:30 dmitri Exp $ */ public class DynamicAttributeIterator extends BeanAttributeIterator { public DynamicAttributeIterator(PropertyOwnerPointer parent, QName name) { super(parent, name); } protected void prepareForIndividualProperty(String name){ ((DynamicPropertyPointer)getPropertyPointer()).setPropertyName(name); super.prepareForIndividualProperty(name); } } 1.1 jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/dynamic/DynamicPropertiesModelTest.java Index: DynamicPropertiesModelTest.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/dynamic/DynamicPropertiesModelTest.java,v 1.1 2002/11/28 01:01:30 dmitri Exp $ * $Revision: 1.1 $ * $Date: 2002/11/28 01:01:30 $ * * ==================================================================== * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2001, Plotnix, Inc, * <http://www.plotnix.com/>. * For more information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model.dynamic; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.JXPathTestCase; import org.apache.commons.jxpath.TestBean; /** * @todo more iterator testing with maps * * @author Dmitri Plotnikov * @version $Revision: 1.1 $ $Date: 2002/11/28 01:01:30 $ */ public class DynamicPropertiesModelTest extends JXPathTestCase { private static boolean enabled = true; private JXPathContext context; /** * Construct a new instance of this test case. * * @param name Name of the test case */ public DynamicPropertiesModelTest(String name){ super(name); } public void setUp(){ if (context == null){ context = JXPathContext.newContext(new TestBean()); context.setFactory(new TestDynamicPropertyFactory()); } } public void testAxisChild(){ assertXPathValue(context, "map/Key1", "Value 1"); assertXPathPointer(context, "map/Key1", "/map[@name='Key1']"); assertXPathValue(context, "map/Key2/name", "Name 6"); assertXPathPointer(context, "map/Key2/name", "/map[@name='Key2']/name"); } public void testAxisDescendant(){ assertXPathValue(context, "//Key1", "Value 1"); } /** * Testing the pseudo-attribute "name" that dynamic property * objects appear to have. */ public void testAttributeName(){ assertXPathValue(context, "map[@name = 'Key1']", "Value 1"); assertXPathPointer(context, "map[@name = 'Key1']", "/map[@name='Key1']"); assertXPathPointerLenient(context, "map[@name = 'Key"'"'1']", "/map[@name='Key"'"'1']"); assertXPathValue(context, "/.[@name='map']/Key2/name", "Name 6"); assertXPathPointer(context, "/.[@name='map']/Key2/name", "/map[@name='Key2']/name"); // Bean in a map assertXPathValue(context, "/map[@name='Key2'][@name='name']", "Name 6"); assertXPathPointer(context, "/map[@name='Key2'][@name='name']", "/map[@name='Key2']/name"); // Map in a bean in a map assertXPathValue(context, "/.[@name='map'][@name='Key2'][@name='name']", "Name 6"); assertXPathPointer(context, "/.[@name='map'][@name='Key2'][@name='name']", "/map[@name='Key2']/name"); } public void testSetPrimitiveValue(){ assertXPathSetValue(context, "map/Key1", new Integer(6)); } public void testSetCollection(){ // See if we can assign a whole collection context.setValue( "map/Key1", new Integer[]{new Integer(7), new Integer(8)}); // And then an element in that collection assertXPathSetValue(context, "map/Key1[1]", new Integer(9)); } public void testSetNewKey(){ assertXPathSetValue(context, "map/Key4", new Integer(7)); } public void testCreatePath(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); // Calls factory.createObject(..., testBean, "map"), then // sets the value assertXPathCreatePath(context, "/map[@name='TestKey1']", "", "/map[@name='TestKey1']"); } public void testCreatePathAndSetValue(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); // Calls factory.createObject(..., testBean, "map"), then // sets the value assertXPathCreatePathAndSetValue(context, "/map[@name='TestKey1']", "Test", "/map[@name='TestKey1']"); } public void testCreatePathCreateBean(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); // Calls factory.createObject(..., testBean, "map"), then // then factory.createObject(..., map, "TestKey2"), then // sets the value assertXPathCreatePath(context, "/map[@name='TestKey2']/int", new Integer(1), "/map[@name='TestKey2']/int"); } public void testCreatePathAndSetValueCreateBean(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); // Calls factory.createObject(..., testBean, "map"), then // then factory.createObject(..., map, "TestKey2"), then // sets the value assertXPathCreatePathAndSetValue(context, "/map[@name='TestKey2']/int", new Integer(4), "/map[@name='TestKey2']/int"); } public void testCreatePathCollectionElement(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); assertXPathCreatePath(context, "/map/TestKey3[2]", null, "/map[@name='TestKey3'][2]"); // Should be the same as the one before assertXPathCreatePath(context, "/map[@name='TestKey3'][3]", null, "/map[@name='TestKey3'][3]"); } public void testCreatePathAndSetValueCollectionElement(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); assertXPathCreatePathAndSetValue(context, "/map/TestKey3[2]", "Test1", "/map[@name='TestKey3'][2]"); // Should be the same as the one before assertXPathCreatePathAndSetValue(context, "/map[@name='TestKey3'][3]", "Test2", "/map[@name='TestKey3'][3]"); } public void testCreatePathNewCollectionElement(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); // Create an element of a dynamic map element, which is a collection assertXPathCreatePath(context, "/map/TestKey4[1]/int", new Integer(1), "/map[@name='TestKey4'][1]/int"); bean.getMap().remove("TestKey4"); // Should be the same as the one before assertXPathCreatePath(context, "/map/TestKey4[1]/int", new Integer(1), "/map[@name='TestKey4'][1]/int"); } public void testCreatePathAndSetValueNewCollectionElement(){ TestBean bean = (TestBean)context.getContextBean(); bean.setMap(null); // Create an element of a dynamic map element, which is a collection assertXPathCreatePathAndSetValue(context, "/map/TestKey4[1]/int", new Integer(2), "/map[@name='TestKey4'][1]/int"); bean.getMap().remove("TestKey4"); // Should be the same as the one before assertXPathCreatePathAndSetValue(context, "/map/TestKey4[1]/int", new Integer(3), "/map[@name='TestKey4'][1]/int"); } public void testRemovePath(){ TestBean bean = (TestBean)context.getContextBean(); bean.getMap().put("TestKey1", "test"); // Remove dynamic property context.removePath("map[@name = 'TestKey1']"); assertEquals("Remove dynamic property value", null, context.getValue("map[@name = 'TestKey1']")); } public void testRemovePathArrayElement(){ TestBean bean = (TestBean)context.getContextBean(); bean.getMap().put("TestKey2", new String[]{"temp1", "temp2"}); context.removePath("map[@name = 'TestKey2'][1]"); assertEquals("Remove dynamic property collection element", "temp2", context.getValue("map[@name = 'TestKey2'][1]")); } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>