1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  package org.jomc.modlet;
32  
33  import java.io.BufferedReader;
34  import java.io.File;
35  import java.io.FileInputStream;
36  import java.io.IOException;
37  import java.io.InputStream;
38  import java.io.InputStreamReader;
39  import java.io.Reader;
40  import java.lang.reflect.UndeclaredThrowableException;
41  import java.net.URI;
42  import java.net.URISyntaxException;
43  import java.net.URL;
44  import java.text.MessageFormat;
45  import java.util.ArrayList;
46  import java.util.Collection;
47  import java.util.Collections;
48  import java.util.Comparator;
49  import java.util.Enumeration;
50  import java.util.HashSet;
51  import java.util.LinkedList;
52  import java.util.List;
53  import java.util.Map;
54  import java.util.ResourceBundle;
55  import java.util.Set;
56  import java.util.StringTokenizer;
57  import java.util.TreeMap;
58  import java.util.concurrent.Callable;
59  import java.util.concurrent.CancellationException;
60  import java.util.concurrent.CopyOnWriteArrayList;
61  import java.util.concurrent.ExecutionException;
62  import java.util.concurrent.Future;
63  import java.util.jar.Attributes;
64  import java.util.jar.Manifest;
65  import java.util.logging.Level;
66  import javax.xml.XMLConstants;
67  import javax.xml.bind.JAXBContext;
68  import javax.xml.bind.JAXBException;
69  import javax.xml.bind.Marshaller;
70  import javax.xml.bind.Unmarshaller;
71  import javax.xml.transform.Source;
72  import javax.xml.transform.sax.SAXSource;
73  import javax.xml.validation.SchemaFactory;
74  import javax.xml.validation.Validator;
75  import org.w3c.dom.ls.LSInput;
76  import org.w3c.dom.ls.LSResourceResolver;
77  import org.xml.sax.EntityResolver;
78  import org.xml.sax.ErrorHandler;
79  import org.xml.sax.InputSource;
80  import org.xml.sax.SAXException;
81  import org.xml.sax.SAXParseException;
82  import org.xml.sax.helpers.DefaultHandler;
83  
84  
85  
86  
87  
88  
89  
90  
91  public class DefaultModelContext extends ModelContext
92  {
93  
94      
95  
96  
97  
98  
99  
100 
101     public static final String PROVIDER_LOCATION_ATTRIBUTE_NAME =
102         "org.jomc.modlet.DefaultModelContext.providerLocationAttribute";
103 
104     
105 
106 
107 
108 
109 
110 
111     public static final String PLATFORM_PROVIDER_LOCATION_ATTRIBUTE_NAME =
112         "org.jomc.modlet.DefaultModelContext.platformProviderLocationAttribute";
113 
114     
115 
116 
117     private static final String[] SCHEMA_EXTENSIONS = new String[]
118     {
119         "xsd"
120     };
121 
122     
123 
124 
125 
126 
127     private static final String DEFAULT_PROVIDER_LOCATION = "META-INF/services";
128 
129     
130 
131 
132 
133 
134     private static final String DEFAULT_PLATFORM_PROVIDER_LOCATION =
135         new StringBuilder( 255 ).append( System.getProperty( "java.home" ) ).append( File.separator ).append( "lib" ).
136         append( File.separator ).append( "jomc.properties" ).toString();
137 
138     
139 
140 
141 
142 
143     private static final String MARSHALLER_LISTENER_SERVICE = "javax.xml.bind.Marshaller.Listener";
144 
145     
146 
147 
148 
149 
150     private static final String UNMARSHALLER_LISTENER_SERVICE = "javax.xml.bind.Unmarshaller.Listener";
151 
152     
153 
154 
155     private static volatile String defaultProviderLocation;
156 
157     
158 
159 
160     private static volatile String defaultPlatformProviderLocation;
161 
162     
163 
164 
165     private volatile String providerLocation;
166 
167     
168 
169 
170     private volatile String platformProviderLocation;
171 
172     
173 
174 
175 
176 
177     public DefaultModelContext()
178     {
179         super();
180     }
181 
182     
183 
184 
185 
186 
187     public DefaultModelContext( final ClassLoader classLoader )
188     {
189         super( classLoader );
190     }
191 
192     
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205     public static String getDefaultProviderLocation()
206     {
207         if ( defaultProviderLocation == null )
208         {
209             defaultProviderLocation = System.getProperty(
210                 "org.jomc.modlet.DefaultModelContext.defaultProviderLocation", DEFAULT_PROVIDER_LOCATION );
211 
212         }
213 
214         return defaultProviderLocation;
215     }
216 
217     
218 
219 
220 
221 
222 
223 
224     public static void setDefaultProviderLocation( final String value )
225     {
226         defaultProviderLocation = value;
227     }
228 
229     
230 
231 
232 
233 
234 
235 
236 
237 
238     public final String getProviderLocation()
239     {
240         String location = this.providerLocation;
241 
242         if ( this.providerLocation == null )
243         {
244             this.providerLocation = getDefaultProviderLocation();
245             location = this.providerLocation;
246 
247             if ( this.isLoggable( Level.CONFIG ) )
248             {
249                 this.log( Level.CONFIG, getMessage( "defaultProviderLocationInfo", location ), null );
250             }
251         }
252 
253         if ( this.getAttribute( PROVIDER_LOCATION_ATTRIBUTE_NAME ) instanceof String )
254         {
255             location = (String) this.getAttribute( PROVIDER_LOCATION_ATTRIBUTE_NAME );
256 
257             if ( this.isLoggable( Level.CONFIG ) )
258             {
259                 this.log( Level.CONFIG, getMessage( "contextProviderLocationInfo", location ), null );
260             }
261         }
262 
263         return location;
264     }
265 
266     
267 
268 
269 
270 
271 
272 
273     public final void setProviderLocation( final String value )
274     {
275         this.providerLocation = value;
276     }
277 
278     
279 
280 
281 
282 
283 
284 
285 
286 
287 
288 
289 
290 
291     public static String getDefaultPlatformProviderLocation()
292     {
293         if ( defaultPlatformProviderLocation == null )
294         {
295             defaultPlatformProviderLocation = System.getProperty(
296                 "org.jomc.modlet.DefaultModelContext.defaultPlatformProviderLocation",
297                 DEFAULT_PLATFORM_PROVIDER_LOCATION );
298 
299         }
300 
301         return defaultPlatformProviderLocation;
302     }
303 
304     
305 
306 
307 
308 
309 
310 
311     public static void setDefaultPlatformProviderLocation( final String value )
312     {
313         defaultPlatformProviderLocation = value;
314     }
315 
316     
317 
318 
319 
320 
321 
322 
323 
324 
325     public final String getPlatformProviderLocation()
326     {
327         String location = this.platformProviderLocation;
328 
329         if ( this.platformProviderLocation == null )
330         {
331             this.platformProviderLocation = getDefaultPlatformProviderLocation();
332             location = this.platformProviderLocation;
333 
334             if ( this.isLoggable( Level.CONFIG ) )
335             {
336                 this.log( Level.CONFIG, getMessage( "defaultPlatformProviderLocationInfo", location ), null );
337             }
338         }
339 
340         if ( this.getAttribute( PLATFORM_PROVIDER_LOCATION_ATTRIBUTE_NAME ) instanceof String )
341         {
342             location = (String) this.getAttribute( PLATFORM_PROVIDER_LOCATION_ATTRIBUTE_NAME );
343 
344             if ( this.isLoggable( Level.CONFIG ) )
345             {
346                 this.log( Level.CONFIG, getMessage( "contextPlatformProviderLocationInfo", location ), null );
347             }
348         }
349 
350         return location;
351     }
352 
353     
354 
355 
356 
357 
358 
359 
360     public final void setPlatformProviderLocation( final String value )
361     {
362         this.platformProviderLocation = value;
363     }
364 
365     
366 
367 
368 
369 
370 
371 
372 
373 
374 
375 
376 
377 
378     @Override
379     @Deprecated
380     public Modlets findModlets() throws ModelException
381     {
382         return this.findModlets( new Modlets() );
383     }
384 
385     
386 
387 
388 
389 
390 
391 
392 
393 
394 
395 
396 
397     @Override
398     public Modlets findModlets( final Modlets modlets ) throws ModelException
399     {
400         if ( modlets == null )
401         {
402             throw new NullPointerException( "modlets" );
403         }
404 
405         Modlets found = modlets.clone();
406         final Collection<ModletProvider> providers = this.loadModletServices( ModletProvider.class );
407 
408         for ( final ModletProvider provider : providers )
409         {
410             if ( this.isLoggable( Level.FINER ) )
411             {
412                 this.log( Level.FINER, getMessage( "creatingModlets", provider.toString() ), null );
413             }
414 
415             final Modlets provided = provider.findModlets( this, found );
416 
417             if ( provided != null )
418             {
419                 found = provided;
420             }
421         }
422 
423         if ( this.isLoggable( Level.FINEST ) )
424         {
425             for ( final Modlet m : found.getModlet() )
426             {
427                 this.log( Level.FINEST,
428                           getMessage( "modletInfo", m.getName(), m.getModel(),
429                                       m.getVendor() != null
430                                           ? m.getVendor() : getMessage( "noVendor" ),
431                                       m.getVersion() != null
432                                           ? m.getVersion() : getMessage( "noVersion" ) ), null );
433 
434                 if ( m.getSchemas() != null )
435                 {
436                     for ( final Schema s : m.getSchemas().getSchema() )
437                     {
438                         this.log( Level.FINEST,
439                                   getMessage( "modletSchemaInfo", m.getName(), s.getPublicId(), s.getSystemId(),
440                                               s.getContextId() != null
441                                                   ? s.getContextId() : getMessage( "noContext" ),
442                                               s.getClasspathId() != null
443                                                   ? s.getClasspathId() : getMessage( "noClasspathId" ) ), null );
444 
445                     }
446                 }
447 
448                 if ( m.getServices() != null )
449                 {
450                     for ( final Service s : m.getServices().getService() )
451                     {
452                         this.log( Level.FINEST, getMessage( "modletServiceInfo", m.getName(), s.getOrdinal(),
453                                                             s.getIdentifier(), s.getClazz() ), null );
454 
455                     }
456                 }
457             }
458         }
459 
460         return found;
461     }
462 
463     
464 
465 
466 
467 
468 
469 
470 
471 
472 
473 
474 
475     @Override
476     public Modlets processModlets( final Modlets modlets ) throws ModelException
477     {
478         if ( modlets == null )
479         {
480             throw new NullPointerException( "modlets" );
481         }
482 
483         Modlets result = modlets.clone();
484         final Collection<ModletProcessor> processors = this.loadModletServices( ModletProcessor.class );
485 
486         for ( final ModletProcessor processor : processors )
487         {
488             if ( this.isLoggable( Level.FINER ) )
489             {
490                 this.log( Level.FINER, getMessage( "processingModlets", processor.toString() ), null );
491             }
492 
493             final Modlets processed = processor.processModlets( this, result );
494 
495             if ( processed != null )
496             {
497                 result = processed;
498             }
499         }
500 
501         return result;
502     }
503 
504     
505 
506 
507 
508 
509 
510 
511 
512 
513 
514 
515 
516     @Override
517     public ModelValidationReport validateModlets( final Modlets modlets ) throws ModelException
518     {
519         if ( modlets == null )
520         {
521             throw new NullPointerException( "modlets" );
522         }
523 
524         final ModelValidationReport report = new ModelValidationReport();
525 
526         for ( final ModletValidator modletValidator
527                   : this.loadModletServices( ModletValidator.class ) )
528         {
529             if ( this.isLoggable( Level.FINER ) )
530             {
531                 this.log( Level.FINER, getMessage( "validatingModlets", modletValidator.toString() ), null );
532             }
533 
534             final ModelValidationReport current = modletValidator.validateModlets( this, modlets );
535 
536             if ( current != null )
537             {
538                 report.getDetails().addAll( current.getDetails() );
539             }
540         }
541 
542         return report;
543     }
544 
545     
546 
547 
548 
549 
550 
551 
552 
553 
554 
555 
556     @Override
557     public Model findModel( final String model ) throws ModelException
558     {
559         if ( model == null )
560         {
561             throw new NullPointerException( "model" );
562         }
563 
564         final Model m = new Model();
565         m.setIdentifier( model );
566 
567         return this.findModel( m );
568     }
569 
570     
571 
572 
573 
574 
575 
576 
577 
578 
579 
580 
581 
582     @Override
583     public Model findModel( final Model model ) throws ModelException
584     {
585         if ( model == null )
586         {
587             throw new NullPointerException( "model" );
588         }
589 
590         Model m = model.clone();
591         final long t0 = System.nanoTime();
592 
593         for ( final ModelProvider provider
594                   : this.createServiceObjects( model.getIdentifier(), ModelProvider.class.getName(),
595                                                ModelProvider.class ) )
596         {
597             if ( this.isLoggable( Level.FINER ) )
598             {
599                 this.log( Level.FINER, getMessage( "creatingModel", m.getIdentifier(), provider.toString() ), null );
600             }
601 
602             final Model provided = provider.findModel( this, m );
603 
604             if ( provided != null )
605             {
606                 m = provided;
607             }
608         }
609 
610         if ( this.isLoggable( Level.FINE ) )
611         {
612             this.log( Level.FINE, getMessage( "findModelReport", m.getIdentifier(), System.nanoTime() - t0 ), null );
613         }
614 
615         return m;
616     }
617 
618     
619 
620 
621 
622 
623 
624 
625 
626 
627 
628     @Override
629     public Model processModel( final Model model ) throws ModelException
630     {
631         if ( model == null )
632         {
633             throw new NullPointerException( "model" );
634         }
635 
636         Model processed = model;
637         final long t0 = System.nanoTime();
638 
639         for ( final ModelProcessor processor
640                   : this.createServiceObjects( model.getIdentifier(), ModelProcessor.class.getName(),
641                                                ModelProcessor.class ) )
642         {
643             if ( this.isLoggable( Level.FINER ) )
644             {
645                 this.log( Level.FINER, getMessage( "processingModel", model.getIdentifier(),
646                                                    processor.toString() ), null );
647 
648             }
649 
650             final Model current = processor.processModel( this, processed );
651 
652             if ( current != null )
653             {
654                 processed = current;
655             }
656         }
657 
658         if ( this.isLoggable( Level.FINE ) )
659         {
660             this.log( Level.FINE, getMessage( "processModelReport", model.getIdentifier(), System.nanoTime() - t0 ),
661                       null );
662 
663         }
664 
665         return processed;
666     }
667 
668     
669 
670 
671 
672 
673 
674 
675 
676 
677 
678     @Override
679     public ModelValidationReport validateModel( final Model model ) throws ModelException
680     {
681         if ( model == null )
682         {
683             throw new NullPointerException( "model" );
684         }
685 
686         try
687         {
688             final long t0 = System.nanoTime();
689             final ModelValidationReport resultReport = new ModelValidationReport();
690 
691             final Collection<? extends ModelValidator> modelValidators =
692                 this.createServiceObjects( model.getIdentifier(), ModelValidator.class.getName(),
693                                            ModelValidator.class );
694 
695             if ( this.getExecutorService() != null && modelValidators.size() > 1 )
696             {
697                 final List<Callable<ModelValidationReport>> tasks =
698                     new ArrayList<Callable<ModelValidationReport>>( modelValidators.size() );
699 
700                 for ( final ModelValidator validator : modelValidators )
701                 {
702                     tasks.add( new Callable<ModelValidationReport>()
703                     {
704 
705                         public ModelValidationReport call() throws ModelException
706                         {
707                             if ( isLoggable( Level.FINER ) )
708                             {
709                                 log( Level.FINER, getMessage( "validatingModel", model.getIdentifier(),
710                                                               validator.toString() ), null );
711 
712                             }
713 
714                             return validator.validateModel( DefaultModelContext.this, model );
715                         }
716 
717                     } );
718 
719                 }
720 
721                 for ( final Future<ModelValidationReport> task : this.getExecutorService().invokeAll( tasks ) )
722                 {
723                     final ModelValidationReport currentReport = task.get();
724 
725                     if ( currentReport != null )
726                     {
727                         resultReport.getDetails().addAll( currentReport.getDetails() );
728                     }
729                 }
730             }
731             else
732             {
733                 for ( final ModelValidator modelValidator : modelValidators )
734                 {
735                     final ModelValidationReport currentReport = modelValidator.validateModel( this, model );
736 
737                     if ( currentReport != null )
738                     {
739                         resultReport.getDetails().addAll( currentReport.getDetails() );
740                     }
741                 }
742             }
743 
744             if ( this.isLoggable( Level.FINE ) )
745             {
746                 this.log( Level.FINE, getMessage( "validateModelReport", model.getIdentifier(),
747                                                   System.nanoTime() - t0 ), null );
748 
749             }
750 
751             return resultReport;
752         }
753         catch ( final CancellationException e )
754         {
755             throw new ModelException( getMessage( "failedValidatingModel", model.getIdentifier() ), e );
756         }
757         catch ( final InterruptedException e )
758         {
759             throw new ModelException( getMessage( "failedValidatingModel", model.getIdentifier() ), e );
760         }
761         catch ( final ExecutionException e )
762         {
763             if ( e.getCause() instanceof ModelException )
764             {
765                 throw (ModelException) e.getCause();
766             }
767             else if ( e.getCause() instanceof RuntimeException )
768             {
769                 
770                 
771                 if ( e.getCause().getCause() instanceof ModelException )
772                 {
773                     throw (ModelException) e.getCause().getCause();
774                 }
775                 else if ( e.getCause().getCause() instanceof RuntimeException )
776                 {
777                     throw (RuntimeException) e.getCause().getCause();
778                 }
779                 else if ( e.getCause().getCause() instanceof Error )
780                 {
781                     throw (Error) e.getCause().getCause();
782                 }
783                 else if ( e.getCause().getCause() instanceof Exception )
784                 {
785                     
786                     throw new UndeclaredThrowableException( e.getCause().getCause() );
787                 }
788                 else
789                 {
790                     throw (RuntimeException) e.getCause();
791                 }
792             }
793             else if ( e.getCause() instanceof Error )
794             {
795                 throw (Error) e.getCause();
796             }
797             else
798             {
799                 
800                 throw new UndeclaredThrowableException( e.getCause() );
801             }
802         }
803     }
804 
805     
806 
807 
808 
809 
810     @Override
811     public ModelValidationReport validateModel( final String model, final Source source ) throws ModelException
812     {
813         if ( model == null )
814         {
815             throw new NullPointerException( "model" );
816         }
817         if ( source == null )
818         {
819             throw new NullPointerException( "source" );
820         }
821 
822         final long t0 = System.nanoTime();
823         final javax.xml.validation.Schema schema = this.createSchema( model );
824         final Validator validator = schema.newValidator();
825         final ModelErrorHandler modelErrorHandler = new ModelErrorHandler( this );
826         validator.setErrorHandler( modelErrorHandler );
827 
828         try
829         {
830             validator.validate( source );
831         }
832         catch ( final SAXException e )
833         {
834             String message = getMessage( e );
835             if ( message == null && e.getException() != null )
836             {
837                 message = getMessage( e.getException() );
838             }
839 
840             if ( this.isLoggable( Level.FINE ) )
841             {
842                 this.log( Level.FINE, message, e );
843             }
844 
845             if ( modelErrorHandler.getReport().isModelValid() )
846             {
847                 throw new ModelException( message, e );
848             }
849         }
850         catch ( final IOException e )
851         {
852             throw new ModelException( getMessage( e ), e );
853         }
854 
855         if ( this.isLoggable( Level.FINE ) )
856         {
857             this.log( Level.FINE, getMessage( "validateModelReport", model, System.nanoTime() - t0 ), null );
858         }
859 
860         return modelErrorHandler.getReport();
861     }
862 
863     @Override
864     public EntityResolver createEntityResolver( final String model ) throws ModelException
865     {
866         if ( model == null )
867         {
868             throw new NullPointerException( "model" );
869         }
870 
871         return this.createEntityResolver( this.getModlets().getSchemas( model ) );
872     }
873 
874     @Override
875     @Deprecated
876     public EntityResolver createEntityResolver( final URI publicId ) throws ModelException
877     {
878         if ( publicId == null )
879         {
880             throw new NullPointerException( "publicId" );
881         }
882 
883         return this.createEntityResolver( this.getModlets().getSchemas( publicId ) );
884     }
885 
886     @Override
887     public LSResourceResolver createResourceResolver( final String model ) throws ModelException
888     {
889         if ( model == null )
890         {
891             throw new NullPointerException( "model" );
892         }
893 
894         return this.createResourceResolver( this.createEntityResolver( model ) );
895     }
896 
897     @Override
898     @Deprecated
899     public LSResourceResolver createResourceResolver( final URI publicId ) throws ModelException
900     {
901         if ( publicId == null )
902         {
903             throw new NullPointerException( "publicId" );
904         }
905 
906         return this.createResourceResolver( this.createEntityResolver( publicId ) );
907     }
908 
909     @Override
910     public javax.xml.validation.Schema createSchema( final String model ) throws ModelException
911     {
912         if ( model == null )
913         {
914             throw new NullPointerException( "model" );
915         }
916 
917         return this.createSchema( this.getModlets().getSchemas( model ), this.createEntityResolver( model ),
918                                   this.createResourceResolver( model ), model, null );
919 
920     }
921 
922     @Override
923     @Deprecated
924     public javax.xml.validation.Schema createSchema( final URI publicId ) throws ModelException
925     {
926         if ( publicId == null )
927         {
928             throw new NullPointerException( "publicId" );
929         }
930 
931         return this.createSchema( this.getModlets().getSchemas( publicId ), this.createEntityResolver( publicId ),
932                                   this.createResourceResolver( publicId ), null, publicId );
933 
934     }
935 
936     @Override
937     public JAXBContext createContext( final String model ) throws ModelException
938     {
939         if ( model == null )
940         {
941             throw new NullPointerException( "model" );
942         }
943 
944         return this.createContext( this.getModlets().getSchemas( model ), model, null );
945     }
946 
947     @Override
948     @Deprecated
949     public JAXBContext createContext( final URI publicId ) throws ModelException
950     {
951         if ( publicId == null )
952         {
953             throw new NullPointerException( "publicId" );
954         }
955 
956         return this.createContext( this.getModlets().getSchemas( publicId ), null, publicId );
957     }
958 
959     @Override
960     public Marshaller createMarshaller( final String model ) throws ModelException
961     {
962         if ( model == null )
963         {
964             throw new NullPointerException( "model" );
965         }
966 
967         return this.createMarshaller( model, null );
968     }
969 
970     @Override
971     @Deprecated
972     public Marshaller createMarshaller( final URI publicId ) throws ModelException
973     {
974         if ( publicId == null )
975         {
976             throw new NullPointerException( "publicId" );
977         }
978 
979         return this.createMarshaller( null, publicId );
980     }
981 
982     @Override
983     public Unmarshaller createUnmarshaller( final String model ) throws ModelException
984     {
985         if ( model == null )
986         {
987             throw new NullPointerException( "model" );
988         }
989 
990         return this.createUnmarshaller( model, null );
991     }
992 
993     @Override
994     @Deprecated
995     public Unmarshaller createUnmarshaller( final URI publicId ) throws ModelException
996     {
997         if ( publicId == null )
998         {
999             throw new NullPointerException( "publicId" );
1000         }
1001 
1002         return this.createUnmarshaller( null, publicId );
1003     }
1004 
1005     
1006 
1007 
1008 
1009 
1010 
1011 
1012 
1013 
1014 
1015 
1016 
1017 
1018 
1019     @Override
1020     @Deprecated
1021     public <T> T createServiceObject( final Service service, final Class<T> type ) throws ModelException
1022     {
1023         if ( service == null )
1024         {
1025             throw new NullPointerException( "service" );
1026         }
1027         if ( type == null )
1028         {
1029             throw new NullPointerException( "type" );
1030         }
1031 
1032         return this.createServiceObject( service, type, this.loadModletServices( ServiceFactory.class ) );
1033     }
1034 
1035     private EntityResolver createEntityResolver( final Schemas schemas )
1036     {
1037         return new DefaultHandler()
1038         {
1039 
1040             @Override
1041             public InputSource resolveEntity( final String publicId, final String systemId )
1042                 throws SAXException, IOException
1043             {
1044                 InputSource schemaSource = null;
1045 
1046                 try
1047                 {
1048                     Schema s = null;
1049 
1050                     if ( schemas != null )
1051                     {
1052                         if ( systemId != null && !"".equals( systemId ) )
1053                         {
1054                             s = schemas.getSchemaBySystemId( systemId );
1055                         }
1056                         else if ( publicId != null )
1057                         {
1058                             s = schemas.getSchemaByPublicId( publicId );
1059                         }
1060                     }
1061 
1062                     if ( s != null )
1063                     {
1064                         schemaSource = new InputSource();
1065                         schemaSource.setPublicId( s.getPublicId() );
1066                         schemaSource.setSystemId( s.getSystemId() );
1067 
1068                         if ( s.getClasspathId() != null )
1069                         {
1070                             final URL resource = findResource( s.getClasspathId() );
1071 
1072                             if ( resource != null )
1073                             {
1074                                 schemaSource.setSystemId( resource.toExternalForm() );
1075                             }
1076                             else if ( isLoggable( Level.WARNING ) )
1077                             {
1078                                 log( Level.WARNING, getMessage( "resourceNotFound", s.getClasspathId() ), null );
1079                             }
1080                         }
1081 
1082                         if ( isLoggable( Level.FINEST ) )
1083                         {
1084                             log( Level.FINEST, getMessage( "resolutionInfo", publicId + ", " + systemId,
1085                                                            schemaSource.getPublicId() + ", "
1086                                                                + schemaSource.getSystemId() ), null );
1087 
1088                         }
1089                     }
1090 
1091                     if ( schemaSource == null && systemId != null && !"".equals( systemId ) )
1092                     {
1093                         final URI systemUri = new URI( systemId );
1094                         String schemaName = systemUri.getPath();
1095 
1096                         if ( schemaName != null )
1097                         {
1098                             final int lastIndexOfSlash = schemaName.lastIndexOf( '/' );
1099                             if ( lastIndexOfSlash != -1 && lastIndexOfSlash < schemaName.length() )
1100                             {
1101                                 schemaName = schemaName.substring( lastIndexOfSlash + 1 );
1102                             }
1103 
1104                             for ( final URI uri : getSchemaResources() )
1105                             {
1106                                 if ( uri.getSchemeSpecificPart() != null
1107                                          && uri.getSchemeSpecificPart().endsWith( schemaName ) )
1108                                 {
1109                                     schemaSource = new InputSource();
1110                                     schemaSource.setPublicId( publicId );
1111                                     schemaSource.setSystemId( uri.toASCIIString() );
1112 
1113                                     if ( isLoggable( Level.FINEST ) )
1114                                     {
1115                                         log( Level.FINEST, getMessage( "resolutionInfo", systemUri.toASCIIString(),
1116                                                                        schemaSource.getSystemId() ), null );
1117 
1118                                     }
1119 
1120                                     break;
1121                                 }
1122                             }
1123                         }
1124                         else
1125                         {
1126                             if ( isLoggable( Level.WARNING ) )
1127                             {
1128                                 log( Level.WARNING, getMessage( "unsupportedIdUri", systemId,
1129                                                                 systemUri.toASCIIString() ), null );
1130 
1131                             }
1132 
1133                             schemaSource = null;
1134                         }
1135                     }
1136                 }
1137                 catch ( final URISyntaxException e )
1138                 {
1139                     if ( isLoggable( Level.WARNING ) )
1140                     {
1141                         log( Level.WARNING, getMessage( "unsupportedIdUri", systemId, getMessage( e ) ), null );
1142                     }
1143 
1144                     schemaSource = null;
1145                 }
1146                 catch ( final ModelException e )
1147                 {
1148                     String message = getMessage( e );
1149                     if ( message == null )
1150                     {
1151                         message = "";
1152                     }
1153                     else if ( message.length() > 0 )
1154                     {
1155                         message = " " + message;
1156                     }
1157 
1158                     String resource = "";
1159                     if ( publicId != null )
1160                     {
1161                         resource = publicId + ", ";
1162                     }
1163                     resource += systemId;
1164 
1165                     
1166                     throw (IOException) new IOException( getMessage(
1167                         "failedResolving", resource, message ) ).initCause( e );
1168 
1169                 }
1170 
1171                 return schemaSource;
1172             }
1173 
1174         };
1175     }
1176 
1177     private LSResourceResolver createResourceResolver( final EntityResolver entityResolver )
1178     {
1179         if ( entityResolver == null )
1180         {
1181             throw new NullPointerException( "entityResolver" );
1182         }
1183 
1184         return new LSResourceResolver()
1185         {
1186 
1187             public LSInput resolveResource( final String type, final String namespaceURI, final String publicId,
1188                                             final String systemId, final String baseURI )
1189             {
1190                 final String resolvePublicId = namespaceURI == null ? publicId : namespaceURI;
1191                 final String resolveSystemId = systemId == null ? "" : systemId;
1192 
1193                 try
1194                 {
1195                     if ( XMLConstants.W3C_XML_SCHEMA_NS_URI.equals( type ) )
1196                     {
1197                         final InputSource schemaSource =
1198                             entityResolver.resolveEntity( resolvePublicId, resolveSystemId );
1199 
1200                         if ( schemaSource != null )
1201                         {
1202                             return new LSInput()
1203                             {
1204 
1205                                 public Reader getCharacterStream()
1206                                 {
1207                                     return schemaSource.getCharacterStream();
1208                                 }
1209 
1210                                 public void setCharacterStream( final Reader characterStream )
1211                                 {
1212                                     if ( isLoggable( Level.WARNING ) )
1213                                     {
1214                                         log( Level.WARNING, getMessage(
1215                                              "unsupportedOperation", "setCharacterStream",
1216                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1217 
1218                                     }
1219                                 }
1220 
1221                                 public InputStream getByteStream()
1222                                 {
1223                                     return schemaSource.getByteStream();
1224                                 }
1225 
1226                                 public void setByteStream( final InputStream byteStream )
1227                                 {
1228                                     if ( isLoggable( Level.WARNING ) )
1229                                     {
1230                                         log( Level.WARNING, getMessage(
1231                                              "unsupportedOperation", "setByteStream",
1232                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1233 
1234                                     }
1235                                 }
1236 
1237                                 public String getStringData()
1238                                 {
1239                                     return null;
1240                                 }
1241 
1242                                 public void setStringData( final String stringData )
1243                                 {
1244                                     if ( isLoggable( Level.WARNING ) )
1245                                     {
1246                                         log( Level.WARNING, getMessage(
1247                                              "unsupportedOperation", "setStringData",
1248                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1249 
1250                                     }
1251                                 }
1252 
1253                                 public String getSystemId()
1254                                 {
1255                                     return schemaSource.getSystemId();
1256                                 }
1257 
1258                                 public void setSystemId( final String systemId )
1259                                 {
1260                                     if ( isLoggable( Level.WARNING ) )
1261                                     {
1262                                         log( Level.WARNING, getMessage(
1263                                              "unsupportedOperation", "setSystemId",
1264                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1265 
1266                                     }
1267                                 }
1268 
1269                                 public String getPublicId()
1270                                 {
1271                                     return schemaSource.getPublicId();
1272                                 }
1273 
1274                                 public void setPublicId( final String publicId )
1275                                 {
1276                                     if ( isLoggable( Level.WARNING ) )
1277                                     {
1278                                         log( Level.WARNING, getMessage(
1279                                              "unsupportedOperation", "setPublicId",
1280                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1281 
1282                                     }
1283                                 }
1284 
1285                                 public String getBaseURI()
1286                                 {
1287                                     return baseURI;
1288                                 }
1289 
1290                                 public void setBaseURI( final String baseURI )
1291                                 {
1292                                     if ( isLoggable( Level.WARNING ) )
1293                                     {
1294                                         log( Level.WARNING, getMessage(
1295                                              "unsupportedOperation", "setBaseURI",
1296                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1297 
1298                                     }
1299                                 }
1300 
1301                                 public String getEncoding()
1302                                 {
1303                                     return schemaSource.getEncoding();
1304                                 }
1305 
1306                                 public void setEncoding( final String encoding )
1307                                 {
1308                                     if ( isLoggable( Level.WARNING ) )
1309                                     {
1310                                         log( Level.WARNING, getMessage(
1311                                              "unsupportedOperation", "setEncoding",
1312                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1313 
1314                                     }
1315                                 }
1316 
1317                                 public boolean getCertifiedText()
1318                                 {
1319                                     return false;
1320                                 }
1321 
1322                                 public void setCertifiedText( final boolean certifiedText )
1323                                 {
1324                                     if ( isLoggable( Level.WARNING ) )
1325                                     {
1326                                         log( Level.WARNING, getMessage(
1327                                              "unsupportedOperation", "setCertifiedText",
1328                                              DefaultModelContext.class.getName() + ".LSResourceResolver" ), null );
1329 
1330                                     }
1331                                 }
1332 
1333                             };
1334                         }
1335 
1336                     }
1337                     else if ( isLoggable( Level.WARNING ) )
1338                     {
1339                         log( Level.WARNING, getMessage( "unsupportedResourceType", type ), null );
1340                     }
1341                 }
1342                 catch ( final SAXException e )
1343                 {
1344                     String message = getMessage( e );
1345                     if ( message == null && e.getException() != null )
1346                     {
1347                         message = getMessage( e.getException() );
1348                     }
1349                     if ( message == null )
1350                     {
1351                         message = "";
1352                     }
1353                     else if ( message.length() > 0 )
1354                     {
1355                         message = " " + message;
1356                     }
1357 
1358                     String resource = "";
1359                     if ( resolvePublicId != null )
1360                     {
1361                         resource = resolvePublicId + ", ";
1362                     }
1363                     resource += resolveSystemId;
1364 
1365                     if ( isLoggable( Level.SEVERE ) )
1366                     {
1367                         log( Level.SEVERE, getMessage( "failedResolving", resource, message ), e );
1368                     }
1369                 }
1370                 catch ( final IOException e )
1371                 {
1372                     String message = getMessage( e );
1373                     if ( message == null )
1374                     {
1375                         message = "";
1376                     }
1377                     else if ( message.length() > 0 )
1378                     {
1379                         message = " " + message;
1380                     }
1381 
1382                     String resource = "";
1383                     if ( resolvePublicId != null )
1384                     {
1385                         resource = resolvePublicId + ", ";
1386                     }
1387                     resource += resolveSystemId;
1388 
1389                     if ( isLoggable( Level.SEVERE ) )
1390                     {
1391                         log( Level.SEVERE, getMessage( "failedResolving", resource, message ), e );
1392                     }
1393                 }
1394 
1395                 return null;
1396             }
1397 
1398         };
1399     }
1400 
1401     private javax.xml.validation.Schema createSchema( final Schemas schemas, final EntityResolver entityResolver,
1402                                                       final LSResourceResolver resourceResolver, final String model,
1403                                                       final URI publicId ) throws ModelException
1404     {
1405         if ( entityResolver == null )
1406         {
1407             throw new NullPointerException( "entityResolver" );
1408         }
1409         if ( model != null && publicId != null )
1410         {
1411             throw new IllegalArgumentException( "model=" + model + ", publicId=" + publicId.toASCIIString() );
1412         }
1413 
1414         try
1415         {
1416             final long t0 = System.nanoTime();
1417             final SchemaFactory f = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
1418             final List<Source> sources = new ArrayList<Source>( schemas != null ? schemas.getSchema().size() : 0 );
1419 
1420             if ( schemas != null )
1421             {
1422                 for ( final Schema s : schemas.getSchema() )
1423                 {
1424                     final InputSource inputSource = entityResolver.resolveEntity( s.getPublicId(), s.getSystemId() );
1425 
1426                     if ( inputSource != null )
1427                     {
1428                         sources.add( new SAXSource( inputSource ) );
1429                     }
1430                 }
1431             }
1432 
1433             if ( sources.isEmpty() )
1434             {
1435                 if ( model != null )
1436                 {
1437                     throw new ModelException( getMessage( "missingSchemasForModel", model ) );
1438                 }
1439                 if ( publicId != null )
1440                 {
1441                     throw new ModelException( getMessage( "missingSchemasForPublicId", publicId ) );
1442                 }
1443             }
1444 
1445             f.setResourceResolver( resourceResolver );
1446             f.setErrorHandler( new ErrorHandler()
1447             {
1448                 
1449 
1450                 public void warning( final SAXParseException e ) throws SAXException
1451                 {
1452                     String message = getMessage( e );
1453                     if ( message == null && e.getException() != null )
1454                     {
1455                         message = getMessage( e.getException() );
1456                     }
1457 
1458                     if ( isLoggable( Level.WARNING ) )
1459                     {
1460                         log( Level.WARNING, message, e );
1461                     }
1462                 }
1463 
1464                 public void error( final SAXParseException e ) throws SAXException
1465                 {
1466                     throw e;
1467                 }
1468 
1469                 public void fatalError( final SAXParseException e ) throws SAXException
1470                 {
1471                     throw e;
1472                 }
1473 
1474             } );
1475 
1476             final javax.xml.validation.Schema schema = f.newSchema( sources.toArray( new Source[ sources.size() ] ) );
1477 
1478             if ( this.isLoggable( Level.FINE ) )
1479             {
1480                 final StringBuilder schemaInfo = new StringBuilder( sources.size() * 50 );
1481 
1482                 for ( final Source s : sources )
1483                 {
1484                     schemaInfo.append( ", " ).append( s.getSystemId() );
1485                 }
1486 
1487                 this.log( Level.FINE, getMessage( "creatingSchema", schemaInfo.substring( 2 ), System.nanoTime() - t0 ),
1488                           null );
1489 
1490             }
1491 
1492             return schema;
1493         }
1494         catch ( final IOException e )
1495         {
1496             throw new ModelException( getMessage( e ), e );
1497         }
1498         catch ( final SAXException e )
1499         {
1500             String message = getMessage( e );
1501             if ( message == null && e.getException() != null )
1502             {
1503                 message = getMessage( e.getException() );
1504             }
1505 
1506             throw new ModelException( message, e );
1507         }
1508     }
1509 
1510     private JAXBContext createContext( final Schemas schemas, final String model, final URI publicId )
1511         throws ModelException
1512     {
1513         if ( model != null && publicId != null )
1514         {
1515             throw new IllegalArgumentException( "model=" + model + ", publicId=" + publicId.toASCIIString() );
1516         }
1517 
1518         try
1519         {
1520             StringBuilder packageNames = null;
1521             final long t0 = System.nanoTime();
1522 
1523             if ( schemas != null )
1524             {
1525                 packageNames = new StringBuilder( schemas.getSchema().size() * 25 );
1526 
1527                 for ( final Schema schema : schemas.getSchema() )
1528                 {
1529                     if ( schema.getContextId() != null )
1530                     {
1531                         packageNames.append( ':' ).append( schema.getContextId() );
1532                     }
1533                 }
1534             }
1535 
1536             if ( packageNames == null || packageNames.length() == 0 )
1537             {
1538                 if ( model != null )
1539                 {
1540                     throw new ModelException( getMessage( "missingSchemasForModel", model ) );
1541                 }
1542                 if ( publicId != null )
1543                 {
1544                     throw new ModelException( getMessage( "missingSchemasForPublicId", publicId ) );
1545                 }
1546             }
1547 
1548             final JAXBContext context = JAXBContext.newInstance( packageNames.substring( 1 ), this.getClassLoader() );
1549 
1550             if ( this.isLoggable( Level.FINE ) )
1551             {
1552                 this.log( Level.FINE, getMessage( "creatingContext", packageNames.substring( 1 ),
1553                                                   System.nanoTime() - t0 ), null );
1554 
1555             }
1556 
1557             return context;
1558         }
1559         catch ( final JAXBException e )
1560         {
1561             String message = getMessage( e );
1562             if ( message == null && e.getLinkedException() != null )
1563             {
1564                 message = getMessage( e.getLinkedException() );
1565             }
1566 
1567             throw new ModelException( message, e );
1568         }
1569     }
1570 
1571     private Marshaller createMarshaller( final String model, final URI publicId )
1572         throws ModelException
1573     {
1574         if ( model != null && publicId != null )
1575         {
1576             throw new IllegalArgumentException( "model=" + model + ", publicId=" + publicId.toASCIIString() );
1577         }
1578 
1579         Schemas schemas = null;
1580 
1581         if ( model != null )
1582         {
1583             schemas = this.getModlets().getSchemas( model );
1584         }
1585 
1586         if ( publicId != null )
1587         {
1588             schemas = this.getModlets().getSchemas( publicId );
1589         }
1590 
1591         try
1592         {
1593             StringBuilder packageNames = null;
1594             StringBuilder schemaLocation = null;
1595             final long t0 = System.nanoTime();
1596 
1597             if ( schemas != null )
1598             {
1599                 packageNames = new StringBuilder( schemas.getSchema().size() * 25 );
1600                 schemaLocation = new StringBuilder( schemas.getSchema().size() * 50 );
1601 
1602                 for ( final Schema schema : schemas.getSchema() )
1603                 {
1604                     if ( schema.getContextId() != null )
1605                     {
1606                         packageNames.append( ':' ).append( schema.getContextId() );
1607                     }
1608                     if ( schema.getPublicId() != null && schema.getSystemId() != null )
1609                     {
1610                         schemaLocation.append( ' ' ).append( schema.getPublicId() ).append( ' ' ).
1611                             append( schema.getSystemId() );
1612 
1613                     }
1614                 }
1615             }
1616 
1617             if ( packageNames == null || packageNames.length() == 0 )
1618             {
1619                 if ( model != null )
1620                 {
1621                     throw new ModelException( getMessage( "missingSchemasForModel", model ) );
1622                 }
1623                 if ( publicId != null )
1624                 {
1625                     throw new ModelException( getMessage( "missingSchemasForPublicId", publicId ) );
1626                 }
1627             }
1628 
1629             final Marshaller m =
1630                 JAXBContext.newInstance( packageNames.substring( 1 ), this.getClassLoader() ).createMarshaller();
1631 
1632             if ( schemaLocation != null && schemaLocation.length() != 0 )
1633             {
1634                 m.setProperty( Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation.substring( 1 ) );
1635             }
1636 
1637             MarshallerListenerList listenerList = null;
1638 
1639             if ( model != null )
1640             {
1641                 final Collection<? extends Marshaller.Listener> listeners =
1642                     this.createServiceObjects( model, MARSHALLER_LISTENER_SERVICE, Marshaller.Listener.class );
1643 
1644                 if ( !listeners.isEmpty() )
1645                 {
1646                     listenerList = new MarshallerListenerList();
1647                     listenerList.getListeners().addAll( listeners );
1648                     m.setListener( listenerList );
1649                 }
1650             }
1651 
1652             if ( this.isLoggable( Level.FINE ) )
1653             {
1654                 if ( listenerList == null )
1655                 {
1656                     this.log( Level.FINE, getMessage( "creatingMarshaller", packageNames.substring( 1 ),
1657                                                       schemaLocation.substring( 1 ),
1658                                                       System.nanoTime() - t0 ), null );
1659 
1660                 }
1661                 else
1662                 {
1663                     final StringBuilder b = new StringBuilder( listenerList.getListeners().size() * 100 );
1664 
1665                     for ( int i = 0, s0 = listenerList.getListeners().size(); i < s0; i++ )
1666                     {
1667                         b.append( ',' ).append( listenerList.getListeners().get( i ) );
1668                     }
1669 
1670                     this.log( Level.FINE, getMessage( "creatingMarshallerWithListeners", packageNames.substring( 1 ),
1671                                                       schemaLocation.substring( 1 ), b.substring( 1 ),
1672                                                       System.nanoTime() - t0 ), null );
1673 
1674                 }
1675             }
1676 
1677             return m;
1678         }
1679         catch ( final JAXBException e )
1680         {
1681             String message = getMessage( e );
1682             if ( message == null && e.getLinkedException() != null )
1683             {
1684                 message = getMessage( e.getLinkedException() );
1685             }
1686 
1687             throw new ModelException( message, e );
1688         }
1689     }
1690 
1691     private Unmarshaller createUnmarshaller( final String model, final URI publicId )
1692         throws ModelException
1693     {
1694         if ( model != null && publicId != null )
1695         {
1696             throw new IllegalArgumentException( "model=" + model + ", publicId=" + publicId.toASCIIString() );
1697         }
1698 
1699         Schemas schemas = null;
1700 
1701         if ( model != null )
1702         {
1703             schemas = this.getModlets().getSchemas( model );
1704         }
1705 
1706         if ( publicId != null )
1707         {
1708             schemas = this.getModlets().getSchemas( publicId );
1709         }
1710 
1711         try
1712         {
1713             StringBuilder packageNames = null;
1714             final long t0 = System.nanoTime();
1715 
1716             if ( schemas != null )
1717             {
1718                 packageNames = new StringBuilder( schemas.getSchema().size() * 25 );
1719 
1720                 for ( final Schema schema : schemas.getSchema() )
1721                 {
1722                     if ( schema.getContextId() != null )
1723                     {
1724                         packageNames.append( ':' ).append( schema.getContextId() );
1725                     }
1726                 }
1727             }
1728 
1729             if ( packageNames == null || packageNames.length() == 0 )
1730             {
1731                 if ( model != null )
1732                 {
1733                     throw new ModelException( getMessage( "missingSchemasForModel", model ) );
1734                 }
1735                 if ( publicId != null )
1736                 {
1737                     throw new ModelException( getMessage( "missingSchemasForPublicId", publicId ) );
1738                 }
1739             }
1740 
1741             final Unmarshaller u =
1742                 JAXBContext.newInstance( packageNames.substring( 1 ), this.getClassLoader() ).createUnmarshaller();
1743 
1744             UnmarshallerListenerList listenerList = null;
1745 
1746             if ( model != null )
1747             {
1748                 final Collection<? extends Unmarshaller.Listener> listeners =
1749                     this.createServiceObjects( model, UNMARSHALLER_LISTENER_SERVICE, Unmarshaller.Listener.class );
1750 
1751                 if ( !listeners.isEmpty() )
1752                 {
1753                     listenerList = new UnmarshallerListenerList();
1754                     listenerList.getListeners().addAll( listeners );
1755                     u.setListener( listenerList );
1756                 }
1757             }
1758 
1759             if ( this.isLoggable( Level.FINE ) )
1760             {
1761                 if ( listenerList == null )
1762                 {
1763                     this.log( Level.FINE, getMessage( "creatingUnmarshaller", packageNames.substring( 1 ),
1764                                                       System.nanoTime() - t0 ), null );
1765 
1766                 }
1767                 else
1768                 {
1769                     final StringBuilder b = new StringBuilder( listenerList.getListeners().size() * 100 );
1770 
1771                     for ( int i = 0, s0 = listenerList.getListeners().size(); i < s0; i++ )
1772                     {
1773                         b.append( ',' ).append( listenerList.getListeners().get( i ) );
1774                     }
1775 
1776                     this.log( Level.FINE, getMessage( "creatingUnmarshallerWithListeners",
1777                                                       packageNames.substring( 1 ), b.substring( 1 ),
1778                                                       System.nanoTime() - t0 ), null );
1779 
1780                 }
1781             }
1782 
1783             return u;
1784         }
1785         catch ( final JAXBException e )
1786         {
1787             String message = getMessage( e );
1788             if ( message == null && e.getLinkedException() != null )
1789             {
1790                 message = getMessage( e.getLinkedException() );
1791             }
1792 
1793             throw new ModelException( message, e );
1794         }
1795     }
1796 
1797     
1798 
1799 
1800 
1801 
1802 
1803 
1804 
1805 
1806     @Override
1807     public <T> Collection<? extends T> createServiceObjects( final String model, final String service,
1808                                                              final Class<T> type )
1809         throws ModelException
1810     {
1811         if ( model == null )
1812         {
1813             throw new NullPointerException( "model" );
1814         }
1815         if ( service == null )
1816         {
1817             throw new NullPointerException( "service" );
1818         }
1819         if ( type == null )
1820         {
1821             throw new NullPointerException( "type" );
1822         }
1823 
1824         final Services modelServices = this.getModlets().getServices( model );
1825         final Collection<T> serviceObjects =
1826             new ArrayList<T>( modelServices != null ? modelServices.getService().size() : 0 );
1827 
1828         if ( modelServices != null )
1829         {
1830             final Collection<ServiceFactory> factories = this.loadModletServices( ServiceFactory.class );
1831 
1832             for ( final Service s : modelServices.getServices( service ) )
1833             {
1834                 serviceObjects.add( this.createServiceObject( s, type, factories ) );
1835             }
1836         }
1837 
1838         return Collections.unmodifiableCollection( serviceObjects );
1839     }
1840 
1841     
1842 
1843 
1844 
1845 
1846 
1847 
1848 
1849 
1850 
1851 
1852 
1853 
1854 
1855     private <T> T createServiceObject( final Service service, final Class<T> type,
1856                                        final Collection<ServiceFactory> factories ) throws ModelException
1857     {
1858         if ( service == null )
1859         {
1860             throw new NullPointerException( "service" );
1861         }
1862         if ( type == null )
1863         {
1864             throw new NullPointerException( "type" );
1865         }
1866         if ( factories == null )
1867         {
1868             throw new NullPointerException( "factories" );
1869         }
1870 
1871         T serviceObject = null;
1872 
1873         for ( final ServiceFactory factory : factories )
1874         {
1875             final T current = factory.createServiceObject( this, service, type );
1876 
1877             if ( current != null )
1878             {
1879                 if ( this.isLoggable( Level.FINER ) )
1880                 {
1881                     this.log( Level.FINER, getMessage( "creatingService", service.getOrdinal(), service.getIdentifier(),
1882                                                        service.getClazz(), factory.toString() ), null );
1883 
1884                 }
1885 
1886                 serviceObject = current;
1887                 break;
1888             }
1889         }
1890 
1891         if ( serviceObject == null )
1892         {
1893             throw new ModelException( getMessage( "serviceNotCreated", service.getOrdinal(), service.getIdentifier(),
1894                                                   service.getClazz() ), null );
1895 
1896         }
1897 
1898         return serviceObject;
1899     }
1900 
1901     private <T> Collection<T> loadModletServices( final Class<T> serviceClass ) throws ModelException
1902     {
1903         InputStream in = null;
1904         BufferedReader reader = null;
1905 
1906         try
1907         {
1908             final String serviceNamePrefix = serviceClass.getName() + ".";
1909             final Map<String, T> sortedPlatformServices = new TreeMap<String, T>( new Comparator<String>()
1910             {
1911 
1912                 public int compare( final String key1, final String key2 )
1913                 {
1914                     return key1.compareTo( key2 );
1915                 }
1916 
1917             } );
1918 
1919             final File platformServices = new File( this.getPlatformProviderLocation() );
1920 
1921             if ( platformServices.exists() )
1922             {
1923                 if ( this.isLoggable( Level.FINEST ) )
1924                 {
1925                     this.log( Level.FINEST, getMessage( "processing", platformServices.getAbsolutePath() ), null );
1926                 }
1927 
1928                 final java.util.Properties p = new java.util.Properties();
1929 
1930                 in = new FileInputStream( platformServices );
1931 
1932                 p.load( in );
1933 
1934                 in.close();
1935                 in = null;
1936 
1937                 for ( final Map.Entry<Object, Object> e : p.entrySet() )
1938                 {
1939                     if ( e.getKey().toString().startsWith( serviceNamePrefix ) )
1940                     {
1941                         final String configuration = e.getValue().toString();
1942 
1943                         if ( this.isLoggable( Level.FINEST ) )
1944                         {
1945                             this.log( Level.FINEST, getMessage( "serviceInfo", platformServices.getAbsolutePath(),
1946                                                                 serviceClass.getName(), configuration ), null );
1947 
1948                         }
1949 
1950                         sortedPlatformServices.put( e.getKey().toString(),
1951                                                     this.createModletServiceObject( serviceClass, configuration ) );
1952 
1953                     }
1954                 }
1955             }
1956 
1957             final Enumeration<URL> classpathServices =
1958                 this.findResources( this.getProviderLocation() + '/' + serviceClass.getName() );
1959 
1960             int count = 0;
1961             final long t0 = System.nanoTime();
1962             final List<T> sortedClasspathServices = new LinkedList<T>();
1963 
1964             while ( classpathServices.hasMoreElements() )
1965             {
1966                 count++;
1967                 final URL url = classpathServices.nextElement();
1968 
1969                 if ( this.isLoggable( Level.FINEST ) )
1970                 {
1971                     this.log( Level.FINEST, getMessage( "processing", url.toExternalForm() ), null );
1972                 }
1973 
1974                 reader = new BufferedReader( new InputStreamReader( url.openStream(), "UTF-8" ) );
1975 
1976                 for ( String line = reader.readLine(); line != null; line = reader.readLine() )
1977                 {
1978                     if ( line.contains( "#" ) )
1979                     {
1980                         continue;
1981                     }
1982 
1983                     if ( this.isLoggable( Level.FINEST ) )
1984                     {
1985                         this.log( Level.FINEST, getMessage( "serviceInfo", url.toExternalForm(),
1986                                                             serviceClass.getName(), line ), null );
1987 
1988                     }
1989 
1990                     final T serviceObject = this.createModletServiceObject( serviceClass, line );
1991                     sortedClasspathServices.add( serviceObject );
1992                 }
1993 
1994                 Collections.sort( sortedClasspathServices,
1995                                   new Comparator<Object>()
1996                               {
1997 
1998                                   public int compare( final Object o1, final Object o2 )
1999                                   {
2000                                       return ordinalOf( o1 ) - ordinalOf( o2 );
2001                                   }
2002 
2003                               } );
2004 
2005                 reader.close();
2006                 reader = null;
2007             }
2008 
2009             if ( this.isLoggable( Level.FINE ) )
2010             {
2011                 this.log( Level.FINE, getMessage( "contextReport", count,
2012                                                   this.getProviderLocation() + '/' + serviceClass.getName(),
2013                                                   System.nanoTime() - t0 ), null );
2014 
2015             }
2016 
2017             final List<T> services =
2018                 new ArrayList<T>( sortedPlatformServices.size() + sortedClasspathServices.size() );
2019 
2020             services.addAll( sortedPlatformServices.values() );
2021             services.addAll( sortedClasspathServices );
2022 
2023             return services;
2024         }
2025         catch ( final IOException e )
2026         {
2027             throw new ModelException( getMessage( e ), e );
2028         }
2029         finally
2030         {
2031             try
2032             {
2033                 if ( in != null )
2034                 {
2035                     in.close();
2036                 }
2037             }
2038             catch ( final IOException e )
2039             {
2040                 this.log( Level.SEVERE, getMessage( e ), e );
2041             }
2042             finally
2043             {
2044                 try
2045                 {
2046                     if ( reader != null )
2047                     {
2048                         reader.close();
2049                     }
2050                 }
2051                 catch ( final IOException e )
2052                 {
2053                     this.log( Level.SEVERE, getMessage( e ), e );
2054                 }
2055             }
2056         }
2057     }
2058 
2059     private <T> T createModletServiceObject( final Class<T> serviceClass, final String configuration )
2060         throws ModelException
2061     {
2062         String className = configuration;
2063         final int i0 = configuration.indexOf( '[' );
2064         final int i1 = configuration.lastIndexOf( ']' );
2065         final Service service = new Service();
2066         service.setIdentifier( serviceClass.getName() );
2067 
2068         if ( i0 != -1 && i1 != -1 )
2069         {
2070             className = configuration.substring( 0, i0 );
2071             final StringTokenizer propertyTokens =
2072                 new StringTokenizer( configuration.substring( i0 + 1, i1 ), "," );
2073 
2074             while ( propertyTokens.hasMoreTokens() )
2075             {
2076                 final String property = propertyTokens.nextToken();
2077                 final int d0 = property.indexOf( '=' );
2078 
2079                 String propertyName = property;
2080                 String propertyValue = null;
2081 
2082                 if ( d0 != -1 )
2083                 {
2084                     propertyName = property.substring( 0, d0 );
2085                     propertyValue = property.substring( d0 + 1, property.length() );
2086                 }
2087 
2088                 final Property p = new Property();
2089                 service.getProperty().add( p );
2090 
2091                 p.setName( propertyName );
2092                 p.setValue( propertyValue );
2093             }
2094         }
2095 
2096         service.setClazz( className );
2097 
2098         
2099         return new DefaultServiceFactory().createServiceObject( this, service, serviceClass );
2100     }
2101 
2102     
2103 
2104 
2105 
2106 
2107 
2108 
2109 
2110 
2111 
2112     private Set<URI> getSchemaResources() throws IOException, URISyntaxException, ModelException
2113     {
2114         final Set<URI> resources = new HashSet<URI>();
2115         final long t0 = System.nanoTime();
2116         int count = 0;
2117 
2118         for ( final Enumeration<URL> e = this.findResources( "META-INF/MANIFEST.MF" ); e.hasMoreElements(); )
2119         {
2120             InputStream manifestStream = null;
2121 
2122             try
2123             {
2124                 count++;
2125                 final URL manifestUrl = e.nextElement();
2126                 final String externalForm = manifestUrl.toExternalForm();
2127                 final String baseUrl = externalForm.substring( 0, externalForm.indexOf( "META-INF" ) );
2128                 manifestStream = manifestUrl.openStream();
2129                 final Manifest mf = new Manifest( manifestStream );
2130 
2131                 if ( this.isLoggable( Level.FINEST ) )
2132                 {
2133                     this.log( Level.FINEST, getMessage( "processing", externalForm ), null );
2134                 }
2135 
2136                 for ( final Map.Entry<String, Attributes> entry : mf.getEntries().entrySet() )
2137                 {
2138                     for ( int i = SCHEMA_EXTENSIONS.length - 1; i >= 0; i-- )
2139                     {
2140                         if ( entry.getKey().toLowerCase().endsWith( '.' + SCHEMA_EXTENSIONS[i].toLowerCase() ) )
2141                         {
2142                             final URL schemaUrl = new URL( baseUrl + entry.getKey() );
2143                             resources.add( schemaUrl.toURI() );
2144 
2145                             if ( this.isLoggable( Level.FINEST ) )
2146                             {
2147                                 this.log( Level.FINEST, getMessage( "foundSchemaCandidate",
2148                                                                     schemaUrl.toExternalForm() ), null );
2149 
2150                             }
2151                         }
2152                     }
2153                 }
2154 
2155                 manifestStream.close();
2156                 manifestStream = null;
2157             }
2158             finally
2159             {
2160                 try
2161                 {
2162                     if ( manifestStream != null )
2163                     {
2164                         manifestStream.close();
2165                     }
2166                 }
2167                 catch ( final IOException ex )
2168                 {
2169                     this.log( Level.SEVERE, getMessage( ex ), ex );
2170                 }
2171             }
2172         }
2173 
2174         if ( this.isLoggable( Level.FINE ) )
2175         {
2176             this.log( Level.FINE, getMessage( "contextReport", count, "META-INF/MANIFEST.MF", System.nanoTime() - t0 ),
2177                       null );
2178 
2179         }
2180 
2181         return resources;
2182     }
2183 
2184     private static int ordinalOf( final Object serviceObject )
2185     {
2186         int ordinal = 0;
2187 
2188         if ( serviceObject instanceof ModletProvider )
2189         {
2190             ordinal = ( (ModletProvider) serviceObject ).getOrdinal();
2191         }
2192         if ( serviceObject instanceof ModletProcessor )
2193         {
2194             ordinal = ( (ModletProcessor) serviceObject ).getOrdinal();
2195         }
2196         if ( serviceObject instanceof ModletValidator )
2197         {
2198             ordinal = ( (ModletValidator) serviceObject ).getOrdinal();
2199         }
2200         if ( serviceObject instanceof ServiceFactory )
2201         {
2202             ordinal = ( (ServiceFactory) serviceObject ).getOrdinal();
2203         }
2204 
2205         return ordinal;
2206     }
2207 
2208     private static String getMessage( final String key, final Object... arguments )
2209     {
2210         return MessageFormat.format( ResourceBundle.getBundle(
2211             DefaultModelContext.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
2212 
2213     }
2214 
2215     private static String getMessage( final Throwable t )
2216     {
2217         return t != null
2218                    ? t.getMessage() != null && t.getMessage().trim().length() > 0
2219                          ? t.getMessage()
2220                          : getMessage( t.getCause() )
2221                    : null;
2222 
2223     }
2224 
2225 }
2226 
2227 
2228 
2229 
2230 
2231 
2232 
2233 class ModelErrorHandler extends DefaultHandler
2234 {
2235 
2236     
2237 
2238 
2239     private final ModelContext context;
2240 
2241     
2242 
2243 
2244     private final ModelValidationReport report;
2245 
2246     
2247 
2248 
2249 
2250 
2251     ModelErrorHandler( final ModelContext context )
2252     {
2253         this( context, new ModelValidationReport() );
2254     }
2255 
2256     
2257 
2258 
2259 
2260 
2261 
2262     ModelErrorHandler( final ModelContext context, final ModelValidationReport report )
2263     {
2264         super();
2265         this.context = context;
2266         this.report = report;
2267     }
2268 
2269     
2270 
2271 
2272 
2273 
2274     public ModelValidationReport getReport()
2275     {
2276         return this.report;
2277     }
2278 
2279     @Override
2280     public void warning( final SAXParseException exception ) throws SAXException
2281     {
2282         String message = getMessage( exception );
2283         if ( message == null && exception.getException() != null )
2284         {
2285             message = getMessage( exception.getException() );
2286         }
2287 
2288         if ( this.context != null && this.context.isLoggable( Level.FINE ) )
2289         {
2290             this.context.log( Level.FINE, message, exception );
2291         }
2292 
2293         this.getReport().getDetails().add( new ModelValidationReport.Detail(
2294             "W3C XML 1.0 Recommendation - Warning condition", Level.WARNING, message, null ) );
2295 
2296     }
2297 
2298     @Override
2299     public void error( final SAXParseException exception ) throws SAXException
2300     {
2301         String message = getMessage( exception );
2302         if ( message == null && exception.getException() != null )
2303         {
2304             message = getMessage( exception.getException() );
2305         }
2306 
2307         if ( this.context != null && this.context.isLoggable( Level.FINE ) )
2308         {
2309             this.context.log( Level.FINE, message, exception );
2310         }
2311 
2312         this.getReport().getDetails().add( new ModelValidationReport.Detail(
2313             "W3C XML 1.0 Recommendation - Section 1.2 - Error", Level.SEVERE, message, null ) );
2314 
2315     }
2316 
2317     @Override
2318     public void fatalError( final SAXParseException exception ) throws SAXException
2319     {
2320         String message = getMessage( exception );
2321         if ( message == null && exception.getException() != null )
2322         {
2323             message = getMessage( exception.getException() );
2324         }
2325 
2326         if ( this.context != null && this.context.isLoggable( Level.FINE ) )
2327         {
2328             this.context.log( Level.FINE, message, exception );
2329         }
2330 
2331         this.getReport().getDetails().add( new ModelValidationReport.Detail(
2332             "W3C XML 1.0 Recommendation - Section 1.2 - Fatal Error", Level.SEVERE, message, null ) );
2333 
2334     }
2335 
2336     private static String getMessage( final Throwable t )
2337     {
2338         return t != null
2339                    ? t.getMessage() != null && t.getMessage().trim().length() > 0
2340                          ? t.getMessage()
2341                          : getMessage( t.getCause() )
2342                    : null;
2343 
2344     }
2345 
2346 }
2347 
2348 
2349 
2350 
2351 
2352 
2353 
2354 
2355 class MarshallerListenerList extends Marshaller.Listener
2356 {
2357 
2358     
2359 
2360 
2361     private final List<Marshaller.Listener> listeners = new CopyOnWriteArrayList<Marshaller.Listener>();
2362 
2363     
2364 
2365 
2366     MarshallerListenerList()
2367     {
2368         super();
2369     }
2370 
2371     
2372 
2373 
2374 
2375 
2376 
2377 
2378 
2379 
2380 
2381     List<Marshaller.Listener> getListeners()
2382     {
2383         return this.listeners;
2384     }
2385 
2386     @Override
2387     public void beforeMarshal( final Object source )
2388     {
2389         for ( final Marshaller.Listener listener : this.getListeners() )
2390         {
2391             listener.beforeMarshal( source );
2392         }
2393     }
2394 
2395     @Override
2396     public void afterMarshal( final Object source )
2397     {
2398         for ( final Marshaller.Listener listener : this.getListeners() )
2399         {
2400             listener.afterMarshal( source );
2401         }
2402     }
2403 
2404 }
2405 
2406 
2407 
2408 
2409 
2410 
2411 
2412 
2413 class UnmarshallerListenerList extends Unmarshaller.Listener
2414 {
2415 
2416     
2417 
2418 
2419     private final List<Unmarshaller.Listener> listeners = new CopyOnWriteArrayList<Unmarshaller.Listener>();
2420 
2421     
2422 
2423 
2424     UnmarshallerListenerList()
2425     {
2426         super();
2427     }
2428 
2429     
2430 
2431 
2432 
2433 
2434 
2435 
2436 
2437 
2438 
2439     List<Unmarshaller.Listener> getListeners()
2440     {
2441         return this.listeners;
2442     }
2443 
2444     @Override
2445     public void beforeUnmarshal( final Object target, final Object parent )
2446     {
2447         for ( final Unmarshaller.Listener listener : this.getListeners() )
2448         {
2449             listener.beforeUnmarshal( target, parent );
2450         }
2451     }
2452 
2453     @Override
2454     public void afterUnmarshal( final Object target, final Object parent )
2455     {
2456         for ( final Unmarshaller.Listener listener : this.getListeners() )
2457         {
2458             listener.afterUnmarshal( target, parent );
2459         }
2460     }
2461 
2462 }