source: trunk/src/ws/fugue88/jpath/Context.java

Last change on this file was 6, checked in by dsowen, 21 years ago

Split out the access stuff into accesslib.
New Creator interface off-loads object creation to user.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.7 KB
Line 
1/*
2 * Created on Apr 23, 2005
3 *
4 * $Log$
5 * Revision 1.4  2005/09/21 22:00:45  dsowen
6 * Split out the access stuff into accesslib.
7 * New Creator interface off-loads object creation to user.
8 *
9 * Revision 1.3  2005/08/19 17:51:17  dsowen
10 * Fixed: NPEs when using accessors from paths, &c.  Included tests.
11 * Fixed: parsing exception wasn't very enlightening.
12 *
13 * Revision 1.2  2005/08/12 19:01:46  dsowen
14 * Feature: can automatically fill missing parts of a graph.
15 *
16 * Revision 1.1  2005/08/03 00:35:29  dsowen
17 * Initial commit.
18 *
19 * Revision 1.2  2005/04/25 02:45:56  dowen
20 * Added type reporting to support creation.
21 *
22 * Revision 1.1  2005/04/25 01:39:53  dowen
23 * Preliminary path support.
24 *
25 */
26package ws.fugue88.jpath;
27
28import java.lang.reflect.Constructor;
29import java.lang.reflect.InvocationTargetException;
30import java.util.Iterator;
31import java.util.List;
32import java.util.Map;
33
34import ws.fugue88.access.Accessor;
35import ws.fugue88.access.ListAccessor;
36import ws.fugue88.access.MapAccessor;
37
38/**
39 * @author dsowen
40 */
41public class Context {
42
43        public Accessor getTargetAccessor(final Path path)
44                        throws BrokenGraphException, IllegalAccessException,
45                        InstantiationException, InvocationTargetException,
46                        NoSuchPropertyException
47        {
48                Context current = this;
49                for(Iterator i = path.parents().iterator(); i.hasNext();) {
50                        final PathPart part = (PathPart)i.next();
51                        Accessor accessor = current.getTargetAccessor(part);
52                        Object obj = accessor.getValue();
53                        if(obj == null)
54                                        obj = _creator.create(accessor.getType(), current._root,
55                                                        part);
56                        if(obj == null)
57                                        throw new BrokenGraphException(this, path, current._root,
58                                                        part);
59
60                        accessor.setValue(obj);
61                        current = new Context(obj, _binder, _creator);
62                }
63                return current.getTargetAccessor(path.terminal());
64        }
65
66        public Object getTarget(final Path path) throws IllegalAccessException,
67                        InstantiationException, InvocationTargetException,
68                        NoSuchPropertyException
69        {
70                try {
71                        return getTargetAccessor(path).getValue();
72                } catch(BrokenGraphException e) {
73                        return null;
74                }
75        }
76
77        public Context navigate(final Path path) throws IllegalAccessException,
78                        InstantiationException, InvocationTargetException,
79                        NoSuchPropertyException
80        {
81                Object child = getTarget(path);
82                return new Context(child, _binder, _creator);
83        }
84
85        public Object getRoot()
86        {
87                return _root;
88        }
89
90        Context(final Object root, final Binder binder, final GraphCreator creator)
91        {
92                // NPEs
93                root.getClass();
94                binder.getClass();
95                creator.getClass();
96
97                _root = root;
98                _binder = binder;
99                _creator = creator;
100        }
101
102        private Accessor getTargetAccessor(final PathPart part)
103                        throws NoSuchPropertyException
104        {
105                if(part instanceof Identifier)
106                                return getTargetAccessor((Identifier)part);
107                return getTargetAccessor((Selector)part);
108        }
109
110        private Accessor getTargetAccessor(final Identifier ident)
111                        throws NoSuchPropertyException
112        {
113                return new PropertyAccessor(_root, _binder.getProperty(
114                                _root.getClass(), ident));
115        }
116
117        private Accessor getTargetAccessor(final Selector sel)
118        {
119                if(_root instanceof Map)
120                                return new MapAccessor((Map)_root, sel.getKey());
121                return new ListAccessor((List)_root, ((NumberSelector)sel).getIndex());
122        }
123
124        private Object createBlank(final Class type) throws IllegalAccessException,
125                        InstantiationException, InvocationTargetException
126        {
127                try {
128                        final Constructor ctor = type.getDeclaredConstructor(null);
129                        ctor.setAccessible(true);
130                        return ctor.newInstance(null);
131                } catch(NoSuchMethodException e) {
132                        throw new InstantiationException("Class " + type.getName()
133                                        + " must have a no-argument constructor.");
134                }
135        }
136
137        private final Object _root;
138        private final Binder _binder;
139        private final GraphCreator _creator;
140}
Note: See TracBrowser for help on using the repository browser.