1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.rblasch.convert.type;
17
18 import org.rblasch.convert.assertion.Assertion;
19
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 /***
29 * @author Ronald Blaschke
30 */
31 public class Types {
32
33 private static Map
34
35 private static boolean isKnown(final Object key) {
36 return types.containsKey(key);
37 }
38
39 private static void makeKnown(final Object key, final Type t) {
40 Type knownT = null;
41 if (types.containsValue(t)) {
42 for (final Iterator i = types.values().iterator(); i.hasNext();) {
43 final Type ti = (Type) i.next();
44 if (t.equals(ti)) {
45 knownT = ti;
46 }
47 }
48 } else {
49 knownT = t;
50 }
51 Assertion.ensure(knownT != null, "Known type must not be null");
52
53 types.put(key, knownT);
54 }
55
56 private static Type knownType(final Object key) {
57 if (isKnown(key)) {
58 return (Type) types.get(key);
59 } else {
60 throw new UnknownTypeException(key + " is not a known type");
61 }
62 }
63
64 public static Type findTypeByName(final String name) throws UnknownTypeException {
65 return findType(name);
66 }
67
68 public static Type primitiveArrayType() {
69 return ArrayType.getInstance();
70 }
71
72 public static Type nullType() {
73 return NullType.getInstance();
74 }
75
76 public static Type findPrimitiveType(final Class c) {
77 return new PrimitiveType(c);
78 }
79
80 public static Type findTypeByClass(final Class c) {
81 return findType(c);
82 }
83
84 public static Type findPTypeByName(final String t, final String p1) throws UnknownTypeException {
85 return findPType(t, Collections.singletonList(p1));
86 }
87
88 public static Type findPTypeByClass(final Class c, final Class p1) throws UnknownTypeException {
89 return findPType(c, Collections.singletonList(p1));
90 }
91
92 public static Type findPTypeByType(final Type t, final Type p1) throws UnknownTypeException {
93 return findPType(t, Collections.singletonList(p1));
94 }
95
96 public static ParameterizableType findPTypeByType(final Type t, final List
97 return findPType(t, parameters);
98 }
99
100 private static ParameterizableType findPType(final Object type, final List
101 final List
102 request.add(type);
103 request.addAll(parameters);
104 if (isKnown(request)) {
105 return (ParameterizableType) knownType(request);
106 } else {
107 final ParameterizableType t = findPTypeInternal(type, parameters);
108 makeKnown(request, t);
109 return t;
110 }
111 }
112
113 private static Type findType(final Object type) throws UnknownTypeException {
114 if (isKnown(type)) {
115 return knownType(type);
116 } else {
117 final Type t = findTypeInternal(type);
118 makeKnown(type, t);
119 return t;
120 }
121 }
122
123 private static Type findTypeInternal(final Object t) throws UnknownTypeException {
124 if (t instanceof Type) {
125 return (Type) t;
126 } else if (t instanceof String) {
127 return findTypeInternal((String) t);
128 } else if (t instanceof Class) {
129 return findTypeInternal((Class) t);
130 } else {
131 throw new UnknownTypeException("Don't know how to resolve type " + t + " (" + t.getClass() + ")");
132 }
133 }
134
135 private static Type findTypeInternal(final String name) throws UnknownTypeException {
136 if ("any".equals(name)) {
137 return AnyType.getInstance();
138 } else if ("array".equals(name)) {
139 return ArrayType.getInstance();
140 } else {
141 try {
142 return PrimitiveType.valueOf(name);
143 } catch (final UnknownTypeException ex) {
144 try {
145 return ClassType.valueOf(name);
146 } catch (final UnknownTypeException ex2) {
147 try {
148 return ParameterizableType.valueOf(name);
149 } catch (final UnknownTypeException ex3) {
150 throw new UnknownTypeException(name + " is not a known type");
151 }
152 }
153 }
154 }
155 }
156
157 private static Type findTypeInternal(final Class c) throws UnknownTypeException {
158 if (c.isPrimitive()) {
159 return new PrimitiveType(c);
160 } else if (c.isArray()) {
161 return new ParameterizableType(ArrayType.getInstance(),
162 Arrays.asList(new Type[]{findTypeByClass(c.getComponentType())}));
163 } else {
164 return new ClassType(c);
165 }
166 }
167
168 private static ParameterizableType findPTypeInternal(final Object t, final List
169 final List
170 for (final Iterator i = parameters.iterator(); i.hasNext();) {
171 l.add(findType(i.next()));
172 }
173 return new ParameterizableType(findType(t), l);
174 }
175 }