View Javadoc

1   //
2   // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.3-b18-fcs 
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: 2004.12.16 at 07:09:42 EST 
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       * Gets a generated implementation class for the specified root element.
40       * This method is used to determine the first object to be unmarshalled.
41       */
42      public UnmarshallingEventHandler createUnmarshaller(String namespaceUri, String localName, UnmarshallingContext context) {
43          // find the root element among the GrammarInfos
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          // 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.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         // 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( 
115                                 Messages.format( Messages.COLLISION_DETECTED,
116                                         points[i], points[i+1] ) );
117                     }
118                 }
119             }
120         }
121     }
122        
123     /*
124      * This static method is used to setup the GrammarInfoFacade.  It 
125      * is invoked by the DefaultJAXBContextImpl constructor
126      */
127     static GrammarInfo createGrammarInfoFacade( String contextPath, 
128                                                 ClassLoader classLoader ) 
129         throws JAXBException {
130             
131         String version=null;
132         
133         // array of GrammarInfo objs
134         ArrayList gis = new ArrayList();
135 
136         StringTokenizer st = new StringTokenizer( contextPath, ":;" );
137 
138         // instantiate all of the specified JAXBContextImpls
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                 // check version
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                 // use reflection to get GrammarInfo
158                 Object grammarInfo = c.getClass().getField("grammarInfo").get(null);
159                
160                 // wrap the grammarInfo into a proxy if necessary
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             // if there's only one path, no need to use a facade.
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             // load al the grammars individually
223             for( int i=0; i<grammarInfos.length; i++ )
224                 grammars[i] = grammarInfos[i].getGrammar();
225             
226             // connect them to each other
227             for( int i=0; i<grammarInfos.length; i++ )
228                 if( grammars[i] instanceof GrammarImpl )
229                     ((GrammarImpl)grammars[i]).connect(grammars);
230             
231             // take union of them
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         // 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.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 }