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

COVERAGE SUMMARY FOR SOURCE FILE [ClassTypeLibrary.java]

nameclass, %method, %block, %line, %
ClassTypeLibrary.java100% (14/14)98%  (46/47)97%  (430/443)96%  (69.8/73)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ClassTypeLibrary$TypeCategory100% (1/1)83%  (5/6)93%  (129/138)86%  (13.8/16)
valueOf (String): ClassTypeLibrary$TypeCategory 0%   (0/1)0%   (0/5)0%   (0/1)
hasDefaultConstructor (Class): boolean 100% (1/1)73%  (11/15)58%  (2.9/5)
<static initializer> 100% (1/1)100% (104/104)100% (11/11)
ClassTypeLibrary$TypeCategory (String, int): void 100% (1/1)100% (5/5)100% (1/1)
ClassTypeLibrary$TypeCategory (String, int, ClassTypeLibrary$1): void 100% (1/1)100% (5/5)100% (1/1)
values (): ClassTypeLibrary$TypeCategory [] 100% (1/1)100% (4/4)100% (1/1)
     
class ClassTypeLibrary100% (1/1)100% (6/6)96%  (91/95)95%  (20/21)
createType (Class): AbstractIndirectType 100% (1/1)86%  (24/28)75%  (3/4)
ClassTypeLibrary (): void 100% (1/1)100% (23/23)100% (6/6)
createReader (CachedLexable): Reader 100% (1/1)100% (6/6)100% (1/1)
createWriter (CachedAppendable): Writer 100% (1/1)100% (6/6)100% (1/1)
getType (Class): AbstractIndirectType 100% (1/1)100% (23/23)100% (6/6)
getTypeFor (Object): IndirectType 100% (1/1)100% (9/9)100% (3/3)
     
class ClassTypeLibrary$1100% (1/1)100% (2/2)100% (19/19)100% (3/3)
ClassTypeLibrary$1 (ClassTypeLibrary, CachedAppendable): void 100% (1/1)100% (9/9)100% (1/1)
write (Object): void 100% (1/1)100% (10/10)100% (2/2)
     
class ClassTypeLibrary$2100% (1/1)100% (3/3)100% (29/29)100% (3/3)
ClassTypeLibrary$2 (ClassTypeLibrary, CachedLexable): void 100% (1/1)100% (9/9)100% (1/1)
read (): Object 100% (1/1)100% (10/10)100% (1/1)
read (Object): Object 100% (1/1)100% (10/10)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$1100% (1/1)100% (3/3)100% (21/21)100% (3/3)
ClassTypeLibrary$TypeCategory$1 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (10/10)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$10100% (1/1)100% (3/3)100% (13/13)100% (3/3)
ClassTypeLibrary$TypeCategory$10 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (2/2)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$2100% (1/1)100% (3/3)100% (14/14)100% (3/3)
ClassTypeLibrary$TypeCategory$2 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (4/4)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (4/4)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$3100% (1/1)100% (3/3)100% (14/14)100% (3/3)
ClassTypeLibrary$TypeCategory$3 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (4/4)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (4/4)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$4100% (1/1)100% (3/3)100% (14/14)100% (3/3)
ClassTypeLibrary$TypeCategory$4 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (3/3)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$5100% (1/1)100% (3/3)100% (14/14)100% (3/3)
ClassTypeLibrary$TypeCategory$5 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (3/3)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$6100% (1/1)100% (3/3)100% (14/14)100% (3/3)
ClassTypeLibrary$TypeCategory$6 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (3/3)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$7100% (1/1)100% (3/3)100% (14/14)100% (3/3)
ClassTypeLibrary$TypeCategory$7 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (4/4)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (4/4)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$8100% (1/1)100% (3/3)100% (22/22)100% (3/3)
ClassTypeLibrary$TypeCategory$8 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (11/11)100% (1/1)
     
class ClassTypeLibrary$TypeCategory$9100% (1/1)100% (3/3)100% (22/22)100% (3/3)
ClassTypeLibrary$TypeCategory$9 (String, int): void 100% (1/1)100% (6/6)100% (1/1)
create (Class): AbstractIndirectType 100% (1/1)100% (5/5)100% (1/1)
isMember (Class): boolean 100% (1/1)100% (11/11)100% (1/1)

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.util.Collection;
22import java.util.HashMap;
23import java.util.Map;
24 
25import org.fuwjax.jon.accessor.Symbol;
26import org.fuwjax.jon.type.AbstractIndirectType;
27import org.fuwjax.jon.type.ArrayType;
28import org.fuwjax.jon.type.ByteArrayType;
29import org.fuwjax.jon.type.CharArrayType;
30import org.fuwjax.jon.type.ClassType;
31import org.fuwjax.jon.type.EnumType;
32import org.fuwjax.jon.type.ListType;
33import org.fuwjax.jon.type.MapType;
34import org.fuwjax.jon.type.NullType;
35import org.fuwjax.jon.type.ObjectType;
36import org.fuwjax.jon.type.PrimitiveType;
37import org.fuwjax.jon.type.StringType;
38import org.fuwjax.jon.type.UnknownType;
39 
40/**
41 * The default type library based on the current class hierarchy.
42 * @author michaeldoberenz
43 */
44public class ClassTypeLibrary implements IndirectTypeLibrary{
45        private Map<Class<?>, AbstractIndirectType> types;
46 
47        /**
48         * The possible categories of indirect types.
49         * @author michaeldoberenz
50         */
51        private enum TypeCategory{
52                /**
53                 * An unknown indirect type.
54                 */
55                UNKNOWN{
56                        @Override
57                        public AbstractIndirectType create(final Class<?> cls){
58                                return new UnknownType(cls);
59                        }
60 
61                        @Override
62                        public boolean isMember(final Class<?> cls){
63                                return cls == null || Object.class.equals(cls);
64                        }
65                },
66                /**
67                 * A byte array indirect type.
68                 */
69                BYTE_ARRAY{
70                        @Override
71                        public AbstractIndirectType create(final Class<?> cls){
72                                return new ByteArrayType();
73                        }
74 
75                        @Override
76                        public boolean isMember(final Class<?> cls){
77                                return byte[].class.equals(cls);
78                        }
79                },
80                /**
81                 * A char array indirect type.
82                 */
83                CHAR_ARRAY{
84                        @Override
85                        public AbstractIndirectType create(final Class<?> cls){
86                                return new CharArrayType();
87                        }
88 
89                        @Override
90                        public boolean isMember(final Class<?> cls){
91                                return char[].class.equals(cls);
92                        }
93                },
94                /**
95                 * An array indirect type.
96                 */
97                ARRAY{
98                        @Override
99                        public AbstractIndirectType create(final Class<?> cls){
100                                return new ArrayType(cls);
101                        }
102 
103                        @Override
104                        public boolean isMember(final Class<?> cls){
105                                return cls.isArray();
106                        }
107                },
108                /**
109                 * An enum indirect type.
110                 */
111                ENUM{
112                        @Override
113                        public AbstractIndirectType create(final Class<?> cls){
114                                return new EnumType(cls);
115                        }
116 
117                        @Override
118                        public boolean isMember(final Class<?> cls){
119                                return cls.isEnum();
120                        }
121                },
122                /**
123                 * A primitive indirect type.
124                 */
125                PRIMITIVE{
126                        @Override
127                        public AbstractIndirectType create(final Class<?> cls){
128                                return new PrimitiveType(cls);
129                        }
130 
131                        @Override
132                        public boolean isMember(final Class<?> cls){
133                                return PrimitiveType.isPrimitive(cls);
134                        }
135                },
136                /**
137                 * An indirect type indirect type.
138                 */
139                INDIRECT_TYPE{
140                        @Override
141                        public AbstractIndirectType create(final Class<?> cls){
142                                throw new IllegalArgumentException();
143                        }
144 
145                        @Override
146                        public boolean isMember(final Class<?> cls){
147                                return IndirectType.class.isAssignableFrom(cls);
148                        }
149                },
150                /**
151                 * A map indirect type.
152                 */
153                MAP{
154                        @Override
155                        public AbstractIndirectType create(final Class<?> cls){
156                                return new MapType(cls);
157                        }
158 
159                        @Override
160                        public boolean isMember(final Class<?> cls){
161                                return Map.class.isAssignableFrom(cls) && hasDefaultConstructor(cls);
162                        }
163                },
164                /**
165                 * A collection indirect type.
166                 */
167                LIST{
168                        @Override
169                        public AbstractIndirectType create(final Class<?> cls){
170                                return new ListType(cls);
171                        }
172 
173                        @Override
174                        public boolean isMember(final Class<?> cls){
175                                return Collection.class.isAssignableFrom(cls) && hasDefaultConstructor(cls);
176                        }
177                },
178                /**
179                 * Everything-under-the-sun indirect type.
180                 */
181                OBJECT{
182                        @Override
183                        public AbstractIndirectType create(final Class<?> cls){
184                                return new ObjectType(cls);
185                        }
186 
187                        @Override
188                        public boolean isMember(final Class<?> cls){
189                                return true;
190                        }
191                };
192                /**
193                 * Returns true if <code>cls</code> is a member of this category.
194                 * @param cls the possible member of this category
195                 * @return true if <code>cls</code> is a member of this category, false
196                 *         otherwise
197                 */
198                public abstract boolean isMember(Class<?> cls);
199 
200                /**
201                 * Returns an indirect type instance for <code>cls</code>.
202                 * @param cls the class to wrap with an indirect type
203                 * @return the indirect type for <code>cls</code>
204                 */
205                public abstract AbstractIndirectType create(Class<?> cls);
206 
207                /**
208                 * Returns true if <code>cls</code> has a default constructor.
209                 * @param cls the class
210                 * @return true if <code>cls</code> has a default constructor, false
211                 *         otherwise.
212                 */
213                static boolean hasDefaultConstructor(final Class<?> cls){
214                        try{
215                                return cls.getConstructor() != null;
216                        }catch(RuntimeException e){
217                                return false;
218                        }catch(NoSuchMethodException e){
219                                return false;
220                        }
221                }
222        }
223 
224        /**
225         * Creates a new instance.
226         */
227        public ClassTypeLibrary(){
228                ClassType.DEFAULT.setLibrary(this);
229                types = new HashMap<Class<?>, AbstractIndirectType>();
230                types.put(String.class, StringType.DEFAULT);
231                types.put(Class.class, ClassType.DEFAULT);
232        }
233 
234        public Writer createWriter(final CachedAppendable writer){
235                return new Writer(){
236                        public void write(final Object object) throws ObjectAccessException, SerialFormatException{
237                                Symbol.Element.write(writer, object, getType(null));
238                        }
239                };
240        }
241 
242        public Reader createReader(final CachedLexable lexer){
243                return new Reader(){
244                        public Object read() throws ObjectAccessException, SerialFormatException{
245                                return Symbol.Element.read(lexer, null, getType(null));
246                        }
247 
248                        public Object read(final Object object) throws ObjectAccessException, SerialFormatException{
249                                return Symbol.Element.read(lexer, object, getType(null));
250                        }
251                };
252        }
253 
254        public IndirectType getTypeFor(final Object object){
255                if(object == null){
256                        return NullType.DEFAULT;
257                }
258                return getType(object.getClass());
259        }
260 
261        public AbstractIndirectType getType(final Class<?> cls){
262                AbstractIndirectType type = types.get(cls);
263                if(type == null){
264                        type = createType(cls);
265                        types.put(cls, type);
266                        type.setLibrary(this);
267                }
268                return type;
269        }
270 
271        private AbstractIndirectType createType(final Class<?> cls){
272                for(TypeCategory category: TypeCategory.values()){
273                        if(category.isMember(cls)){
274                                return category.create(cls);
275                        }
276                }
277                throw new IllegalArgumentException();
278        }
279}

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