View Javadoc
1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
3    * Thomschke.
4    * 
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    * 
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.ogn;
14  
15  import java.lang.reflect.AccessibleObject;
16  import java.lang.reflect.Field;
17  import java.lang.reflect.Method;
18  
19  import net.sf.oval.exception.InvalidConfigurationException;
20  import net.sf.oval.internal.util.Assert;
21  import net.sf.oval.internal.util.ReflectionUtils;
22  
23  /**
24   * Default object graph navigator implementation.
25   * 
26   * Object path separator is a colon (.), e.g. owner.address.street
27   * 
28   * The implementation currently is limited to address fields and properties. Separate items of arrays, maps or keys cannot be addressed.
29   * 
30   * @author Sebastian Thomschke
31   */
32  public class ObjectGraphNavigatorDefaultImpl implements ObjectGraphNavigator
33  {
34  	public ObjectGraphNavigationResult navigateTo(final Object root, final String path)
35  			throws InvalidConfigurationException
36  	{
37  		Assert.argumentNotNull("root", root);
38  		Assert.argumentNotNull("path", path);
39  
40  		Object parent = null;
41  		Object target = root;
42  		AccessibleObject targetAccessor = null;
43  		for (final String chunk : path.split("\\."))
44  		{
45  			parent = target;
46  			if (parent == null) return null;
47  			final Field field = ReflectionUtils.getFieldRecursive(parent.getClass(), chunk);
48  			if (field == null)
49  			{
50  				final Method getter = ReflectionUtils.getGetterRecursive(parent.getClass(), chunk);
51  				if (getter == null)
52  					throw new InvalidConfigurationException("Invalid object navigation path from root object class ["
53  							+ root.getClass().getName() + "] path: " + path);
54  				targetAccessor = getter;
55  				target = ReflectionUtils.invokeMethod(getter, parent);
56  			}
57  			else
58  			{
59  				targetAccessor = field;
60  				target = ReflectionUtils.getFieldValue(field, parent);
61  			}
62  		}
63  		return new ObjectGraphNavigationResult(root, path, parent, targetAccessor, target);
64  	}
65  }