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
32
33
34
35 package org.ogf.graap.wsag.server.engine;
36
37 import java.io.File;
38 import java.io.InputStream;
39 import java.net.URL;
40 import java.text.MessageFormat;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.Vector;
44
45 import javax.xml.namespace.QName;
46
47 import org.apache.log4j.Logger;
48 import org.apache.xml.resolver.tools.CatalogResolver;
49 import org.apache.xmlbeans.SchemaType;
50 import org.apache.xmlbeans.SchemaTypeLoader;
51 import org.apache.xmlbeans.SchemaTypeSystem;
52 import org.apache.xmlbeans.XmlBeans;
53 import org.apache.xmlbeans.XmlError;
54 import org.apache.xmlbeans.XmlObject;
55 import org.apache.xmlbeans.XmlOptions;
56 import org.apache.xmlbeans.impl.common.ResolverUtil;
57 import org.apache.xmlbeans.impl.xb.xsdschema.ComplexRestrictionType;
58 import org.apache.xmlbeans.impl.xb.xsdschema.ComplexType;
59 import org.apache.xmlbeans.impl.xb.xsdschema.FormChoice;
60 import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
61 import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema;
62 import org.apache.xmlbeans.impl.xb.xsdschema.SimpleType;
63 import org.ogf.graap.wsag.api.AgreementOffer;
64 import org.ogf.graap.wsag.api.logging.LogMessage;
65 import org.ogf.graap.wsag.api.types.AgreementOfferType;
66 import org.ogf.graap.wsag4j.types.configuration.SchemaImportType;
67 import org.ogf.graap.wsag4j.types.configuration.ValidatorConfigurationDocument;
68 import org.ogf.graap.wsag4j.types.configuration.ValidatorType;
69 import org.ogf.graap.wsag4j.types.engine.ConstraintAnnotationDocument;
70 import org.ogf.graap.wsag4j.types.engine.ConstraintAnnotationType;
71 import org.ogf.graap.wsag4j.types.engine.ItemCardinalityType;
72 import org.ogf.schemas.graap.wsAgreement.AgreementOfferDocument;
73 import org.ogf.schemas.graap.wsAgreement.AgreementTemplateType;
74 import org.ogf.schemas.graap.wsAgreement.AgreementType;
75 import org.ogf.schemas.graap.wsAgreement.OfferItemType;
76 import org.ogf.schemas.graap.wsAgreement.OfferItemType.ItemConstraint;
77 import org.ogf.schemas.graap.wsAgreement.TemplateDocument;
78 import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationConstraintType;
79 import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationOfferDocument;
80 import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationOfferItemType;
81 import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationOfferType;
82 import org.ogf.schemas.graap.wsAgreement.negotiation.NegotiationRoleType.Enum;
83
84
85
86
87
88
89
90
91
92 public class TemplateValidator
93 {
94
95 private static final String GENERATED_TYPE_NAME = "GeneratedConstraintValidationType";
96
97 private static final String XML_SCHEMA_FILENAME = "/validator/XMLSchema.xml";
98
99 private static final String WSAG_SCHEMA_FILENAME = "/validator/ws-agreement-xsd-types.xsd";
100
101 private static final Logger LOG = Logger.getLogger( TemplateValidator.class );
102
103 private final HashMap<String, Boolean[]> knownSchemaFormChoice = new HashMap<String, Boolean[]>();
104
105 private XmlOptions options = null;
106
107 private ValidatorType configuration;
108
109
110
111
112 private SchemaTypeLoader loader;
113
114
115
116
117
118
119
120 public static void main( String[] args )
121 {
122 if ( args.length != 3 )
123 {
124 LOG.info( "Usage: TemplateValidator agreement_template.xml agreement_offer.xml validator_config.xml" );
125 return;
126 }
127
128 URL templateURL = System.class.getResource( args[0] );
129 URL offerURL = System.class.getResource( args[1] );
130 URL configURL = System.class.getResource( args[2] );
131
132 if ( templateURL == null )
133 {
134 LOG.error( "Template does not exist..." );
135 return;
136 }
137 if ( offerURL == null )
138 {
139 LOG.error( "Offer does not exist..." );
140 return;
141 }
142 if ( configURL == null )
143 {
144 LOG.error( "Config file does not exist..." );
145 return;
146 }
147
148 File templateFile;
149 File offerFile;
150 File configFile;
151
152 try
153 {
154 templateFile = new File( templateURL.toURI() );
155 offerFile = new File( offerURL.toURI() );
156 configFile = new File( configURL.toURI() );
157 }
158 catch ( Exception ex )
159 {
160 LOG.error( "Error opening file. Reason: " + ex.getMessage() );
161 return;
162 }
163
164 if ( !( templateFile.exists() && templateFile.isFile() ) )
165 {
166 LOG.error( LogMessage.getMessage( "Template file <{0}> does not exist or is a directory...",
167 templateURL.toExternalForm() ) );
168 return;
169 }
170
171 if ( !( offerFile.exists() && offerFile.isFile() ) )
172 {
173 LOG.error( LogMessage.getMessage( "Offer file <{0}> does not exist or is a directory...",
174 offerURL.toExternalForm() ) );
175 return;
176 }
177
178 if ( !( configFile.exists() && configFile.isFile() ) )
179 {
180 LOG.error( LogMessage.getMessage( "Config file <{0}> does not exist or is a directory...",
181 offerURL.toExternalForm() ) );
182 return;
183 }
184
185 AgreementTemplateType template;
186 try
187 {
188 template = parseTemplate( templateFile );
189 }
190 catch ( Exception e )
191 {
192 LOG.error( "Could not load template file. Reason: " + e.getMessage() );
193 return;
194 }
195
196 AgreementType offer;
197 try
198 {
199 XmlObject parsedResult = XmlObject.Factory.parse( offerFile );
200
201 if ( parsedResult instanceof AgreementOfferDocument )
202 {
203 offer = ( (AgreementOfferDocument) parsedResult ).getAgreementOffer();
204 }
205 else
206 {
207 Object[] filler =
208 new Object[] { ( parsedResult.schemaType().getName() != null ) ? parsedResult.schemaType()
209 .getName()
210 : parsedResult.schemaType().getDocumentElementName() };
211 String message =
212 MessageFormat.format( "Offer file of type {0} is not a valid Agreement Offer Document. ",
213 filler );
214 LOG.error( message );
215 return;
216 }
217 }
218 catch ( Exception e )
219 {
220 LOG.error( "Could not load template file. Reason: " + e.getMessage() );
221 return;
222 }
223
224 ValidatorType validatorConfig;
225 try
226 {
227 XmlObject parsedResult = XmlObject.Factory.parse( configFile );
228
229 if ( parsedResult instanceof ValidatorConfigurationDocument )
230 {
231 validatorConfig =
232 ( (ValidatorConfigurationDocument) parsedResult ).getValidatorConfiguration();
233 }
234 else
235 {
236 Object[] filler =
237 new Object[] { ( parsedResult.schemaType().getName() != null ) ? parsedResult.schemaType()
238 .getName()
239 : parsedResult.schemaType().getDocumentElementName() };
240
241 String msgNoValidConfig =
242 "Config file of type {0} is not a valid Validator Config Document. ";
243 String message = MessageFormat.format( msgNoValidConfig, filler );
244 LOG.error( message );
245 return;
246 }
247 }
248 catch ( Exception e )
249 {
250 LOG.error( "Could not load config file. Reason: " + e.getMessage() );
251 return;
252 }
253
254 TemplateValidator validator = new TemplateValidator();
255 validator.setConfiguration( validatorConfig );
256
257 AgreementTemplateType offerTemplate = AgreementTemplateType.Factory.newInstance();
258 offerTemplate.setAgreementId( offer.getAgreementId() );
259 offerTemplate.setTemplateId( "" );
260 offerTemplate.setName( offer.getName() );
261 offerTemplate.setAgreementId( offer.getAgreementId() );
262 offerTemplate.addNewContext().set( offer.getContext() );
263 offerTemplate.addNewTerms().set( offer.getTerms() );
264 offerTemplate.addNewCreationConstraints();
265
266 AgreementOffer offerInstance = new AgreementOfferType( offerTemplate );
267
268 boolean result = validator.validate( offerInstance, template );
269 LOG.info( "Validation result: " + result );
270 }
271
272
273
274
275
276
277
278 private static AgreementTemplateType parseTemplate( File templateFile ) throws Exception
279 {
280 XmlObject parsedResult = XmlObject.Factory.parse( templateFile );
281
282 if ( parsedResult instanceof TemplateDocument )
283 {
284 return ( (TemplateDocument) parsedResult ).getTemplate();
285 }
286 else
287 {
288 Object[] filler =
289 new Object[] { ( parsedResult.schemaType().getName() != null ) ? parsedResult.schemaType()
290 .getName()
291 : parsedResult.schemaType().getDocumentElementName() };
292 String message =
293 MessageFormat.format(
294 "Template file of type {0} is not a valid Agreement Template Document. ", filler );
295 throw new Exception( message );
296 }
297 }
298
299
300
301
302 public TemplateValidator()
303 {
304
305
306
307
308
309
310
311
312 System.setProperty( "xmlbean.entityResolver", CatalogResolver.class.getName() );
313 if ( ResolverUtil.getGlobalEntityResolver() == null )
314 {
315 String warn0 =
316 "The XmlBeans global entity resolver is not set. "
317 + "This might cause problems in the WSAG4J offer validation process.";
318
319 String warn1 =
320 "Make sure that the 'xmlbean.entityResolver' system property is set to {0} "
321 + "before executing the first XmlObject.FACTORY.parse() operation.";
322
323 LOG.warn( warn0 );
324 LOG.warn( MessageFormat.format( warn1, new Object[] { CatalogResolver.class.getName() } ) );
325 }
326
327
328
329
330 options = new XmlOptions();
331 options.setLoadLineNumbers();
332 options.setLoadLineNumbers( XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT );
333 options.setLoadMessageDigest();
334 options.setSavePrettyPrint();
335 options.setSaveOuter();
336
337
338
339
340
341 options.setEntityResolver( new CatalogResolver() );
342
343
344
345
346 configuration = ValidatorType.Factory.newInstance();
347 configuration.addNewSchemaImports();
348 configuration.getSchemaImports().addNewSchemaFilename().setStringValue( XML_SCHEMA_FILENAME );
349 configuration.getSchemaImports().addNewSchemaFilename().setStringValue( WSAG_SCHEMA_FILENAME );
350 }
351
352
353
354
355
356
357
358
359
360
361
362
363 public boolean validate( AgreementOfferDocument offer, TemplateDocument template )
364 {
365 return validate( offer, template, new StringBuffer() );
366 }
367
368 private boolean validate( AgreementOfferDocument offer, TemplateDocument template, StringBuffer error )
369 {
370
371 LOG.debug( "start agreement offer validation process" );
372 LOG.debug( LogMessage.getMessage( "offer name: {0}", offer.getAgreementOffer().getName() ) );
373 LOG.debug( LogMessage.getMessage( "template name: {0}, id: {1}", template.getTemplate().getName(),
374 template.getTemplate().getTemplateId() ) );
375
376 try
377 {
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395 try
396 {
397 XmlObject parsedTemplate =
398 getWSAGCompiledTypeLoader().parse( template.xmlText( options ), TemplateDocument.type,
399 new XmlOptions().setLoadLineNumbers() );
400
401 if ( LOG.isTraceEnabled() )
402 {
403 LOG.trace( "Successfully parsed agreement template with WSAJ4J type system" );
404 }
405
406 XmlObject parsedOffer =
407 getWSAGCompiledTypeLoader().parse( offer.xmlText( options ), AgreementOfferDocument.type,
408 new XmlOptions().setLoadLineNumbers() );
409
410 if ( LOG.isTraceEnabled() )
411 {
412 LOG.trace( "Successfully parsed agreement offer with WSAJ4J type system" );
413 }
414
415 template = (TemplateDocument) parsedTemplate;
416 offer = (AgreementOfferDocument) parsedOffer;
417
418 if ( LOG.isTraceEnabled() )
419 {
420 LOG.trace( "Successfully converted template/offer using WSAJ4J build in type system" );
421 }
422 }
423 catch ( Exception e )
424 {
425 LOG.error( "Failed to parse the AgreementTemplateDocument or AgreementOfferDocument.", e );
426 LOG.error( "Agreement offer validation failed." );
427 return false;
428 }
429
430
431
432
433 if ( LOG.isTraceEnabled() )
434 {
435 LOG.trace( "Agreement template:\n" + template.xmlText( options ) );
436 }
437
438
439
440
441
442 boolean validTemplate = validate( template, error );
443
444 LOG.debug( LogMessage.getMessage( "Template validation result: {0}", validTemplate ) );
445
446 if ( !validTemplate )
447 {
448 LOG.error( "Agreement offer validation failed. The agreement template document is not valid." );
449 return false;
450 }
451
452
453
454
455 if ( LOG.isTraceEnabled() )
456 {
457 LOG.trace( "Agreement offer:\n" + offer.xmlText( options ) );
458 }
459
460
461
462
463
464 boolean validOffer = validate( offer, error );
465
466 LOG.debug( LogMessage.getMessage( "Offer validation result: {0}", validOffer ) );
467
468 if ( !validOffer )
469 {
470 LOG.error( "Agreement offer validation failed. The agreement offer document is not valid." );
471 return false;
472 }
473
474
475
476
477 OfferItemType[] items = template.getTemplate().getCreationConstraints().getItemArray();
478 for ( int i = 0; i < items.length; i++ )
479 {
480 if ( !validateConstraint( offer, items[i], error ) )
481 {
482
483 return false;
484 }
485 }
486
487 return true;
488
489 }
490 finally
491 {
492 LOG.debug( "Finished agreement offer validation process." );
493 }
494 }
495
496 private boolean validate( NegotiationOfferDocument counterOfferDoc,
497 NegotiationOfferDocument parentOfferDoc, StringBuffer error )
498 {
499 NegotiationOfferType counterOffer = counterOfferDoc.getNegotiationOffer();
500 NegotiationOfferType parentOffer = parentOfferDoc.getNegotiationOffer();
501
502 boolean validationResult = true;
503
504
505
506
507 String offerId = parentOffer.getOfferId();
508 String counterOfferId = counterOffer.getNegotiationOfferContext().getCounterOfferTo();
509
510 if ( !offerId.equals( counterOfferId ) )
511 {
512 String msgText = "(Counter) Offer combination is not valid [''{0}'' <-> ''{1}''].";
513 LOG.debug( LogMessage.getMessage( msgText, offerId, counterOfferId ) );
514
515 validationResult = false;
516 }
517
518 LOG.debug( "start agreement offer validation process" );
519 Enum parentCreator = parentOffer.getNegotiationOfferContext().getCreator();
520 LOG.debug( LogMessage.getMessage( "offer creator: {0}", parentCreator ) );
521 LOG.debug( LogMessage.getMessage( "counter offer name: {0}, id: {1}",
522 counterOffer.getNegotiationOfferContext().getCounterOfferTo(), counterOffer.getOfferId() ) );
523
524 try
525 {
526 try
527 {
528
529 XmlObject parsedCounterOffer = parseOffer( counterOfferDoc );
530 LOG.trace( "Successfully parsed agreement template with WSAG4J type system." );
531
532 XmlObject parsedOffer = parseOffer( parentOfferDoc );
533 LOG.trace( "Successfully parsed agreement offer with WSAG4J type system" );
534
535 counterOffer = ( (NegotiationOfferDocument) parsedCounterOffer ).getNegotiationOffer();
536 parentOffer = ( (NegotiationOfferDocument) parsedOffer ).getNegotiationOffer();
537 LOG.trace( "Successfully converted counter offer/offer using WSAJ4J build in type system" );
538 }
539 catch ( Exception e )
540 {
541 LOG.error( "Failed to parse the NegotiationOfferType or AgreementOfferDocument.", e );
542 LOG.error( "Agreement counter offer validation failed." );
543
544 validationResult = false;
545 }
546
547
548
549
550 if ( LOG.isTraceEnabled() )
551 {
552 LOG.trace( "Agreement counter offer:\n" + counterOffer.xmlText( options ) );
553 }
554
555
556
557
558
559 boolean validCounterOffer = validate( counterOffer, error );
560
561 LOG.debug( LogMessage.getMessage( "Counter offer validation result: {0}", validCounterOffer ) );
562
563 if ( !validCounterOffer )
564 {
565 LOG.error( "Counter offer validation failed. The counter offer document is not valid." );
566 validationResult = false;
567 }
568
569
570
571
572 LOG.trace( LogMessage.getMessage( "Agreement offer:\n{0}", parentOffer.xmlText( options ) ) );
573
574
575
576
577
578 boolean validOffer = validate( parentOffer, error );
579
580 LOG.debug( LogMessage.getMessage( "Offer validation result: {0}", validOffer ) );
581
582 if ( !validOffer )
583 {
584 validationResult = false;
585 LOG.error( "Agreement offer validation failed. The agreement offer document is not valid." );
586 }
587
588
589
590
591
592 NegotiationOfferItemType[] items = parentOffer.getNegotiationConstraints().getItemArray();
593 for ( int i = 0; i < items.length; i++ )
594 {
595 if ( !validateConstraint( counterOfferDoc, items[i], error ) )
596 {
597 if ( items[i].getType() == NegotiationConstraintType.OPTIONAL )
598 {
599 if ( LOG.isInfoEnabled() )
600 {
601 LOG.info( "Validation of an optional term failed. Continue with the term validation." );
602 }
603 continue;
604 }
605
606 validationResult = false;
607 break;
608 }
609 }
610 }
611 finally
612 {
613 final String message = "Finished agreement offer validation process. Result is: {0}";
614 LOG.debug( LogMessage.getMessage( message, validationResult ) );
615 }
616
617 return validationResult;
618 }
619
620
621
622
623
624
625 private NegotiationOfferDocument parseOffer( NegotiationOfferDocument offerDoc ) throws Exception
626 {
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645 return (NegotiationOfferDocument) getWSAGCompiledTypeLoader().parse( offerDoc.xmlText( options ),
646 NegotiationOfferDocument.type, new XmlOptions().setLoadLineNumbers() );
647 }
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663 public boolean validate( AgreementOffer offer, AgreementTemplateType template, StringBuffer error )
664 {
665 AgreementOfferDocument offerDoc = AgreementOfferDocument.Factory.newInstance( options );
666
667 offerDoc.addNewAgreementOffer();
668 offerDoc.getAgreementOffer().setName( offer.getName() );
669 offerDoc.getAgreementOffer().setContext( offer.getContext() );
670 offerDoc.getAgreementOffer().setTerms( offer.getTerms() );
671
672 TemplateDocument templateDoc = TemplateDocument.Factory.newInstance();
673 templateDoc.addNewTemplate().set( template );
674
675 return validate( offerDoc, templateDoc, error );
676 }
677
678
679
680
681
682
683
684
685
686
687
688
689 public boolean validate( AgreementOffer offer, AgreementTemplateType template )
690 {
691 return validate( offer, template, new StringBuffer() );
692 }
693
694
695
696
697
698
699
700
701
702
703
704
705 public boolean validate( NegotiationOfferType offer, AgreementTemplateType template )
706 {
707 AgreementOfferDocument offerDoc = AgreementOfferDocument.Factory.newInstance( options );
708
709 offerDoc.addNewAgreementOffer();
710 offerDoc.getAgreementOffer().setName( offer.getName() );
711 offerDoc.getAgreementOffer().setContext( offer.getContext() );
712 offerDoc.getAgreementOffer().setTerms( offer.getTerms() );
713
714 TemplateDocument templateDoc = TemplateDocument.Factory.newInstance();
715 templateDoc.addNewTemplate().set( template );
716
717 return validate( offerDoc, templateDoc );
718 }
719
720
721
722
723
724
725
726
727
728
729
730
731 public boolean validate( NegotiationOfferType offer, NegotiationOfferType counterOffer )
732 {
733 NegotiationOfferDocument offerDoc = NegotiationOfferDocument.Factory.newInstance( options );
734 offerDoc.addNewNegotiationOffer();
735 offerDoc.getNegotiationOffer().setOfferId( offer.getOfferId() );
736 offerDoc.getNegotiationOffer().setName( offer.getName() );
737 offerDoc.getNegotiationOffer().setContext( offer.getContext() );
738 offerDoc.getNegotiationOffer().setTerms( offer.getTerms() );
739 offerDoc.getNegotiationOffer().setNegotiationConstraints( offer.getNegotiationConstraints() );
740 offerDoc.getNegotiationOffer().setNegotiationOfferContext( offer.getNegotiationOfferContext() );
741
742 NegotiationOfferDocument counterOfferDoc = NegotiationOfferDocument.Factory.newInstance( options );
743 counterOfferDoc.addNewNegotiationOffer();
744 counterOfferDoc.getNegotiationOffer().setOfferId( counterOffer.getOfferId() );
745 counterOfferDoc.getNegotiationOffer().setName( counterOffer.getName() );
746 counterOfferDoc.getNegotiationOffer().setContext( counterOffer.getContext() );
747 counterOfferDoc.getNegotiationOffer().setTerms( counterOffer.getTerms() );
748 counterOfferDoc.getNegotiationOffer().setNegotiationConstraints(
749 counterOffer.getNegotiationConstraints() );
750 counterOfferDoc.getNegotiationOffer().setNegotiationOfferContext(
751 counterOffer.getNegotiationOfferContext() );
752
753 return validate( offerDoc, counterOfferDoc, new StringBuffer() );
754 }
755
756
757
758
759
760
761 public ValidatorType getConfiguration()
762 {
763 return configuration;
764 }
765
766
767
768
769
770
771
772
773 public void setConfiguration( ValidatorType configuration )
774 {
775 this.configuration = configuration;
776 }
777
778 private boolean validateConstraint( XmlObject target, OfferItemType item, StringBuffer error )
779 {
780
781 try
782 {
783 boolean result = true;
784
785 if ( LOG.isTraceEnabled() )
786 {
787 LOG.trace( "**************************************************************"
788 + "********************************************************************************" );
789 LOG.trace( "validation of item constraint:\n" + item.xmlText( options ) );
790 LOG.trace( "--------------------------------------------------------------"
791 + "--------------------------------------------------------------------------------" );
792 }
793
794 XmlObject[] items = target.selectPath( item.getLocation() );
795
796
797
798
799
800 result = checkItemCardinality( item, items );
801 if ( !result )
802 {
803 return result;
804 }
805
806
807
808
809 HashMap<SchemaType, SchemaTypeLoader> schemaLoaderMap =
810 new HashMap<SchemaType, SchemaTypeLoader>();
811 HashMap<SchemaType, SchemaType> schemaTypeMap = new HashMap<SchemaType, SchemaType>();
812
813 for ( int i = 0; i < items.length; i++ )
814 {
815
816 SchemaType sourcetype = getSourceType( items[i] );
817
818 if ( !schemaTypeMap.containsKey( sourcetype ) )
819 {
820
821 SchemaDocument schema = initializeSchema( sourcetype );
822
823 Schema generatedSchema =
824 createSchemaType( schema.getSchema(), sourcetype, item.getItemConstraint() );
825
826 if ( LOG.isTraceEnabled() )
827 {
828 LOG.trace( "generated schema for type [" + sourcetype.getName() + "]" );
829 LOG.trace( "--------------------------------------------------------------------" );
830 LOG.trace( "generated xml schema:\n" + generatedSchema.xmlText( options ) );
831 }
832
833 try
834 {
835 QName generatedTypeQName =
836 new QName( sourcetype.getName().getNamespaceURI(), GENERATED_TYPE_NAME, "wsag4j" );
837 SchemaTypeLoader schemaLoader = getLoader( generatedSchema );
838 SchemaType schemaType = schemaLoader.findType( generatedTypeQName );
839 schemaTypeMap.put( sourcetype, schemaType );
840 schemaLoaderMap.put( sourcetype, schemaLoader );
841 }
842 catch ( Exception e )
843 {
844 LOG.debug( LogMessage.getMessage(
845 "Failed to create schema for item constraint. Error: {0}", e.getMessage() ) );
846
847 LOG.debug( LogMessage.getMessage( "{0}", item.xmlText( options ) ) );
848
849 String message =
850 LogMessage.format(
851 "Failed to create schema for agreement offer validation. Error: {0}",
852 e.getMessage() );
853
854 LOG.error( message );
855 error.append( message );
856
857 return false;
858 }
859 }
860 }
861
862 for ( int i = 0; i < items.length; i++ )
863 {
864
865 XmlOptions serializeOptions = new XmlOptions( options );
866 serializeOptions.setSaveOuter();
867
868 String serializedItem = items[i].xmlText( serializeOptions );
869
870 if ( LOG.isTraceEnabled() )
871 {
872 LOG.trace( "restricted item:\n" + serializedItem );
873 LOG.trace( "document validation result: " + items[i].validate() );
874 }
875
876 try
877 {
878 SchemaType sourceType = getSourceType( items[i] );
879
880 SchemaType restrictionType = schemaTypeMap.get( sourceType );
881
882 XmlOptions schemaOptions = new XmlOptions( options );
883 schemaOptions.setLoadReplaceDocumentElement( null );
884 schemaOptions.setDocumentType( restrictionType );
885
886
887
888
889
890 SchemaTypeLoader schemaLoader = schemaLoaderMap.get( sourceType );
891
892 XmlObject check = schemaLoader.parse( serializedItem, restrictionType, schemaOptions );
893 result = result && validate( check, error );
894
895 }
896 catch ( Exception e )
897 {
898 LOG.error( "Could not parse target element: " + e.getMessage() );
899
900 result = false;
901 break;
902 }
903 }
904
905 if ( LOG.isTraceEnabled() )
906 {
907 LOG.trace( MessageFormat.format( "Item constraint validation result: {0}",
908 new Object[] { ( result ) ? "successful" : "failed" } ) );
909 }
910
911 return result;
912 }
913 catch ( Exception ex )
914 {
915 LOG.error( "Failed to validate creation constraint: " + ex.getMessage() );
916 return false;
917 }
918 }
919
920
921
922
923
924 private SchemaDocument initializeSchema( SchemaType sourcetype )
925 {
926 SchemaDocument schema = SchemaDocument.Factory.newInstance();
927 schema.addNewSchema();
928
929
930
931
932
933
934
935
936
937
938
939
940 schema.getSchema().setTargetNamespace( sourcetype.getName().getNamespaceURI() );
941 schema.getSchema().setVersion( "1.0" );
942
943 schema.getSchema().setElementFormDefault( FormChoice.UNQUALIFIED );
944 schema.getSchema().setAttributeFormDefault( FormChoice.UNQUALIFIED );
945
946 String sourceNamespace = sourcetype.getName().getNamespaceURI();
947 if ( knownSchemaFormChoice.containsKey( sourceNamespace ) )
948 {
949 Boolean[] efq = knownSchemaFormChoice.get( sourceNamespace );
950 boolean isElementQualified = efq[0].booleanValue();
951 boolean isAttributeQualified = efq[1].booleanValue();
952
953 if ( isElementQualified )
954 {
955 schema.getSchema().setElementFormDefault( FormChoice.QUALIFIED );
956 }
957 if ( isAttributeQualified )
958 {
959 schema.getSchema().setAttributeFormDefault( FormChoice.QUALIFIED );
960 }
961 }
962 return schema;
963 }
964
965
966
967
968
969
970 private boolean checkItemCardinality( OfferItemType item, XmlObject[] items )
971 {
972
973 ConstraintAnnotationType annotation = ConstraintAnnotationType.Factory.newInstance();
974 annotation.setMultiplicity( ItemCardinalityType.X_0_TO_N );
975 XmlObject[] cadinalityDoc =
976 item.selectChildren( ConstraintAnnotationDocument.type.getDocumentElementName() );
977 if ( cadinalityDoc.length > 0 )
978 {
979 annotation = (ConstraintAnnotationType) cadinalityDoc[0];
980 }
981
982 switch ( annotation.getMultiplicity().intValue() )
983 {
984 case ItemCardinalityType.INT_X_0_TO_1:
985
986 if ( items.length > 1 )
987 {
988 LogMessage message =
989 LogMessage.getMessage( "Selected {0} elements for item constraint {1}, "
990 + "but constraint annotation specified multiplicity of 0..1", items.length,
991 item.getName() );
992 LOG.error( message );
993
994 return false;
995 }
996 return true;
997
998 case ItemCardinalityType.INT_X_1:
999
1000 if ( items.length != 1 )
1001 {
1002 LogMessage message =
1003 LogMessage.getMessage( "Selected {0} elements for item constraint {1}, "
1004 + "but constraint annotation specified multiplicity of 1", items.length,
1005 item.getName() );
1006 LOG.error( message );
1007
1008 return false;
1009 }
1010 return true;
1011
1012 case ItemCardinalityType.INT_X_1_TO_N:
1013
1014 if ( items.length == 0 )
1015 {
1016 LogMessage message =
1017 LogMessage.getMessage( "Selected 0 elements for item constraint {0}, "
1018 + "but constraint annotation specified multiplicity of 1..N", item.getName() );
1019 LOG.error( message );
1020
1021 return false;
1022 }
1023 return true;
1024
1025 default:
1026
1027
1028
1029 return true;
1030 }
1031 }
1032
1033 private boolean validate( XmlObject object, StringBuffer error )
1034 {
1035 ArrayList<XmlError> list = new ArrayList<XmlError>();
1036
1037 XmlOptions voptions = new XmlOptions( options );
1038 voptions.setErrorListener( list );
1039
1040 if ( !object.validate( voptions ) )
1041 {
1042 for ( int i = 0; i < list.size(); i++ )
1043 {
1044 if ( LOG.isDebugEnabled() )
1045 {
1046 XmlError e = list.get( i );
1047 String message =
1048 MessageFormat.format( "Type validation error [line {0}]: {1}. Code: {2}",
1049 e.getLine(), e.getMessage(), e.getErrorCode() );
1050 error.append( message + "\n" );
1051 LOG.debug( message );
1052 }
1053 }
1054
1055 return false;
1056 }
1057
1058 return true;
1059 }
1060
1061 private SchemaType getSourceType( XmlObject item ) throws Exception
1062 {
1063 SchemaType sourcetype = item.schemaType().getPrimitiveType();
1064
1065 if ( sourcetype == null )
1066 {
1067 sourcetype = item.schemaType();
1068
1069 if ( sourcetype.isNoType() )
1070 {
1071 LOG.error( "No type information found for restricted item:" );
1072 LOG.error( item.xmlText( options ) );
1073
1074 throw new Exception( "No type information found for item: " + item.xmlText() );
1075 }
1076 }
1077
1078 return sourcetype;
1079 }
1080
1081 private Schema createSchemaType( Schema schema, SchemaType type, ItemConstraint constraint )
1082 {
1083
1084 Schema result = null;
1085
1086
1087
1088 if ( constraint.isSetAll() || constraint.isSetChoice() || constraint.isSetGroup()
1089 || constraint.isSetSequence() )
1090 {
1091
1092 result = createTypeDefParticleSchema( schema, type, constraint );
1093 }
1094 else
1095 {
1096 result = createSimpleRestrictionModelSchema( schema, type, constraint );
1097 }
1098
1099 return result;
1100 }
1101
1102 private Schema createSimpleRestrictionModelSchema( Schema schema, SchemaType type,
1103 ItemConstraint constraint )
1104 {
1105 QName typeName =
1106 new QName( "http://wsag4j.scai.fraunhofer.de/generated", "GeneratedConstraintValidationType",
1107 "wsag4j" );
1108
1109 SimpleType simple = schema.addNewSimpleType();
1110 simple.setName( typeName.getLocalPart() );
1111 simple.addNewRestriction();
1112
1113 if ( constraint.isSetSimpleType() )
1114 {
1115 simple.getRestriction().setSimpleType( constraint.getSimpleType() );
1116 }
1117 else
1118 {
1119 simple.getRestriction().setBase( type.getPrimitiveType().getName() );
1120 }
1121
1122 simple.getRestriction().setLengthArray( constraint.getLengthArray() );
1123
1124 simple.getRestriction().setMinInclusiveArray( constraint.getMinInclusiveArray() );
1125 simple.getRestriction().setMaxInclusiveArray( constraint.getMaxInclusiveArray() );
1126
1127 simple.getRestriction().setMinExclusiveArray( constraint.getMinExclusiveArray() );
1128 simple.getRestriction().setMaxExclusiveArray( constraint.getMaxExclusiveArray() );
1129
1130 simple.getRestriction().setEnumerationArray( constraint.getEnumerationArray() );
1131
1132 simple.getRestriction().setLengthArray( constraint.getLengthArray() );
1133 simple.getRestriction().setMaxLengthArray( constraint.getMaxLengthArray() );
1134 simple.getRestriction().setMinLengthArray( constraint.getMinLengthArray() );
1135
1136 simple.getRestriction().setFractionDigitsArray( constraint.getFractionDigitsArray() );
1137
1138 simple.getRestriction().setPatternArray( constraint.getPatternArray() );
1139 simple.getRestriction().setTotalDigitsArray( constraint.getTotalDigitsArray() );
1140 simple.getRestriction().setWhiteSpaceArray( constraint.getWhiteSpaceArray() );
1141
1142 return schema;
1143 }
1144
1145 private Schema createTypeDefParticleSchema( Schema schema, SchemaType type, ItemConstraint constraint )
1146 {
1147 ComplexType complex = schema.addNewComplexType();
1148 complex.setName( GENERATED_TYPE_NAME );
1149
1150 ComplexRestrictionType restriction = complex.addNewComplexContent().addNewRestriction();
1151 restriction.setBase( type.getName() );
1152
1153 if ( constraint.isSetAll() )
1154 {
1155 restriction.setAll( constraint.getAll() );
1156 }
1157 if ( constraint.isSetChoice() )
1158 {
1159 restriction.setChoice( constraint.getChoice() );
1160 }
1161 if ( constraint.isSetSequence() )
1162 {
1163 restriction.setSequence( constraint.getSequence() );
1164 }
1165 if ( constraint.isSetGroup() )
1166 {
1167 restriction.setGroup( constraint.getGroup() );
1168 }
1169
1170 return schema;
1171 }
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 private SchemaTypeLoader getWSAGCompiledTypeLoader() throws Exception
1183 {
1184 SchemaTypeLoader dynamicLoader = getLoader();
1185 SchemaTypeLoader compiledLoader = AgreementTemplateType.type.getTypeSystem();
1186 SchemaTypeLoader compiledNegotiationLoader = NegotiationOfferDocument.type.getTypeSystem();
1187 SchemaTypeLoader compiledLoaderEngine = ConstraintAnnotationType.type.getTypeSystem();
1188
1189 return XmlBeans.typeLoaderUnion( new SchemaTypeLoader[] { compiledLoader, compiledNegotiationLoader,
1190 compiledLoaderEngine, dynamicLoader } );
1191 }
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202 private synchronized SchemaTypeLoader getLoader( Schema schema ) throws Exception
1203 {
1204
1205
1206
1207
1208
1209 SchemaTypeLoader wsagLoader = getLoader();
1210
1211
1212
1213
1214 SchemaDocument importSchema = SchemaDocument.Factory.parse( schema.getDomNode() );
1215 SchemaTypeSystem schemats =
1216 XmlBeans.compileXsd( new XmlObject[] { importSchema }, wsagLoader, options );
1217
1218
1219
1220
1221 return XmlBeans.typeLoaderUnion( new SchemaTypeLoader[] { schemats, wsagLoader } );
1222 }
1223
1224
1225
1226
1227
1228
1229
1230
1231 private synchronized SchemaTypeLoader getLoader() throws Exception
1232 {
1233
1234
1235
1236
1237 if ( loader == null )
1238 {
1239
1240
1241
1242
1243
1244
1245 Vector<SchemaTypeSystem> wsag4jTypeSystems = new Vector<SchemaTypeSystem>();
1246
1247
1248
1249
1250 wsag4jTypeSystems.add( XmlBeans.getBuiltinTypeSystem() );
1251
1252
1253
1254
1255
1256 SchemaImportType imports = getConfiguration().getSchemaImports();
1257 if ( imports != null )
1258 {
1259 String[] schemaFilenames = imports.getSchemaFilenameArray();
1260 for ( int i = 0; i < schemaFilenames.length; i++ )
1261 {
1262 try
1263 {
1264 InputStream resource =
1265 TemplateValidator.class.getResourceAsStream( schemaFilenames[i] );
1266 SchemaDocument importSchema = SchemaDocument.Factory.parse( resource );
1267
1268 if ( !knownSchemaFormChoice.containsKey( importSchema.getSchema()
1269 .getTargetNamespace() ) )
1270 {
1271 boolean isAttributeQualified = false;
1272 boolean isElementQualified = false;
1273
1274 if ( importSchema.getSchema().isSetAttributeFormDefault() )
1275 {
1276 isAttributeQualified =
1277 importSchema.getSchema().getAttributeFormDefault() == FormChoice.QUALIFIED;
1278 }
1279
1280 if ( importSchema.getSchema().isSetElementFormDefault() )
1281 {
1282 isElementQualified =
1283 importSchema.getSchema().getElementFormDefault() == FormChoice.QUALIFIED;
1284 }
1285
1286 knownSchemaFormChoice.put(
1287 importSchema.getSchema().getTargetNamespace(),
1288 new Boolean[] { Boolean.valueOf( isElementQualified ),
1289 Boolean.valueOf( isAttributeQualified ) } );
1290 }
1291
1292 SchemaTypeSystem schemats =
1293 XmlBeans.compileXsd( new XmlObject[] { importSchema }, loader, options );
1294 wsag4jTypeSystems.add( schemats );
1295
1296 LOG.debug( LogMessage.getMessage( "Loaded schema file {0}", schemaFilenames[i] ) );
1297
1298 }
1299 catch ( Exception e )
1300 {
1301 LOG.error( LogMessage.getMessage( "Could not load imported schema {0}. Error: {1}",
1302 schemaFilenames[i], e.getMessage() ) );
1303 LOG.debug( e );
1304 LOG.error( "Hint: check the order of the import schema entries in the wsag4j config file." );
1305 }
1306 }
1307 }
1308
1309 SchemaTypeLoader[] typeSystem =
1310 wsag4jTypeSystems.toArray( new SchemaTypeLoader[wsag4jTypeSystems.size()] );
1311
1312 loader = XmlBeans.typeLoaderUnion( typeSystem );
1313 }
1314
1315 return loader;
1316 }
1317 }