1
2
3
4
5
6
7
8 package net.sf.jour.config.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
22 * dispatches rootElement requests to the underlying GrammarInfo objects.
23 *
24 * @version $Revision: 1.14.4.1 $
25 */
26 class GrammarInfoFacade implements GrammarInfo {
27
28 private GrammarInfo[] grammarInfos = null;
29
30
31
32 public GrammarInfoFacade( GrammarInfo[] items ) throws JAXBException {
33 grammarInfos = items;
34
35 detectRootElementCollisions( getProbePoints() );
36 }
37
38
39
40
41
42 public UnmarshallingEventHandler createUnmarshaller(String namespaceUri, String localName, UnmarshallingContext context) {
43
44 for( int i = 0; i < grammarInfos.length; i++ ) {
45 UnmarshallingEventHandler ueh = grammarInfos[i].createUnmarshaller( 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.size() ] );
93 }
94
95
96 /***
97 * Iterate through the probe points looking for root element collisions.
98 * If a duplicate is detected, then multiple root element componenets
99 * exist 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(
115 Messages.format( Messages.COLLISION_DETECTED,
116 points[i], points[i+1] ) );
117 }
118 }
119 }
120 }
121 }
122
123
124
125
126
127 static GrammarInfo createGrammarInfoFacade( String contextPath,
128 ClassLoader classLoader )
129 throws JAXBException {
130
131 String version=null;
132
133
134 ArrayList gis = new ArrayList();
135
136 StringTokenizer st = new StringTokenizer( contextPath, ":;" );
137
138
139 while( st.hasMoreTokens() ) {
140 String targetPackage = st.nextToken();
141 String objectFactoryName = targetPackage + ".ObjectFactory";
142
143 try {
144 JAXBContext c = (JAXBContext)Class.forName(
145 objectFactoryName, true, classLoader ).newInstance();
146
147
148 if( version==null ) version = getVersion(c);
149 else
150 if( !version.equals(getVersion(c)) )
151 throw new JAXBException( Messages.format(
152 Messages.INCOMPATIBLE_VERSION, new Object[]{
153 version,
154 c.getClass().getName(),
155 getVersion(c) } ) );
156
157
158 Object grammarInfo = c.getClass().getField("grammarInfo").get(null);
159
160
161 grammarInfo = ProxyGroup.blindWrap(
162 grammarInfo, GrammarInfo.class,
163 new Class[]{
164 GrammarInfo.class,
165 UnmarshallingContext.class,
166 UnmarshallingEventHandler.class,
167 XMLSerializer.class,
168 XMLSerializable.class,
169 NamespaceContext2.class,
170 ValidatableObject.class
171 } );
172
173 gis.add( grammarInfo );
174 } catch( ClassNotFoundException e ) {
175 throw new NoClassDefFoundError(e.getMessage());
176 } catch( Exception e ) {
177 throw new JAXBException(e);
178 }
179 }
180
181 if( gis.size()==1 )
182
183 return (GrammarInfo)gis.get(0);
184
185 return new GrammarInfoFacade(
186 (GrammarInfo[])(gis.toArray( new GrammarInfo[ gis.size() ] ) ) );
187 }
188
189 /***
190 * Obtains a version number of the JAXB RI that has generated
191 * the specified context, or null if it fails (for example
192 * because it's not generated by JAXB RI.)
193 *
194 * @param c
195 * an instance of a generated ObjectFactory class.
196 * This will return the version number written into
197 * the corresponding JAXBVersion class.
198 */
199 private static String getVersion(JAXBContext c) throws JAXBException {
200 try {
201 Class jaxbBersionClass = (Class)c.getClass().getField("version").get(null);
202 return (String)jaxbBersionClass.getField("version").get(null);
203 } catch( Throwable t ) {
204 return null;
205 }
206 }
207
208 public Class getDefaultImplementation( Class javaContentInterface ) {
209 for( int i=0; i<grammarInfos.length; i++ ) {
210 Class c = grammarInfos[i].getDefaultImplementation( javaContentInterface );
211 if(c!=null) return c;
212 }
213 return null;
214 }
215
216 private com.sun.msv.grammar.Grammar bgm = null;
217
218 public com.sun.msv.grammar.Grammar getGrammar() throws JAXBException {
219 if(bgm==null) {
220 com.sun.msv.grammar.Grammar[] grammars = new com.sun.msv.grammar.Grammar[grammarInfos.length];
221
222
223 for( int i=0; i<grammarInfos.length; i++ )
224 grammars[i] = grammarInfos[i].getGrammar();
225
226
227 for( int i=0; i<grammarInfos.length; i++ )
228 if( grammars[i] instanceof GrammarImpl )
229 ((GrammarImpl)grammars[i]).connect(grammars);
230
231
232 for( int i=0; i<grammarInfos.length; i++ ) {
233 com.sun.msv.grammar.Grammar n = grammars[i];
234 if( bgm == null ) bgm = n;
235 else bgm = union( bgm, n );
236 }
237 }
238 return bgm;
239 }
240
241
242 /***
243 * Computes the union of two grammars.
244 */
245 private com.sun.msv.grammar.Grammar union( com.sun.msv.grammar.Grammar g1, 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.getTopLevel(),g2.getTopLevel());
250
251 return new com.sun.msv.grammar.Grammar() {
252 public com.sun.msv.grammar.ExpressionPool getPool() {
253 return pool;
254 }
255 public com.sun.msv.grammar.Expression getTopLevel() {
256 return top;
257 }
258 };
259 }
260
261
262 /***
263 * @see com.sun.tools.xjc.runtime.GrammarInfo#castToXMLSerializable(java.lang.Object)
264 */
265 public XMLSerializable castToXMLSerializable(Object o) {
266 XMLSerializable result = null;
267 for( int i = 0; i < grammarInfos.length; i++ ) {
268 result = grammarInfos[i].castToXMLSerializable( o );
269 if( result != null ) {
270 return result;
271 }
272 }
273 return null;
274 }
275
276 /***
277 * @see com.sun.tools.xjc.runtime.GrammarInfo#castToValidatableObject(java.lang.Object)
278 */
279 public ValidatableObject castToValidatableObject(Object o) {
280 ValidatableObject result = null;
281 for( int i = 0; i < grammarInfos.length; i++ ) {
282 result = grammarInfos[i].castToValidatableObject( o );
283 if( result != null ) {
284 return result;
285 }
286 }
287 return null;
288 }
289 }