1
2
3
4
5
6
7
8 package de.nierbeck.timeTrack.model.impl.runtime;
9
10 import java.util.ArrayList;
11 import java.util.StringTokenizer;
12
13 import javax.xml.bind.JAXBContext;
14 import javax.xml.bind.JAXBException;
15
16 import com.sun.xml.bind.GrammarImpl;
17 import com.sun.xml.bind.Messages;
18 import com.sun.xml.bind.ProxyGroup;
19
20 /***
21 * This class is a facade to a collection of GrammarInfo objects. It dispatches
22 * rootElement requests to the underlying GrammarInfo objects.
23 *
24 * @version $Revision: 1.3 $
25 */
26 class GrammarInfoFacade implements GrammarInfo {
27
28 private GrammarInfo[] grammarInfos = null;
29
30 public GrammarInfoFacade(GrammarInfo[] items) throws JAXBException {
31 grammarInfos = items;
32
33 detectRootElementCollisions(getProbePoints());
34 }
35
36
37
38
39
40 public UnmarshallingEventHandler createUnmarshaller(String namespaceUri,
41 String localName, UnmarshallingContext context) {
42
43 for (int i = 0; i < grammarInfos.length; i++) {
44 UnmarshallingEventHandler ueh = grammarInfos[i].createUnmarshaller(
45 namespaceUri, localName, context);
46 if (ueh != null) {
47 return ueh;
48 }
49 }
50
51
52 return null;
53 }
54
55 public Class getRootElement(String namespaceUri, String localName) {
56
57 for (int i = 0; i < grammarInfos.length; i++) {
58 Class c = grammarInfos[i].getRootElement(namespaceUri, localName);
59 if (c != null) {
60 return c;
61 }
62 }
63
64
65 return null;
66 }
67
68 public boolean recognize(String nsUri, String localName) {
69 for (int i = 0; i < grammarInfos.length; i++)
70 if (grammarInfos[i].recognize(nsUri, localName))
71 return true;
72 return false;
73 }
74
75
76
77
78
79
80
81 public String[] getProbePoints() {
82 ArrayList probePointList = new ArrayList();
83
84 for (int i = 0; i < grammarInfos.length; i++) {
85 String[] points = grammarInfos[i].getProbePoints();
86 for (int j = 0; j < points.length; j++) {
87 probePointList.add(points[j]);
88 }
89 }
90
91
92 return (String[]) probePointList.toArray(new String[probePointList
93 .size()]);
94 }
95
96 /***
97 * Iterate through the probe points looking for root element collisions. If
98 * a duplicate is detected, then multiple root element componenets exist
99 * with the same uri:localname
100 */
101 private void detectRootElementCollisions(String[] points)
102 throws JAXBException {
103
104
105 for (int i = 0; i < points.length; i += 2) {
106
107
108 boolean elementFound = false;
109 for (int j = grammarInfos.length - 1; j >= 0; j--) {
110 if (grammarInfos[j].recognize(points[i], points[i + 1])) {
111 if (elementFound == false) {
112 elementFound = true;
113 } else {
114 throw new JAXBException(Messages.format(
115 Messages.COLLISION_DETECTED, points[i],
116 points[i + 1]));
117 }
118 }
119 }
120 }
121 }
122
123
124
125
126
127 static GrammarInfo createGrammarInfoFacade(String contextPath,
128 ClassLoader classLoader) throws JAXBException {
129
130 String version = null;
131
132
133 ArrayList gis = new ArrayList();
134
135 StringTokenizer st = new StringTokenizer(contextPath, ":;");
136
137
138 while (st.hasMoreTokens()) {
139 String targetPackage = st.nextToken();
140 String objectFactoryName = targetPackage + ".ObjectFactory";
141
142 try {
143 JAXBContext c = (JAXBContext) Class.forName(objectFactoryName,
144 true, classLoader).newInstance();
145
146
147 if (version == null)
148 version = getVersion(c);
149 else if (!version.equals(getVersion(c)))
150 throw new JAXBException(Messages.format(
151 Messages.INCOMPATIBLE_VERSION, new Object[] {
152 version, c.getClass().getName(),
153 getVersion(c) }));
154
155
156 Object grammarInfo = c.getClass().getField("grammarInfo").get(
157 null);
158
159
160 grammarInfo = ProxyGroup.blindWrap(grammarInfo,
161 GrammarInfo.class, new Class[] { GrammarInfo.class,
162 UnmarshallingContext.class,
163 UnmarshallingEventHandler.class,
164 XMLSerializer.class, XMLSerializable.class,
165 NamespaceContext2.class,
166 ValidatableObject.class });
167
168 gis.add(grammarInfo);
169 } catch (ClassNotFoundException e) {
170 throw new NoClassDefFoundError(e.getMessage());
171 } catch (Exception e) {
172 throw new JAXBException(e);
173 }
174 }
175
176 if (gis.size() == 1)
177
178 return (GrammarInfo) gis.get(0);
179
180 return new GrammarInfoFacade((GrammarInfo[]) (gis
181 .toArray(new GrammarInfo[gis.size()])));
182 }
183
184 /***
185 * Obtains a version number of the JAXB RI that has generated the specified
186 * context, or null if it fails (for example because it's not generated by
187 * JAXB RI.)
188 *
189 * @param c
190 * an instance of a generated ObjectFactory class. This will
191 * return the version number written into the corresponding
192 * JAXBVersion class.
193 */
194 private static String getVersion(JAXBContext c) throws JAXBException {
195 try {
196 Class jaxbBersionClass = (Class) c.getClass().getField("version")
197 .get(null);
198 return (String) jaxbBersionClass.getField("version").get(null);
199 } catch (Throwable t) {
200 return null;
201 }
202 }
203
204 public Class getDefaultImplementation(Class javaContentInterface) {
205 for (int i = 0; i < grammarInfos.length; i++) {
206 Class c = grammarInfos[i]
207 .getDefaultImplementation(javaContentInterface);
208 if (c != null)
209 return c;
210 }
211 return null;
212 }
213
214 private com.sun.msv.grammar.Grammar bgm = null;
215
216 public com.sun.msv.grammar.Grammar getGrammar() throws JAXBException {
217 if (bgm == null) {
218 com.sun.msv.grammar.Grammar[] grammars = new com.sun.msv.grammar.Grammar[grammarInfos.length];
219
220
221 for (int i = 0; i < grammarInfos.length; i++)
222 grammars[i] = grammarInfos[i].getGrammar();
223
224
225 for (int i = 0; i < grammarInfos.length; i++)
226 if (grammars[i] instanceof GrammarImpl)
227 ((GrammarImpl) grammars[i]).connect(grammars);
228
229
230 for (int i = 0; i < grammarInfos.length; i++) {
231 com.sun.msv.grammar.Grammar n = grammars[i];
232 if (bgm == null)
233 bgm = n;
234 else
235 bgm = union(bgm, n);
236 }
237 }
238 return bgm;
239 }
240
241 /***
242 * Computes the union of two grammars.
243 */
244 private com.sun.msv.grammar.Grammar union(com.sun.msv.grammar.Grammar g1,
245 com.sun.msv.grammar.Grammar g2) {
246
247
248 final com.sun.msv.grammar.ExpressionPool pool = g1.getPool();
249 final com.sun.msv.grammar.Expression top = pool.createChoice(g1
250 .getTopLevel(), g2.getTopLevel());
251
252 return new com.sun.msv.grammar.Grammar() {
253 public com.sun.msv.grammar.ExpressionPool getPool() {
254 return pool;
255 }
256
257 public com.sun.msv.grammar.Expression getTopLevel() {
258 return top;
259 }
260 };
261 }
262
263 /***
264 * @see com.sun.tools.xjc.runtime.GrammarInfo#castToXMLSerializable(java.lang.Object)
265 */
266 public XMLSerializable castToXMLSerializable(Object o) {
267 XMLSerializable result = null;
268 for (int i = 0; i < grammarInfos.length; i++) {
269 result = grammarInfos[i].castToXMLSerializable(o);
270 if (result != null) {
271 return result;
272 }
273 }
274 return null;
275 }
276
277 /***
278 * @see com.sun.tools.xjc.runtime.GrammarInfo#castToValidatableObject(java.lang.Object)
279 */
280 public ValidatableObject castToValidatableObject(Object o) {
281 ValidatableObject result = null;
282 for (int i = 0; i < grammarInfos.length; i++) {
283 result = grammarInfos[i].castToValidatableObject(o);
284 if (result != null) {
285 return result;
286 }
287 }
288 return null;
289 }
290 }