View Javadoc

1   //
2   // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v@@BUILD_VERSION@@ 
3   // 	See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
4   // 	Any modifications to this file will be lost upon recompilation of the source schema. 
5   // 	Generated on: 2005.06.30 um 05:21:08 CEST 
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  	 * Gets a generated implementation class for the specified root element.
38  	 * This method is used to determine the first object to be unmarshalled.
39  	 */
40  	public UnmarshallingEventHandler createUnmarshaller(String namespaceUri,
41  			String localName, UnmarshallingContext context) {
42  		// find the root element among the GrammarInfos
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  		// the element was not located in any of the grammar infos...
52  		return null;
53  	}
54  
55  	public Class getRootElement(String namespaceUri, String localName) {
56  		// find the root element among the GrammarInfos
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  		// the element was not located in any of the grammar infos...
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  	 * Return the probe points for this GrammarInfo, which are used to detect
77  	 * {namespaceURI,localName} collisions across the GrammarInfo's on the
78  	 * schemaPath. This is a slightly more complex implementation than a simple
79  	 * hashmap, but it is more flexible in supporting additional schema langs.
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  		// once per JAXBContext creation, so it may not be worth it.
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 		// the array of probe points contain uri:localname pairs
105 		for (int i = 0; i < points.length; i += 2) {
106 			// iterate over GrammarInfos - if more than one GI returns
107 			// a class from getRootElement, then there is a collision
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 	 * This static method is used to setup the GrammarInfoFacade. It is invoked
125 	 * by the DefaultJAXBContextImpl constructor
126 	 */
127 	static GrammarInfo createGrammarInfoFacade(String contextPath,
128 			ClassLoader classLoader) throws JAXBException {
129 
130 		String version = null;
131 
132 		// array of GrammarInfo objs
133 		ArrayList gis = new ArrayList();
134 
135 		StringTokenizer st = new StringTokenizer(contextPath, ":;");
136 
137 		// instantiate all of the specified JAXBContextImpls
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 				// check version
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 				// use reflection to get GrammarInfo
156 				Object grammarInfo = c.getClass().getField("grammarInfo").get(
157 						null);
158 
159 				// wrap the grammarInfo into a proxy if necessary
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 			// if there's only one path, no need to use a facade.
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 			// load al the grammars individually
221 			for (int i = 0; i < grammarInfos.length; i++)
222 				grammars[i] = grammarInfos[i].getGrammar();
223 
224 			// connect them to each other
225 			for (int i = 0; i < grammarInfos.length; i++)
226 				if (grammars[i] instanceof GrammarImpl)
227 					((GrammarImpl) grammars[i]).connect(grammars);
228 
229 			// take union of them
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 		// either g1.getPool() or g2.getPool() is OK.
247 		// this is just a metter of performance problem.
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 }