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

COVERAGE SUMMARY FOR SOURCE FILE [ObjectType.java]

nameclass, %method, %block, %line, %
ObjectType.java100% (2/2)100% (16/16)99%  (240/243)99%  (66/67)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ObjectType100% (1/1)100% (14/14)99%  (227/230)98%  (61/62)
getField (String): FieldWrapper 100% (1/1)89%  (24/27)75%  (3/4)
ObjectType (Class): void 100% (1/1)100% (10/10)100% (3/3)
buildFieldList (): void 100% (1/1)100% (50/50)100% (10/10)
createContainer (Object): Object 100% (1/1)100% (13/13)100% (5/5)
createInstance (Object, Object): Object 100% (1/1)100% (2/2)100% (1/1)
getClassCastStrategy (): ClassCastStrategy 100% (1/1)100% (2/2)100% (1/1)
getReferenceStrategy (): ReferenceStrategy 100% (1/1)100% (2/2)100% (1/1)
getSymbolSpec (): Symbol 100% (1/1)100% (2/2)100% (1/1)
init (): void 100% (1/1)100% (16/16)100% (6/6)
readEntries (KeyValueReader, Object): void 100% (1/1)100% (8/8)100% (3/3)
readEntry (KeyValueReader, Object): boolean 100% (1/1)100% (33/33)100% (9/9)
readPartitions (ListReader, Object): void 100% (1/1)100% (18/18)100% (7/7)
writeEntries (KeyValueWriter, Object): void 100% (1/1)100% (30/30)100% (4/4)
writePartitions (ListWriter, Object): void 100% (1/1)100% (17/17)100% (7/7)
     
class ObjectType$AccessibleAction100% (1/1)100% (2/2)100% (13/13)100% (5/5)
ObjectType$AccessibleAction (Class): void 100% (1/1)100% (6/6)100% (3/3)
run (): Object 100% (1/1)100% (7/7)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.type;
20 
21import java.lang.reflect.AccessibleObject;
22import java.lang.reflect.Field;
23import java.security.AccessController;
24import java.security.PrivilegedAction;
25import java.util.ArrayList;
26import java.util.List;
27 
28import org.fuwjax.jon.ClassCastStrategy;
29import org.fuwjax.jon.IndirectType;
30import org.fuwjax.jon.ObjectAccessException;
31import org.fuwjax.jon.ReferenceStrategy;
32import org.fuwjax.jon.SerialFormatException;
33import org.fuwjax.jon.accessor.EntriesAccessor;
34import org.fuwjax.jon.accessor.KeyValueReader;
35import org.fuwjax.jon.accessor.KeyValueWriter;
36import org.fuwjax.jon.accessor.ListReader;
37import org.fuwjax.jon.accessor.ListWriter;
38import org.fuwjax.jon.accessor.ObjectAccessor;
39import org.fuwjax.jon.accessor.Symbol;
40 
41/**
42 * An abstract type for objects.
43 * @author michaeldoberenz
44 */
45public class ObjectType extends AbstractIndirectType implements ObjectAccessor, EntriesAccessor{
46        private FieldWrapper[] fields;
47        private ObjectType parent;
48 
49        /**
50         * Creates an instance.
51         * @param cls the class backing this type
52         */
53        public ObjectType(final Class<?> cls){
54                super(cls);
55                AccessController.doPrivileged(new AccessibleAction(cls));
56        }
57 
58        @Override
59        protected void init(){
60                buildFieldList();
61                try{
62                        parent = (ObjectType)getIndirectType(getType().getSuperclass());
63                }catch(ClassCastException e){
64                        parent = null;
65                }
66        }
67 
68        private void buildFieldList(){
69                final Field[] refFields = getType().getDeclaredFields();
70                final List<FieldWrapper> entryList = new ArrayList<FieldWrapper>();
71                for(int i = 0; i < refFields.length; ++i){
72                        if(FieldWrapper.isTransient(refFields[i])){
73                                continue;
74                        }
75                        final IndirectType type = getIndirectType(refFields[i].getType());
76                        final FieldWrapper entry = new FieldWrapper(refFields[i], type);
77                        entryList.add(entry);
78                }
79                fields = entryList.toArray(new FieldWrapper[entryList.size()]);
80        }
81 
82        public ReferenceStrategy getReferenceStrategy(){
83                return ReferenceStrategy.AssignedReference;
84        }
85 
86        public ClassCastStrategy getClassCastStrategy(){
87                return ClassCastStrategy.AlwaysCast;
88        }
89 
90        public Symbol getSymbolSpec(){
91                return Symbol.Object;
92        }
93 
94        /**
95         * Creates a new {@link PrivilegedAction} that sets all the fields on a
96         * supplied {@link Class} accessible.
97         * @author michaeldoberenz
98         */
99        private static final class AccessibleAction implements PrivilegedAction<Object>{
100                private Class<?> cls;
101 
102                /**
103                 * Creates a new privileged action that sets all the fields on
104                 * <code>cls</code> accessible.
105                 * @param cls the class whose fields should be made accessible
106                 */
107                AccessibleAction(final Class<?> cls){
108                        this.cls = cls;
109                }
110 
111                public Object run(){
112                        AccessibleObject.setAccessible(cls.getDeclaredFields(), true);
113                        return null; // nothing to return
114                }
115        }
116 
117        public void writePartitions(final ListWriter writer, final Object object) throws ObjectAccessException,
118              SerialFormatException{
119                ObjectType partition = this;
120                while(partition != null){
121                        if(partition.fields.length > 0){
122                                writer.write(object, partition);
123                        }
124                        partition = partition.parent;
125                }
126        }
127 
128        public void writeEntries(final KeyValueWriter writer, final Object object) throws ObjectAccessException,
129              SerialFormatException{
130                for(FieldWrapper field: fields){
131                        writer.writeKey(field.getName(), IdentifierType.DEFAULT);
132                        writer.writeValue(field.getValue(object), field.getType());
133                }
134        }
135 
136        public Object createContainer(final Object object) throws ObjectAccessException{
137                if(object != null){
138                        return object;
139                }
140                try{
141                        return NaiveInstantiator.create(getType());
142                }catch(ObjectAccessException e){
143                        return UnsafeInstantiator.create(getType());
144                }
145        }
146 
147        public Object createInstance(final Object container, final Object object){
148                return container;
149        }
150 
151        public void readPartitions(final ListReader listReader, final Object container) throws ObjectAccessException,
152              SerialFormatException{
153                ObjectType partition = this;
154                while(partition != null){
155                        if(partition.fields.length > 0){
156                                listReader.read(container, partition);
157                        }
158                        partition = partition.parent;
159                }
160        }
161 
162        private FieldWrapper getField(final String key) throws ObjectAccessException{
163                for(FieldWrapper field: fields){
164                        if(field.getName().equals(key)){
165                                return field;
166                        }
167                }
168                throw ObjectAccessException.Message.FieldNotFound.exception();
169        }
170 
171        public void readEntries(final KeyValueReader reader, final Object container) throws ObjectAccessException,
172              SerialFormatException{
173                boolean foundEntry;
174                do{
175                        foundEntry = readEntry(reader, container);
176                }while(foundEntry);
177        }
178 
179        private boolean readEntry(final KeyValueReader reader, final Object container) throws ObjectAccessException,
180              SerialFormatException{
181                final int pos = reader.getPosition();
182                try{
183                        final String key = reader.readKey(null, IdentifierType.DEFAULT).toString();
184                        final FieldWrapper field = getField(key);
185                        final Object value = reader.readValue(field.getValue(container), field.getType());
186                        field.setValue(container, value);
187                        return true;
188                }catch(SerialFormatException e){
189                        e.assertPosition(pos);
190                        return false;
191                }
192        }
193}

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