EMMA Coverage Report (generated Wed Aug 29 00:03:59 CDT 2007)
[all classes][org.fuwjax.jon]

COVERAGE SUMMARY FOR SOURCE FILE [Reference.java]

nameclass, %method, %block, %line, %
Reference.java88%  (7/8)92%  (23/25)84%  (237/281)82%  (75/92)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Reference$CollectionTask0%   (0/1)0%   (0/2)0%   (0/18)0%   (0/8)
Reference$CollectionTask (Collection): void 0%   (0/1)0%   (0/6)0%   (0/3)
setValue (Object): void 0%   (0/1)0%   (0/12)0%   (0/5)
     
class Reference$ArrayTask100% (1/1)100% (2/2)77%  (17/22)78%  (7/9)
setValue (Object): void 100% (1/1)62%  (8/13)60%  (3/5)
Reference$ArrayTask (Object, int): void 100% (1/1)100% (9/9)100% (4/4)
     
class Reference$ListTask100% (1/1)100% (2/2)78%  (18/23)78%  (7/9)
setValue (Object): void 100% (1/1)64%  (9/14)60%  (3/5)
Reference$ListTask (List, int): void 100% (1/1)100% (9/9)100% (4/4)
     
class Reference100% (1/1)100% (9/9)90%  (102/113)91%  (31/34)
addTask (Reference$StoreTask): void 100% (1/1)64%  (9/14)60%  (3/5)
addTo (Collection): void 100% (1/1)77%  (20/26)86%  (6/7)
Reference (String): void 100% (1/1)100% (11/11)100% (4/4)
getName (): String 100% (1/1)100% (3/3)100% (1/1)
getObject (): Object 100% (1/1)100% (8/8)100% (3/3)
putTo (Map, Object, Object): void 100% (1/1)100% (12/12)100% (4/4)
setArrayElement (Object, int): void 100% (1/1)100% (8/8)100% (2/2)
setField (Field, Object): void 100% (1/1)100% (8/8)100% (2/2)
store (Object): void 100% (1/1)100% (23/23)100% (6/6)
     
class Reference$MapTask100% (1/1)100% (4/4)93%  (62/67)90%  (18/20)
put (): void 100% (1/1)67%  (10/15)60%  (3/5)
Reference$MapTask (Map): void 100% (1/1)100% (6/6)100% (3/3)
setMapKey (Object): void 100% (1/1)100% (23/23)100% (6/6)
setMapValue (Object): void 100% (1/1)100% (23/23)100% (6/6)
     
class Reference$FieldTask100% (1/1)100% (2/2)100% (16/16)100% (6/6)
Reference$FieldTask (Object, Field): void 100% (1/1)100% (9/9)100% (4/4)
setValue (Object): void 100% (1/1)100% (7/7)100% (2/2)
     
class Reference$MapTask$1100% (1/1)100% (2/2)100% (11/11)100% (3/3)
Reference$MapTask$1 (Reference$MapTask): void 100% (1/1)100% (6/6)100% (1/1)
setValue (Object): void 100% (1/1)100% (5/5)100% (2/2)
     
class Reference$MapTask$2100% (1/1)100% (2/2)100% (11/11)100% (3/3)
Reference$MapTask$2 (Reference$MapTask): void 100% (1/1)100% (6/6)100% (1/1)
setValue (Object): void 100% (1/1)100% (5/5)100% (2/2)

1/*
2 * This file is part of JON.
3 *
4 * JON is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * JON is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 * 
17 * Copyright 2007 Michael Doberenz
18 */
19package org.fuwjax.jon;
20 
21import java.lang.reflect.Array;
22import java.lang.reflect.Field;
23import java.util.Collection;
24import java.util.LinkedList;
25import java.util.List;
26import java.util.Map;
27 
28import org.fuwjax.jon.type.FieldWrapper;
29 
30/**
31 * Manages the reference to a deserialized object.
32 * @author michaeldoberenz
33 */
34public class Reference{
35        private Object obj;
36        private String name;
37        private boolean stored;
38        private List<StoreTask> tasks;
39 
40        /**
41         * Creates a reference for <code>name</code>.
42         * @param name the reference identifier
43         */
44        public Reference(final String name){
45                this.name = name;
46                tasks = new LinkedList<StoreTask>();
47        }
48 
49        /**
50         * Stores <code>object</code> to the cache this reference was created from.
51         * @param object the newly stored object
52         * @throws ObjectAccessException if an object relationship cannot be restored
53         */
54        public void store(final Object object) throws ObjectAccessException{
55                obj = object;
56                for(StoreTask task: tasks){
57                        task.setValue(obj);
58                }
59                stored = true;
60        }
61 
62        /**
63         * Returns the stored object, if one has been stored to this reference,
64         * otherwise this reference.
65         * @return the stored object or this reference if no object has yet been
66         *         stored
67         */
68        public Object getObject(){
69                if(!stored){
70                        return this;
71                }
72                return obj;
73        }
74 
75        /**
76         * Returns the reference identifier.
77         * @return the reference identifier
78         */
79        public String getName(){
80                return name;
81        }
82 
83        /**
84         * Defers the setting of <code>field</code> on <code>container</code>
85         * until an object is stored in this reference. The value of the field is
86         * then set to the stored object.
87         * @param field the field to set on <code>container</code>
88         * @param container the object to modify
89         * @throws ObjectAccessException if an object relationship cannot be restored
90         */
91        public void setField(final Field field, final Object container) throws ObjectAccessException{
92                addTask(new FieldTask(container, field));
93        }
94 
95        /**
96         * Defers the setting of the element of <code>array</code> at
97         * <code>index</code> until an object is stored in this reference. The
98         * value of the array at index is then set to the stored object.
99         * @param array the array to modify
100         * @param index the index to change in <code>array</code>
101         * @throws ObjectAccessException if an object relationship cannot be restored
102         */
103        public void setArrayElement(final Object array, final int index) throws ObjectAccessException{
104                addTask(new ArrayTask(array, index));
105        }
106 
107        /**
108         * Defers the adding to <code>list</code> until an object is stored in this
109         * reference. The stored object is then added to the list.
110         * @param list the list to add to
111         * @throws ObjectAccessException if an object relationship cannot be restored
112         */
113        public void addTo(final Collection<Object> list) throws ObjectAccessException{
114                if(list instanceof List){
115                        final int i = list.size();
116                        list.add(null);
117                        addTask(new ListTask((List<Object>)list, i));
118                }else{
119                        addTask(new CollectionTask(list));
120                }
121        }
122 
123        /**
124         * Defers the setting of <code>key</code> in <code>map</code> to
125         * <code>value</code> until an object is stored in both the key and value.
126         * @param map the map to modify
127         * @param key the key to modify in <code>map</code>
128         * @param value the new value of <code>key</code> in <code>map</code>
129         * @throws ObjectAccessException if an object relationship cannot be restored
130         */
131        public static void putTo(final Map<Object, Object> map, final Object key, final Object value)
132              throws ObjectAccessException{
133                final MapTask task = new MapTask(map);
134                task.setMapKey(key);
135                task.setMapValue(value);
136        }
137 
138        /**
139         * Adds a task to this reference.
140         * @param task the deferred task to execute during the store operation
141         * @throws ObjectAccessException if an object relationship cannot be restored
142         */
143        protected void addTask(final StoreTask task) throws ObjectAccessException{
144                if(stored){
145                        task.setValue(obj);
146                }else{
147                        tasks.add(task);
148                }
149        }
150 
151        /**
152         * Creates a task which defers the setting of <code>field</code> on
153         * <code>container</code> until an object is stored in the reference.
154         * @author michaeldoberenz
155         */
156        private static class FieldTask implements StoreTask{
157                private final Object container;
158                private final Field field;
159 
160                /**
161                 * Creates a task which defers the setting of <code>field</code> on
162                 * <code>container</code> until an object is stored in the reference.
163                 * The value of the field is then set to the stored object.
164                 * @param field the field to set on <code>container</code>
165                 * @param container the object to modify
166                 */
167                FieldTask(final Object container, final Field field){
168                        this.container = container;
169                        this.field = field;
170                }
171 
172                public void setValue(final Object value) throws ObjectAccessException{
173                        FieldWrapper.setFieldValue(container, field, value);
174                }
175        }
176 
177        /**
178         * Creates a task which defers the setting of <code>array</code> at
179         * <code>index</code> until an object is stored in the reference.
180         * @author michaeldoberenz
181         */
182        private static class ArrayTask implements StoreTask{
183                private final Object array;
184                private final int index;
185 
186                /**
187                 * Creates a task which defers the setting of <code>array</code> at
188                 * <code>index</code> until an object is stored in the reference. The
189                 * value of the array at index is then set to the stored object.
190                 * @param array the field to set on <code>container</code>
191                 * @param index the object to modify
192                 */
193                ArrayTask(final Object array, final int index){
194                        this.array = array;
195                        this.index = index;
196                }
197 
198                public void setValue(final Object value) throws ObjectAccessException{
199                        try{
200                                Array.set(array, index, value);
201                        }catch(RuntimeException e){
202                                throw ObjectAccessException.Message.MethodFailure.exception(e);
203                        }
204                }
205        }
206 
207        /**
208         * Creates a task which defers the adding to <code>list</code> until an
209         * object is stored in the reference.
210         */
211        private static class ListTask implements StoreTask{
212                private final List<Object> list;
213                private int index;
214 
215                /**
216                 * Creates a task which defers the adding to <code>list</code> until an
217                 * object is stored in the reference.
218                 * @param list the list to add the stored value to
219                 * @param index the position in <code>list</code> to set to the stored value
220                 */
221                ListTask(final List<Object> list, final int index){
222                        this.list = list;
223                        this.index = index;
224                }
225 
226                public void setValue(final Object value) throws ObjectAccessException{
227                        try{
228                                list.set(index, value);
229                        }catch(RuntimeException e){
230                                throw ObjectAccessException.Message.MethodFailure.exception(e);
231                        }
232                }
233        }
234 
235        /**
236         * Creates a task which defers the adding to <code>list</code> until an
237         * object is stored in the reference.
238         */
239        private static class CollectionTask implements StoreTask{
240                private final Collection<Object> list;
241 
242                /**
243                 * Creates a task which defers the adding to <code>list</code> until an
244                 * object is stored in the reference.
245                 * @param list the list to add the stored value to
246                 */
247                CollectionTask(final Collection<Object> list){
248                        this.list = list;
249                }
250 
251                public void setValue(final Object value) throws ObjectAccessException{
252                        try{
253                                list.add(value);
254                        }catch(RuntimeException e){
255                                throw ObjectAccessException.Message.MethodFailure.exception(e);
256                        }
257                }
258        }
259 
260        /**
261         * Creates a new composite task which defers both the key and value of a put
262         * operation.
263         */
264        private static class MapTask{
265                private final Map<Object, Object> map;
266                private Object key;
267                private Object value;
268 
269                /**
270                 * Creates a new composite task which defers both the key and value of a
271                 * put operation.
272                 * @param map the map to modify
273                 */
274                MapTask(final Map<Object, Object> map){
275                        this.map = map;
276                }
277 
278                /**
279                 * Sets the value of this map entry to <code>mapValue</code>.
280                 * @param mapValue the new value of this entry
281                 * @throws ObjectAccessException if an object relationship cannot be
282                 *         restored
283                 */
284                protected void setMapValue(final Object mapValue) throws ObjectAccessException{
285                        value = mapValue;
286                        if(value instanceof Reference){
287                                ((Reference)value).addTask(new StoreTask(){
288                                        public void setValue(final Object val) throws ObjectAccessException{
289                                                setMapValue(val);
290                                        }
291                                });
292                        }else if(!(key instanceof Reference)){
293                                put();
294                        }
295                }
296 
297                /**
298                 * Sets the key of this map entry to <code>mapKey</code>.
299                 * @param mapKey the new key of this entry
300                 * @throws ObjectAccessException if an object relationship cannot be
301                 *         restored
302                 */
303                protected void setMapKey(final Object mapKey) throws ObjectAccessException{
304                        key = mapKey;
305                        if(key instanceof Reference){
306                                ((Reference)key).addTask(new StoreTask(){
307                                        public void setValue(final Object val) throws ObjectAccessException{
308                                                setMapKey(val);
309                                        }
310                                });
311                        }else if(!(value instanceof Reference)){
312                                put();
313                        }
314                }
315 
316                private void put() throws ObjectAccessException{
317                        try{
318                                map.put(key, value);
319                        }catch(RuntimeException e){
320                                throw ObjectAccessException.Message.MethodFailure.exception(e);
321                        }
322                }
323        }
324 
325        /**
326         * An interface for tasks which should run when the object is stored.
327         * @author michaeldoberenz
328         */
329        private static interface StoreTask{
330                /**
331                 * Sets the value of the task to <code>value</code>.
332                 * @param value the stored object
333                 * @throws ObjectAccessException if an object relationship cannot be
334                 *         restored
335                 */
336                void setValue(Object value) throws ObjectAccessException;
337        }
338}

[all classes][org.fuwjax.jon]
EMMA 2.0.5312 (C) Vladimir Roubtsov