Index: /trunk/.cvsignore
===================================================================
--- /trunk/.cvsignore	(revision 2)
+++ /trunk/.cvsignore	(revision 2)
@@ -0,0 +1,3 @@
+target
+.classpath
+.project
Index: /trunk/project.xml
===================================================================
--- /trunk/project.xml	(revision 2)
+++ /trunk/project.xml	(revision 2)
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+ -->
+<project>
+  <pomVersion>3</pomVersion>
+  <id>omlib</id>
+  <name>Java Path Library</name>
+  <!-- The version of the project under development, e.g.
+       1.1, 1.2, 2.0-SNAPSHOT -->
+  <currentVersion>1.0</currentVersion>
+  <!-- details about the organization that 'owns' the project -->
+  <organization>
+    <name>David Owen</name>
+    <url>http://www.fugue88.ws/</url>
+  </organization>
+  <inceptionYear>2005</inceptionYear>
+  <package>ws.fugue88.jpath</package>
+  <description>This is a small library that facilitates interaction with instance managers whose signatures aren't known at compile time. It assumes certain naming conventions that the instance managers are supposed to follow in order to locate and invoke the appropriate methods.</description>
+  <!-- the project home page -->
+  <url>http://maven.apache.org/reference/plugins/examples/</url>
+  <siteAddress>jakarta.apache.org</siteAddress>
+  <siteDirectory>/www/maven.apache.org/reference/plugins/examples/</siteDirectory>
+  <distributionDirectory>/www/maven.apache.org/builds/</distributionDirectory>
+  <!-- the version control repository and http url for online access
+       the connection element has the form:
+       scm:<system>:<system specific connection string> -->
+  <repository>
+    <connection>scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:maven-plugins/examples</connection>
+    <url>http://cvs.apache.org/viewcvs/maven-plugins/examples/</url>
+  </repository>
+  <developers>
+    <developer>
+      <id>dsowen</id>
+      <name>David Owen</name>
+    </developer>
+  </developers>
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <unitTestSourceDirectory>testsrc</unitTestSourceDirectory>
+    <unitTest>
+      <includes>
+        <include>**/*Test.java</include>
+      </includes>
+    </unitTest>
+  </build>
+</project>
Index: /trunk/src/ws/fugue88/jpath/Accessor.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Accessor.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Accessor.java	(revision 2)
@@ -0,0 +1,24 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author dsowen
+ */
+public interface Accessor {
+
+	public abstract Class getType();
+
+	public abstract Object getValue() throws InvocationTargetException;
+
+	public abstract void setValue(final Object value)
+			throws InvocationTargetException;
+}
Index: /trunk/src/ws/fugue88/jpath/Binder.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Binder.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Binder.java	(revision 2)
@@ -0,0 +1,47 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+class Binder {
+
+	Property getProperty(final Class type, final Identifier part)
+			throws NoSuchPropertyException
+	{
+		try {
+			return new MutableMethodProperty(part.getName(), type, "get"
+					+ initialize(part.getName()), "set"
+					+ initialize(part.getName()));
+		} catch(NoSuchMethodException e) {
+			try {
+				return new ImmutableMethodProperty(part.getName(), type, "get"
+						+ initialize(part.getName()));
+			} catch(NoSuchMethodException e1) {
+				try {
+					return new FieldProperty(part.getName(), type,
+							part.getName());
+				} catch(NoSuchFieldException e2) {
+					try {
+						return new FieldProperty(part.getName(), type, "_"
+								+ part.getName());
+					} catch(NoSuchFieldException e3) {
+						throw new NoSuchPropertyException(type, part.getName());
+					}
+				}
+			}
+		}
+	}
+
+	private static String initialize(final String s)
+	{
+		return s.substring(0, 1).toUpperCase() + s.substring(1);
+	}
+}
Index: /trunk/src/ws/fugue88/jpath/Context.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Context.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Context.java	(revision 2)
@@ -0,0 +1,87 @@
+/*
+ * Created on Apr 23, 2005
+ *
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ * Revision 1.2  2005/04/25 02:45:56  dowen
+ * Added type reporting to support creation.
+ *
+ * Revision 1.1  2005/04/25 01:39:53  dowen
+ * Preliminary path support.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dsowen
+ */
+public class Context {
+
+	public Accessor getTargetAccessor(final Path path)
+			throws InvocationTargetException, NoSuchPropertyException
+	{
+		Context current = this;
+		Accessor accessor = null;
+		for(Iterator i = path.iterator(); i.hasNext();) {
+			accessor = current.getTargetAccessor((PathPart)i.next());
+			current = new Context(accessor.getValue(), _binder);
+		}
+		return accessor;
+	}
+
+	public Object getTarget(final Path path) throws InvocationTargetException,
+			NoSuchPropertyException
+	{
+		return getTargetAccessor(path).getValue();
+	}
+
+	public Context navigate(final Path path) throws InvocationTargetException,
+			NoSuchPropertyException
+	{
+		Object child = getTarget(path);
+		return new Context(child, _binder);
+	}
+
+	public Object getRoot()
+	{
+		return _root;
+	}
+
+	Context(final Object root, final Binder binder)
+	{
+		_root = root;
+		_binder = binder;
+	}
+
+	private Accessor getTargetAccessor(final PathPart part)
+			throws NoSuchPropertyException
+	{
+		if(part instanceof Identifier)
+				return getTargetAccessor((Identifier)part);
+		return getTargetAccessor((Selector)part);
+	}
+
+	private Accessor getTargetAccessor(final Identifier ident)
+			throws NoSuchPropertyException
+	{
+		return new PropertyAccessor(_root, _binder.getProperty(
+				_root.getClass(), ident));
+	}
+
+	private Accessor getTargetAccessor(final Selector sel)
+	{
+		if(_root instanceof Map)
+				return new MapAccessor((Map)_root, sel.getKey());
+		return new ListAccessor((List)_root, ((NumberSelector)sel).getIndex());
+	}
+
+	private final Object _root;
+	private final Binder _binder;
+}
Index: /trunk/src/ws/fugue88/jpath/ContextFactory.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/ContextFactory.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/ContextFactory.java	(revision 2)
@@ -0,0 +1,22 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public class ContextFactory {
+
+	public Context createContext(final Object root)
+	{
+		return new Context(root, _binder);
+	}
+
+	private final Binder _binder = new Binder();
+}
Index: /trunk/src/ws/fugue88/jpath/FieldProperty.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/FieldProperty.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/FieldProperty.java	(revision 2)
@@ -0,0 +1,66 @@
+/*
+ * Created on Mar 15, 2005
+ *
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ * Revision 1.2  2005/04/10 19:48:29  dowen
+ * Renamed package.
+ *
+ * Revision 1.1  2005/03/19 16:49:20  dowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.Field;
+
+/**
+ * @author dsowen
+ */
+class FieldProperty implements Property {
+
+	FieldProperty(String name, Class clas, String field)
+			throws NoSuchFieldException
+	{
+		_name = name;
+
+		_field = clas.getDeclaredField(field);
+		_field.setAccessible(true);
+
+		_type = _field.getType();
+	}
+
+	public String getName()
+	{
+		return _name;
+	}
+
+	public Class getType()
+	{
+		return _type;
+	}
+
+	public Object getValue(Object that)
+	{
+		try {
+			return _field.get(that);
+		} catch(IllegalAccessException e) {
+			throw new Error(e);
+		}
+	}
+
+	public void setValue(Object that, Object value)
+	{
+		try {
+			_field.set(that, value);
+		} catch(IllegalAccessException e) {
+			throw new Error(e);
+		}
+	}
+
+	private String _name;
+	private Class _type;
+	private Field _field;
+}
Index: /trunk/src/ws/fugue88/jpath/Identifier.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Identifier.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Identifier.java	(revision 2)
@@ -0,0 +1,27 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public class Identifier extends PathPart {
+
+	public Identifier(final String name)
+	{
+		_name = name;
+	}
+
+	public String getName()
+	{
+		return _name;
+	}
+
+	private final String _name;
+}
Index: /trunk/src/ws/fugue88/jpath/ImmutableMethodProperty.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/ImmutableMethodProperty.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/ImmutableMethodProperty.java	(revision 2)
@@ -0,0 +1,65 @@
+/*
+ * Created on Mar 15, 2005
+ *
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ * Revision 1.2  2005/04/10 19:48:29  dowen
+ * Renamed package.
+ *
+ * Revision 1.1  2005/03/19 16:49:20  dowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * @author dsowen
+ */
+class ImmutableMethodProperty implements Property {
+
+	ImmutableMethodProperty(String name, Class clas, String get_method)
+			throws NoSuchMethodException
+	{
+		_name = name;
+
+		_get = clas.getDeclaredMethod(get_method, null);
+		_get.setAccessible(true);
+
+		_type = _get.getReturnType();
+	}
+
+	public Class getType()
+	{
+		return _type;
+	}
+
+	public String getName()
+	{
+		return _name;
+	}
+
+	public Object getValue(Object that) throws InvocationTargetException
+	{
+		try {
+			return _get.invoke(that, null);
+		} catch(IllegalAccessException e) {
+			throw new Error(e);
+		}
+	}
+
+	public void setValue(Object that, Object value)
+			throws InvocationTargetException
+	{
+		throw new UnsupportedOperationException("Property '" + _name
+				+ "' of class " + _type + "is read-only.");
+	}
+
+	private String _name;
+	private Class _type;
+	private Method _get;
+}
Index: /trunk/src/ws/fugue88/jpath/ListAccessor.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/ListAccessor.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/ListAccessor.java	(revision 2)
@@ -0,0 +1,42 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+/**
+ * @author dsowen
+ */
+public class ListAccessor implements Accessor {
+
+	public Class getType()
+	{
+		throw new UnsupportedOperationException();
+	}
+
+	public Object getValue() throws InvocationTargetException
+	{
+		return _idx >= _list.size() ? null : _list.get(_idx);
+	}
+
+	public void setValue(final Object value) throws InvocationTargetException
+	{
+		_list.set(_idx, value);
+	}
+
+	ListAccessor(final List list, final int idx)
+	{
+		_list = list;
+		_idx = idx;
+	}
+
+	private final List _list;
+	private final int _idx;
+}
Index: /trunk/src/ws/fugue88/jpath/MapAccessor.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/MapAccessor.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/MapAccessor.java	(revision 2)
@@ -0,0 +1,42 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+/**
+ * @author dsowen
+ */
+public class MapAccessor implements Accessor {
+
+	public Class getType()
+	{
+		return _map.get(_key) == null ? null : _map.get(_key).getClass();
+	}
+
+	public Object getValue() throws InvocationTargetException
+	{
+		return _map.get(_key);
+	}
+
+	public void setValue(final Object value) throws InvocationTargetException
+	{
+		_map.put(_key, value);
+	}
+
+	MapAccessor(final Map map, final Object key)
+	{
+		_map = map;
+		_key = key;
+	}
+
+	private final Map _map;
+	private final Object _key;
+}
Index: /trunk/src/ws/fugue88/jpath/MutableMethodProperty.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/MutableMethodProperty.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/MutableMethodProperty.java	(revision 2)
@@ -0,0 +1,40 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * @author dsowen
+ */
+public class MutableMethodProperty extends ImmutableMethodProperty {
+
+	MutableMethodProperty(String name, Class clas, String get_method,
+			String set_method) throws NoSuchMethodException
+	{
+		super(name, clas, get_method);
+
+		_set = clas.getDeclaredMethod(set_method, new Class[] { getType() });
+		_set.setAccessible(true);
+	}
+
+	public void setValue(Object that, Object value)
+			throws InvocationTargetException
+	{
+		try {
+			_set.invoke(that, new Object[] { value });
+		} catch(IllegalAccessException e) {
+			throw new Error(e);
+		}
+	}
+
+	private Method _set;
+
+}
Index: /trunk/src/ws/fugue88/jpath/NoSuchPropertyException.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/NoSuchPropertyException.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/NoSuchPropertyException.java	(revision 2)
@@ -0,0 +1,26 @@
+/*
+ * Created on Mar 15, 2005
+ *
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ * Revision 1.2  2005/04/10 19:48:29  dowen
+ * Renamed package.
+ *
+ * Revision 1.1  2005/03/19 16:49:21  dowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public class NoSuchPropertyException extends Exception {
+
+	NoSuchPropertyException(final Class type, final String property)
+	{
+		super("Property '" + property + "' on class " + type + "not found.");
+	}
+}
Index: /trunk/src/ws/fugue88/jpath/NumberSelector.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/NumberSelector.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/NumberSelector.java	(revision 2)
@@ -0,0 +1,32 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public class NumberSelector extends Selector {
+
+	public NumberSelector(final String number)
+	{
+		_number = Integer.valueOf(number);
+	}
+
+	public Object getKey()
+	{
+		return _number;
+	}
+
+	public int getIndex()
+	{
+		return _number.intValue();
+	}
+
+	private final Integer _number;
+}
Index: /trunk/src/ws/fugue88/jpath/Path.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Path.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Path.java	(revision 2)
@@ -0,0 +1,94 @@
+/*
+ * Created on Apr 24, 2005
+ *
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ * Revision 1.1  2005/04/25 01:39:53  dowen
+ * Preliminary path support.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.nio.CharBuffer;
+import java.text.ParseException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author dsowen
+ */
+public class Path {
+
+	public static String quote(final String s)
+	{
+		return s.replaceAll("'", "\\\\'");
+	}
+
+	public static String unquote(final String s)
+	{
+		return s.replaceAll("\\\\'", "'");
+	}
+
+	public Path(final String path) throws ParseException
+	{
+		_parts = new LinkedList();
+
+		CharSequence buff = CharBuffer.wrap(path);
+		do {
+			Matcher m;
+			final PathPart pp;
+			if((m = IDENT.matcher(buff)).find()) {
+				pp = new Identifier(m.group(1));
+			} else if((m = NUM_SEL.matcher(buff)).find()) {
+				pp = new NumberSelector(m.group(1));
+			} else if((m = STR_SEL.matcher(buff)).find()) {
+				pp = new StringSelector(unquote(m.group(1)));
+			} else {
+				throw new ParseException(null, -1);
+			}
+			_parts.add(pp);
+			buff = buff.subSequence(m.end(), buff.length());
+		} while(buff.length() > 0);
+	}
+
+	public Path parents()
+	{
+		return new Path(_parts.subList(0, _parts.size() - 1));
+	}
+
+	public String terminal()
+	{
+		return (String)_parts.get(_parts.size() - 1);
+	}
+
+	public Iterator iterator()
+	{
+		return Collections.unmodifiableList(_parts).iterator();
+	}
+
+	protected Path(final List list)
+	{
+		_parts = list;
+	}
+
+	private final List _parts;
+
+	private static final String IDENT_START = "A-Za-z_";
+	private static final String IDENT_END = IDENT_START + "0-9";
+	private static final Pattern IDENT = Pattern.compile("^/([" + IDENT_START
+			+ "][" + IDENT_END + "]*)");
+
+	private static final String NUM_LIT = "-?[0-9]+";
+	private static final Pattern NUM_SEL = Pattern.compile("^\\[(" + NUM_LIT
+			+ ")\\]");
+
+	private static final String STR_LIT = "'((?:[^']|\\\\')*)'";
+	private static final Pattern STR_SEL = Pattern.compile("^\\[" + STR_LIT
+			+ "\\]");
+}
Index: /trunk/src/ws/fugue88/jpath/PathPart.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/PathPart.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/PathPart.java	(revision 2)
@@ -0,0 +1,15 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public class PathPart {
+}
Index: /trunk/src/ws/fugue88/jpath/Property.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Property.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Property.java	(revision 2)
@@ -0,0 +1,31 @@
+/*
+ * Created on Mar 15, 2005
+ *
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ * Revision 1.2  2005/04/10 19:48:29  dowen
+ * Renamed package.
+ *
+ * Revision 1.1  2005/03/19 16:49:21  dowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author dsowen
+ */
+interface Property {
+
+	String getName();
+
+	Class getType();
+
+	Object getValue(Object that) throws InvocationTargetException;
+
+	void setValue(Object that, Object value) throws InvocationTargetException;
+}
Index: /trunk/src/ws/fugue88/jpath/PropertyAccessor.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/PropertyAccessor.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/PropertyAccessor.java	(revision 2)
@@ -0,0 +1,41 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author dsowen
+ */
+public class PropertyAccessor implements Accessor {
+
+	public Class getType()
+	{
+		return _prop.getType();
+	}
+
+	public Object getValue() throws InvocationTargetException
+	{
+		return _prop.getValue(_that);
+	}
+
+	public void setValue(final Object value) throws InvocationTargetException
+	{
+		_prop.setValue(_that, value);
+	}
+
+	PropertyAccessor(final Object that, final Property property)
+	{
+		_that = that;
+		_prop = property;
+	}
+
+	private final Object _that;
+	private final Property _prop;
+}
Index: /trunk/src/ws/fugue88/jpath/Selector.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/Selector.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/Selector.java	(revision 2)
@@ -0,0 +1,17 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public abstract class Selector extends PathPart {
+
+	public abstract Object getKey();
+}
Index: /trunk/src/ws/fugue88/jpath/StringSelector.java
===================================================================
--- /trunk/src/ws/fugue88/jpath/StringSelector.java	(revision 2)
+++ /trunk/src/ws/fugue88/jpath/StringSelector.java	(revision 2)
@@ -0,0 +1,27 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+/**
+ * @author dsowen
+ */
+public class StringSelector extends Selector {
+
+	public StringSelector(final String str)
+	{
+		_str = str;
+	}
+
+	public Object getKey()
+	{
+		return _str;
+	}
+
+	private final String _str;
+}
Index: /trunk/testsrc/ws/fugue88/jpath/ContextTest.java
===================================================================
--- /trunk/testsrc/ws/fugue88/jpath/ContextTest.java	(revision 2)
+++ /trunk/testsrc/ws/fugue88/jpath/ContextTest.java	(revision 2)
@@ -0,0 +1,103 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+/**
+ * @author dsowen
+ */
+public class ContextTest extends TestCase {
+
+	public void testFieldIdentifier() throws Exception
+	{
+		class A {
+
+			String b = "test";
+		}
+		A a = new A();
+
+		ContextFactory factory = new ContextFactory();
+		Context context = factory.createContext(a);
+		assertSame(a.b, context.getTarget(new Path("/b")));
+
+		Accessor accessor = context.getTargetAccessor(new Path("/b"));
+		assertSame(a.b, accessor.getValue());
+		accessor.setValue("done");
+		assertEquals("done", accessor.getValue());
+		assertEquals("done", a.b);
+	}
+
+	public void testGetterIdentifier() throws Exception
+	{
+		class A {
+
+			String getB()
+			{
+				return "test";
+			}
+		}
+		A a = new A();
+
+		ContextFactory factory = new ContextFactory();
+		Context context = factory.createContext(a);
+		assertEquals("test", context.getTarget(new Path("/b")));
+		try {
+			context.getTargetAccessor(new Path("/b")).setValue("done");
+			assertTrue(false);
+		} catch(UnsupportedOperationException e) {}
+	}
+
+	public void testGetterSetterIdentifier() throws Exception
+	{
+		class A {
+
+			String getB()
+			{
+				return x;
+			}
+
+			void setB(String s)
+			{
+				x = s;
+			}
+
+			String x = "test";
+		}
+		A a = new A();
+
+		ContextFactory factory = new ContextFactory();
+		Context context = factory.createContext(a);
+		assertEquals("test", context.getTarget(new Path("/b")));
+		context.getTargetAccessor(new Path("/b")).setValue("done");
+		assertEquals("done", a.getB());
+	}
+
+	public void testKey() throws Exception
+	{
+		class A {
+
+			HashMap b = new HashMap();
+
+			A()
+			{
+				b.put("c", "test");
+			}
+		}
+		A a = new A();
+
+		ContextFactory factory = new ContextFactory();
+		Context context = factory.createContext(a);
+		assertEquals("test", context.getTarget(new Path("/b['c']")));
+		context.getTargetAccessor(new Path("/b['c']")).setValue("done");
+		assertEquals("done", a.b.get("c"));
+	}
+}
Index: /trunk/testsrc/ws/fugue88/jpath/FieldPropertyTest.java
===================================================================
--- /trunk/testsrc/ws/fugue88/jpath/FieldPropertyTest.java	(revision 2)
+++ /trunk/testsrc/ws/fugue88/jpath/FieldPropertyTest.java	(revision 2)
@@ -0,0 +1,42 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import junit.framework.TestCase;
+
+/**
+ * @author dsowen
+ */
+public class FieldPropertyTest extends TestCase {
+
+	public void testGet() throws Exception
+	{
+		class A {
+
+			String b = "test";
+		}
+		A a = new A();
+
+		FieldProperty property = new FieldProperty("b", A.class, "b");
+		assertSame(a.b, property.getValue(a));
+	}
+
+	public void testSet() throws Exception
+	{
+		class A {
+
+			String b = "test";
+		}
+		A a = new A();
+
+		FieldProperty property = new FieldProperty("b", A.class, "b");
+		property.setValue(a, "done");
+		assertEquals("done", a.b);
+	}
+}
Index: /trunk/testsrc/ws/fugue88/jpath/PathTest.java
===================================================================
--- /trunk/testsrc/ws/fugue88/jpath/PathTest.java	(revision 2)
+++ /trunk/testsrc/ws/fugue88/jpath/PathTest.java	(revision 2)
@@ -0,0 +1,77 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+/**
+ * @author dsowen
+ */
+public class PathTest extends TestCase {
+
+	public void testQuote()
+	{
+		assertEquals("test", Path.quote("test"));
+		assertEquals("te\\'st", Path.quote("te'st"));
+	}
+
+	public void testIdentifier() throws Exception
+	{
+		Path path = new Path("/test");
+		Iterator i = path.iterator();
+		PathPart part = (PathPart)i.next();
+		assertTrue(part instanceof Identifier);
+		assertEquals("test", ((Identifier)part).getName());
+		assertFalse(i.hasNext());
+	}
+
+	public void testNumberSelector() throws Exception
+	{
+		Path path = new Path("[0]");
+		Iterator i = path.iterator();
+		PathPart part = (PathPart)i.next();
+		assertTrue(part instanceof NumberSelector);
+		assertEquals(0, ((NumberSelector)part).getIndex());
+		assertFalse(i.hasNext());
+	}
+
+	public void testStringSelectorSimple() throws Exception
+	{
+		Path path = new Path("['test']");
+		Iterator i = path.iterator();
+		PathPart part = (PathPart)i.next();
+		assertTrue(part instanceof StringSelector);
+		assertEquals("test", ((StringSelector)part).getKey());
+		assertFalse(i.hasNext());
+	}
+
+	public void testStringSelectorQuoted() throws Exception
+	{
+		Path path = new Path("['te\\'st']");
+		Iterator i = path.iterator();
+		PathPart part = (PathPart)i.next();
+		assertTrue(part instanceof StringSelector);
+		assertEquals("te'st", ((StringSelector)part).getKey());
+		assertFalse(i.hasNext());
+	}
+	public void testCompound1() throws Exception
+	{
+		Path path = new Path("/a/b");
+		Iterator i = path.iterator();
+		PathPart part = (PathPart)i.next();
+		assertTrue(part instanceof Identifier);
+		assertEquals("a", ((Identifier)part).getName());
+		part = (PathPart)i.next();
+		assertTrue(part instanceof Identifier);
+		assertEquals("b", ((Identifier)part).getName());
+		assertFalse(i.hasNext());
+	}
+}
Index: /trunk/testsrc/ws/fugue88/jpath/PropertyAccessorTest.java
===================================================================
--- /trunk/testsrc/ws/fugue88/jpath/PropertyAccessorTest.java	(revision 2)
+++ /trunk/testsrc/ws/fugue88/jpath/PropertyAccessorTest.java	(revision 2)
@@ -0,0 +1,32 @@
+/*
+ * Created on Aug 2, 2005
+ * 
+ * $Log$
+ * Revision 1.1  2005/08/03 00:35:29  dsowen
+ * Initial commit.
+ *
+ */
+package ws.fugue88.jpath;
+
+import junit.framework.TestCase;
+
+/**
+ * @author dsowen
+ */
+public class PropertyAccessorTest extends TestCase {
+
+	public void testFieldAccessor() throws Exception
+	{
+		class A {
+
+			String b = "test";
+		}
+		A a = new A();
+
+		PropertyAccessor accessor = new PropertyAccessor(a, new FieldProperty(
+				"b", A.class, "b"));
+		assertSame(a.b, accessor.getValue());
+		accessor.setValue("done");
+		assertEquals("done", a.b);
+	}
+}
