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.model.modlet;
32
33 import java.text.MessageFormat;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.Iterator;
39 import java.util.LinkedList;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.ResourceBundle;
44 import java.util.Set;
45 import java.util.logging.Level;
46 import javax.xml.bind.JAXBElement;
47 import javax.xml.bind.JAXBException;
48 import javax.xml.bind.util.JAXBSource;
49 import javax.xml.namespace.QName;
50 import javax.xml.transform.Source;
51 import org.jomc.model.Dependency;
52 import org.jomc.model.Implementation;
53 import org.jomc.model.ImplementationReference;
54 import org.jomc.model.Implementations;
55 import org.jomc.model.Inheritable;
56 import org.jomc.model.InheritanceModel;
57 import org.jomc.model.Message;
58 import org.jomc.model.MessageReference;
59 import org.jomc.model.ModelObject;
60 import org.jomc.model.Module;
61 import org.jomc.model.Modules;
62 import org.jomc.model.Multiplicity;
63 import org.jomc.model.ObjectFactory;
64 import org.jomc.model.Property;
65 import org.jomc.model.PropertyException;
66 import org.jomc.model.PropertyReference;
67 import org.jomc.model.Specification;
68 import org.jomc.model.SpecificationReference;
69 import org.jomc.model.Specifications;
70 import org.jomc.model.Text;
71 import org.jomc.modlet.Model;
72 import org.jomc.modlet.ModelContext;
73 import org.jomc.modlet.ModelException;
74 import org.jomc.modlet.ModelValidationReport;
75 import org.jomc.modlet.ModelValidator;
76 import org.jomc.util.ParseException;
77 import org.jomc.util.TokenMgrError;
78 import org.jomc.util.VersionParser;
79 import org.w3c.dom.Element;
80
81
82
83
84
85
86
87
88 public class DefaultModelValidator implements ModelValidator
89 {
90
91
92 public DefaultModelValidator()
93 {
94 super();
95 }
96
97 public ModelValidationReport validateModel( final ModelContext context, final Model model ) throws ModelException
98 {
99 if ( context == null )
100 {
101 throw new NullPointerException( "context" );
102 }
103 if ( model == null )
104 {
105 throw new NullPointerException( "model" );
106 }
107
108 try
109 {
110 final Source source = new JAXBSource( context.createContext( model.getIdentifier() ),
111 new org.jomc.modlet.ObjectFactory().createModel( model ) );
112
113 final ModelValidationReport report = context.validateModel( model.getIdentifier(), source );
114 final Modules modules = ModelHelper.getModules( model );
115
116 if ( modules != null )
117 {
118 final ValidationContext validationContext = new ValidationContext( context, modules, report );
119 assertModulesValid( validationContext );
120 assertSpecificationsValid( validationContext );
121 assertImplementationsValid( validationContext );
122 }
123
124 return report;
125 }
126 catch ( final JAXBException e )
127 {
128 String message = getMessage( e );
129 if ( message == null && e.getLinkedException() != null )
130 {
131 message = getMessage( e.getLinkedException() );
132 }
133
134 if ( context.isLoggable( Level.FINE ) )
135 {
136 context.log( Level.FINE, message, e );
137 }
138
139 throw new ModelException( message, e );
140 }
141 }
142
143 private static void assertModulesValid( final ValidationContext validationContext )
144 {
145 for ( int i = 0, s0 = validationContext.getModules().getModule().size(); i < s0; i++ )
146 {
147 final Module m = validationContext.getModules().getModule().get( i );
148
149 if ( m.getImplementations() != null )
150 {
151 for ( int j = 0, s1 = m.getImplementations().getReference().size(); j < s1; j++ )
152 {
153 final ImplementationReference r = m.getImplementations().getReference().get( j );
154 addDetail( validationContext.getReport(), "MODULE_IMPLEMENTATION_REFERENCE_DECLARATION_CONSTRAINT",
155 Level.SEVERE, new ObjectFactory().createModule( m ),
156 "moduleImplementationReferenceDeclarationConstraint", m.getName(), r.getIdentifier() );
157
158 }
159 }
160
161 if ( m.getMessages() != null )
162 {
163 for ( int j = 0, s1 = m.getMessages().getMessage().size(); j < s1; j++ )
164 {
165 final Message msg = m.getMessages().getMessage().get( j );
166
167 if ( msg.isFinal() )
168 {
169 addDetail( validationContext.getReport(), "MODULE_FINAL_MESSAGE_DECLARATION_CONSTRAINT",
170 Level.SEVERE, new ObjectFactory().createModule( m ), "moduleFinalMessageConstraint",
171 m.getName(), msg.getName() );
172
173 }
174
175 if ( msg.isOverride() )
176 {
177 addDetail( validationContext.getReport(), "MODULE_OVERRIDE_MESSAGE_DECLARATION_CONSTRAINT",
178 Level.SEVERE, new ObjectFactory().createModule( m ),
179 "moduleOverrideMessageConstraint", m.getName(), msg.getName() );
180
181 }
182
183 if ( msg.getTemplate() != null )
184 {
185 for ( int k = 0, s2 = msg.getTemplate().getText().size(); k < s2; k++ )
186 {
187 final Text t = msg.getTemplate().getText().get( k );
188
189 try
190 {
191 new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
192 }
193 catch ( final IllegalArgumentException e )
194 {
195 final String message = getMessage( e );
196
197 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
198 {
199 validationContext.getModelContext().log( Level.FINE, message, e );
200 }
201
202 addDetail( validationContext.getReport(), "MODULE_MESSAGE_TEMPLATE_CONSTRAINT",
203 Level.SEVERE, new ObjectFactory().createModule( m ),
204 "moduleMessageTemplateConstraint", m.getName(), msg.getName(), t.getValue(),
205 message );
206
207 }
208 }
209 }
210 }
211
212 for ( int j = 0, s1 = m.getMessages().getReference().size(); j < s1; j++ )
213 {
214 final MessageReference r = m.getMessages().getReference().get( j );
215 addDetail( validationContext.getReport(), "MODULE_MESSAGE_REFERENCE_DECLARATION_CONSTRAINT",
216 Level.SEVERE, new ObjectFactory().createModule( m ),
217 "moduleMessageReferenceDeclarationConstraint", m.getName(), r.getName() );
218
219 }
220 }
221
222 if ( m.getProperties() != null )
223 {
224 for ( int j = 0, s1 = m.getProperties().getProperty().size(); j < s1; j++ )
225 {
226 final Property p = m.getProperties().getProperty().get( j );
227
228 if ( p.isFinal() )
229 {
230 addDetail( validationContext.getReport(), "MODULE_FINAL_PROPERTY_DECLARATION_CONSTRAINT",
231 Level.SEVERE, new ObjectFactory().createModule( m ), "moduleFinalPropertyConstraint",
232 m.getName(), p.getName() );
233
234 }
235
236 if ( p.isOverride() )
237 {
238 addDetail( validationContext.getReport(), "MODULE_OVERRIDE_PROPERTY_DECLARATION_CONSTRAINT",
239 Level.SEVERE, new ObjectFactory().createModule( m ),
240 "moduleOverridePropertyConstraint", m.getName(), p.getName() );
241
242 }
243
244 if ( p.getValue() != null && p.getAny() != null )
245 {
246 addDetail( validationContext.getReport(), "MODULE_PROPERTY_VALUE_CONSTRAINT", Level.SEVERE,
247 new ObjectFactory().createModule( m ), "modulePropertyValueConstraint", m.getName(),
248 p.getName() );
249
250 }
251
252 if ( p.getAny() != null && p.getType() == null )
253 {
254 addDetail( validationContext.getReport(), "MODULE_PROPERTY_TYPE_CONSTRAINT", Level.SEVERE,
255 new ObjectFactory().createModule( m ), "modulePropertyTypeConstraint", m.getName(),
256 p.getName() );
257
258 }
259
260 try
261 {
262 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
263 }
264 catch ( final PropertyException e )
265 {
266 final String message = getMessage( e );
267
268 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
269 {
270 validationContext.getModelContext().log( Level.FINE, message, e );
271 }
272
273 addDetail( validationContext.getReport(), "MODULE_PROPERTY_JAVA_VALUE_CONSTRAINT", Level.SEVERE,
274 new ObjectFactory().createModule( m ), "modulePropertyJavaValueConstraint",
275 m.getName(), p.getName(), message );
276
277 }
278 }
279
280 for ( int j = 0, s1 = m.getProperties().getReference().size(); j < s1; j++ )
281 {
282 final PropertyReference r = m.getProperties().getReference().get( j );
283 addDetail( validationContext.getReport(), "MODULE_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT",
284 Level.SEVERE, new ObjectFactory().createModule( m ),
285 "modulePropertyReferenceDeclarationConstraint", m.getName(), r.getName() );
286
287 }
288 }
289
290 if ( m.getSpecifications() != null )
291 {
292 for ( int j = 0, s1 = m.getSpecifications().getReference().size(); j < s1; j++ )
293 {
294 final SpecificationReference r = m.getSpecifications().getReference().get( j );
295 addDetail( validationContext.getReport(), "MODULE_SPECIFICATION_REFERENCE_DECLARATION_CONSTRAINT",
296 Level.SEVERE, new ObjectFactory().createModule( m ),
297 "moduleSpecificationReferenceDeclarationConstraint", m.getName(), r.getIdentifier() );
298
299 }
300 }
301 }
302 }
303
304 private static void assertImplementationsValid( final ValidationContext validationContext )
305 {
306 final Implementations implementations = validationContext.getModules().getImplementations();
307
308 if ( implementations != null )
309 {
310 final Map<String, Implementation> implementationClassDeclarations = new HashMap<String, Implementation>();
311
312 for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
313 {
314 final Implementation impl = implementations.getImplementation().get( i );
315 final InheritanceModel imodel = validationContext.getInheritanceModel();
316 final List<String> cyclePath = new LinkedList<String>();
317 final Module moduleOfImpl =
318 validationContext.getModules().getModuleOfImplementation( impl.getIdentifier() );
319
320 if ( isInheritanceCycle( validationContext, impl, null, cyclePath ) )
321 {
322 final StringBuilder b = new StringBuilder( cyclePath.size() * 50 );
323
324 for ( int j = 0, s1 = cyclePath.size(); j < s1; j++ )
325 {
326 b.append( " -> " ).append( "'" ).append( cyclePath.get( j ) ).append( "'" );
327 }
328
329 addDetail( validationContext.getReport(), "IMPLEMENTATION_INHERITANCE_CYCLE_CONSTRAINT",
330 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
331 "implementationInheritanceCycleConstraint", impl.getIdentifier(),
332 moduleOfImpl.getName(), b.substring( " -> ".length() ) );
333
334 }
335
336 if ( impl.isClassDeclaration() )
337 {
338 if ( impl.getClazz() == null )
339 {
340 addDetail( validationContext.getReport(), "IMPLEMENTATION_CLASS_CONSTRAINT", Level.SEVERE,
341 new ObjectFactory().createImplementation( impl ), "implementationClassConstraint",
342 impl.getIdentifier(), moduleOfImpl.getName() );
343
344 }
345 else
346 {
347 final Implementation prev = implementationClassDeclarations.get( impl.getClazz() );
348
349 if ( prev != null && !prev.getIdentifier().equals( impl.getIdentifier() ) )
350 {
351 final Module moduleOfPrev =
352 validationContext.getModules().getModuleOfImplementation( prev.getIdentifier() );
353
354 addDetail( validationContext.getReport(), "IMPLEMENTATION_CLASS_DECLARATION_CONSTRAINT",
355 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
356 "implementationClassDeclarationConstraint", impl.getIdentifier(),
357 moduleOfImpl.getName(), impl.getClazz(), prev.getIdentifier(),
358 moduleOfPrev.getName() );
359
360 }
361 else
362 {
363 implementationClassDeclarations.put( impl.getClazz(), impl );
364 }
365 }
366 }
367
368 if ( impl.isAbstract() && impl.getLocation() != null )
369 {
370 addDetail( validationContext.getReport(), "IMPLEMENTATION_ABSTRACT_LOCATION_DECLARATION_CONSTRAINT",
371 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
372 "implementationAbstractLocationDeclarationConstraint", impl.getIdentifier(),
373 moduleOfImpl.getName(), impl.getLocation() );
374
375 }
376
377 if ( impl.getDependencies() != null )
378 {
379 for ( int j = 0, s1 = impl.getDependencies().getDependency().size(); j < s1; j++ )
380 {
381 final Dependency d = impl.getDependencies().getDependency().get( j );
382
383 final Set<InheritanceModel.Node<Dependency>> effDependencies =
384 imodel.getDependencyNodes( impl.getIdentifier(), d.getName() );
385
386 for ( final InheritanceModel.Node<Dependency> effDependency : effDependencies )
387 {
388 final Set<InheritanceModel.Node<Dependency>> overriddenDependencies =
389 modifiableSet( effDependency.getOverriddenNodes() );
390
391 if ( d.isOverride() && effDependency.getOverriddenNodes().isEmpty() )
392 {
393 addDetail( validationContext.getReport(),
394 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_CONSTRAINT",
395 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
396 "implementationDependencyOverrideConstraint", impl.getIdentifier(),
397 moduleOfImpl.getName(), d.getName() );
398
399 }
400
401 if ( !( d.isOverride() || overriddenDependencies.isEmpty() ) )
402 {
403 for ( final InheritanceModel.Node<Dependency> overriddenDependency :
404 overriddenDependencies )
405 {
406 Implementation overriddenImplementation = overriddenDependency.getImplementation();
407 if ( overriddenDependency.getClassDeclaration() != null )
408 {
409 overriddenImplementation = overriddenDependency.getClassDeclaration();
410 }
411
412 final Module moduleOfDependency =
413 validationContext.getModules().getModuleOfImplementation(
414 overriddenImplementation.getIdentifier() );
415
416 addDetail( validationContext.getReport(),
417 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_WARNING",
418 Level.WARNING, new ObjectFactory().createImplementation( impl ),
419 "implementationDependencyOverrideWarning", impl.getIdentifier(),
420 moduleOfImpl.getName(), d.getName(),
421 overriddenImplementation.getIdentifier(),
422 moduleOfDependency.getName(),
423 getNodePathString( overriddenDependency ) );
424
425 }
426 }
427
428 retainFinalNodes( overriddenDependencies );
429
430 for ( final InheritanceModel.Node<Dependency> overriddenDependency :
431 overriddenDependencies )
432 {
433 Implementation overriddenImplementation = overriddenDependency.getImplementation();
434 if ( overriddenDependency.getClassDeclaration() != null )
435 {
436 overriddenImplementation = overriddenDependency.getClassDeclaration();
437 }
438
439 final Module moduleOfDependency =
440 validationContext.getModules().getModuleOfImplementation(
441 overriddenImplementation.getIdentifier() );
442
443 addDetail( validationContext.getReport(),
444 "IMPLEMENTATION_DEPENDENCY_INHERITANCE_CONSTRAINT", Level.SEVERE,
445 new ObjectFactory().createImplementation( impl ),
446 "implementationDependencyFinalConstraint", impl.getIdentifier(),
447 moduleOfImpl.getName(), d.getName(),
448 overriddenImplementation.getIdentifier(),
449 moduleOfDependency.getName(),
450 getNodePathString( overriddenDependency ) );
451
452 }
453 }
454
455 assertDependencyValid( validationContext, impl, d );
456 }
457 }
458
459 if ( impl.getImplementations() != null )
460 {
461 final Set<String> effImplementationReferences =
462 imodel.getImplementationReferenceIdentifiers( impl.getIdentifier() );
463
464 for ( final String effImplementationReference : effImplementationReferences )
465 {
466 final Implementation ancestorImplementation =
467 validationContext.getModules().getImplementation( effImplementationReference );
468
469 if ( ancestorImplementation != null && ancestorImplementation.isFinal() )
470 {
471 final Module moduleOfFinal = validationContext.getModules().getModuleOfImplementation(
472 ancestorImplementation.getIdentifier() );
473
474 addDetail( validationContext.getReport(),
475 "IMPLEMENTATION_IMPLEMENTATION_INHERITANCE_CONSTRAINT", Level.SEVERE,
476 new ObjectFactory().createImplementation( impl ),
477 "implementationFinalImplementationConstraint", impl.getIdentifier(),
478 moduleOfImpl.getName(), ancestorImplementation.getIdentifier(),
479 moduleOfFinal.getName() );
480
481 }
482 }
483
484 for ( int j = 0, s1 = impl.getImplementations().getImplementation().size(); j < s1; j++ )
485 {
486 final Implementation pi = impl.getImplementations().getImplementation().get( j );
487
488 addDetail( validationContext.getReport(),
489 "IMPLEMENTATION_IMPLEMENTATION_DECLARATION_CONSTRAINT", Level.SEVERE,
490 new ObjectFactory().createImplementation( impl ),
491 "implementationImplementationDeclarationConstraint", impl.getIdentifier(),
492 moduleOfImpl.getName(), pi.getIdentifier() );
493
494 }
495
496 for ( int j = 0, s1 = impl.getImplementations().getReference().size(); j < s1; j++ )
497 {
498 final ImplementationReference r = impl.getImplementations().getReference().get( j );
499
500 final Set<InheritanceModel.Node<ImplementationReference>> effReferences =
501 imodel.getImplementationReferenceNodes( impl.getIdentifier(), r.getIdentifier() );
502
503 for ( final InheritanceModel.Node<ImplementationReference> effReference : effReferences )
504 {
505 final Set<InheritanceModel.Node<ImplementationReference>> overriddenReferences =
506 modifiableSet( effReference.getOverriddenNodes() );
507
508 if ( r.isOverride() && overriddenReferences.isEmpty() )
509 {
510 addDetail( validationContext.getReport(),
511 "IMPLEMENTATION_IMPLEMENTATION_OVERRIDE_CONSTRAINT", Level.SEVERE,
512 new ObjectFactory().createImplementation( impl ),
513 "implementationImplementationOverrideConstraint", impl.getIdentifier(),
514 moduleOfImpl.getName(), r.getIdentifier() );
515
516 }
517
518 if ( !( r.isOverride() || overriddenReferences.isEmpty() ) )
519 {
520 for ( final InheritanceModel.Node<ImplementationReference> overriddenReference :
521 overriddenReferences )
522 {
523 Implementation overriddenImplementation = overriddenReference.getImplementation();
524 if ( overriddenReference.getClassDeclaration() != null )
525 {
526 overriddenImplementation = overriddenReference.getClassDeclaration();
527 }
528
529 final Module moduleOfReference =
530 validationContext.getModules().getModuleOfImplementation(
531 overriddenImplementation.getIdentifier() );
532
533 addDetail( validationContext.getReport(),
534 "IMPLEMENTATION_IMPLEMENTATION_REFERENCE_OVERRIDE_WARNING",
535 Level.WARNING, new ObjectFactory().createImplementation( impl ),
536 "implementationImplementationOverrideWarning", impl.getIdentifier(),
537 moduleOfImpl.getName(), r.getIdentifier(),
538 overriddenImplementation.getIdentifier(),
539 moduleOfReference.getName(),
540 getNodePathString( overriddenReference ) );
541
542 }
543 }
544
545 retainFinalNodes( overriddenReferences );
546
547 for ( final InheritanceModel.Node<ImplementationReference> overriddenReference :
548 overriddenReferences )
549 {
550 Implementation overriddenImplementation = overriddenReference.getImplementation();
551 if ( overriddenReference.getClassDeclaration() != null )
552 {
553 overriddenImplementation = overriddenReference.getClassDeclaration();
554 }
555
556 final Module moduleOfReference =
557 validationContext.getModules().getModuleOfImplementation(
558 overriddenImplementation.getIdentifier() );
559
560 addDetail( validationContext.getReport(),
561 "IMPLEMENTATION_IMPLEMENTATION_REFERENCE_INHERITANCE_CONSTRAINT",
562 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
563 "implementationFinalImplementatioReferenceConstraint", impl.getIdentifier(),
564 moduleOfImpl.getName(), r.getIdentifier(),
565 overriddenImplementation.getIdentifier(),
566 moduleOfReference.getName(), getNodePathString( overriddenReference ) );
567
568 }
569 }
570 }
571 }
572
573 if ( impl.getMessages() != null )
574 {
575 for ( int j = 0, s1 = impl.getMessages().getMessage().size(); j < s1; j++ )
576 {
577 final Message m = impl.getMessages().getMessage().get( j );
578
579 if ( impl.getMessages().getReference( m.getName() ) != null )
580 {
581 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGES_UNIQUENESS_CONSTRAINT",
582 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
583 "implementationMessagesUniquenessConstraint", impl.getIdentifier(),
584 moduleOfImpl.getName(), m.getName() );
585
586 }
587
588 if ( m.getTemplate() != null )
589 {
590 for ( int k = 0, s2 = m.getTemplate().getText().size(); k < s2; k++ )
591 {
592 final Text t = m.getTemplate().getText().get( k );
593
594 try
595 {
596 new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
597 }
598 catch ( final IllegalArgumentException e )
599 {
600 final String message = getMessage( e );
601
602 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
603 {
604 validationContext.getModelContext().log( Level.FINE, message, e );
605 }
606
607 addDetail( validationContext.getReport(),
608 "IMPLEMENTATION_MESSAGE_TEMPLATE_CONSTRAINT", Level.SEVERE,
609 new ObjectFactory().createImplementation( impl ),
610 "implementationMessageTemplateConstraint", impl.getIdentifier(),
611 moduleOfImpl.getName(), m.getName(), t.getValue(),
612 message != null && message.length() > 0 ? " " + message : "" );
613
614 }
615 }
616 }
617
618 final Set<InheritanceModel.Node<Message>> effMessages =
619 imodel.getMessageNodes( impl.getIdentifier(), m.getName() );
620
621 for ( final InheritanceModel.Node<Message> effMessage : effMessages )
622 {
623 final Set<InheritanceModel.Node<Message>> overriddenMessages =
624 modifiableSet( effMessage.getOverriddenNodes() );
625
626 if ( m.isOverride() && overriddenMessages.isEmpty() )
627 {
628 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_CONSTRAINT",
629 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
630 "implementationMessageOverrideConstraint", impl.getIdentifier(),
631 moduleOfImpl.getName(), m.getName() );
632
633 }
634
635 if ( !( m.isOverride() || overriddenMessages.isEmpty() ) )
636 {
637 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
638 {
639 Implementation overriddenImplementation = overriddenMessage.getImplementation();
640 if ( overriddenMessage.getClassDeclaration() != null )
641 {
642 overriddenImplementation = overriddenMessage.getClassDeclaration();
643 }
644
645 final Module moduleOfMessage =
646 validationContext.getModules().getModuleOfImplementation(
647 overriddenImplementation.getIdentifier() );
648
649 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_WARNING",
650 Level.WARNING, new ObjectFactory().createImplementation( impl ),
651 "implementationMessageOverrideWarning", impl.getIdentifier(),
652 moduleOfImpl.getName(), m.getName(),
653 overriddenImplementation.getIdentifier(),
654 moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
655
656 }
657 }
658
659 retainFinalNodes( overriddenMessages );
660
661 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
662 {
663 Implementation overriddenImplementation = overriddenMessage.getImplementation();
664 if ( overriddenMessage.getClassDeclaration() != null )
665 {
666 overriddenImplementation = overriddenMessage.getClassDeclaration();
667 }
668
669 final Module moduleOfMessage = validationContext.getModules().getModuleOfImplementation(
670 overriddenImplementation.getIdentifier() );
671
672 addDetail( validationContext.getReport(),
673 "IMPLEMENTATION_MESSAGE_INHERITANCE_CONSTRAINT",
674 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
675 "implementationMessageFinalConstraint", impl.getIdentifier(),
676 moduleOfImpl.getName(), m.getName(),
677 overriddenImplementation.getIdentifier(),
678 moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
679
680 }
681 }
682 }
683
684 for ( int j = 0, s1 = impl.getMessages().getReference().size(); j < s1; j++ )
685 {
686 final MessageReference r = impl.getMessages().getReference().get( j );
687
688 final Set<InheritanceModel.Node<Message>> effMessages =
689 imodel.getMessageNodes( impl.getIdentifier(), r.getName() );
690
691 for ( final InheritanceModel.Node<Message> effMessage : effMessages )
692 {
693 final Set<InheritanceModel.Node<Message>> overriddenMessages =
694 modifiableSet( effMessage.getOverriddenNodes() );
695
696 if ( r.isOverride() && overriddenMessages.isEmpty() )
697 {
698 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_CONSTRAINT",
699 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
700 "implementationMessageOverrideConstraint", impl.getIdentifier(),
701 moduleOfImpl.getName(), r.getName() );
702
703 }
704
705 if ( !( r.isOverride() || overriddenMessages.isEmpty() ) )
706 {
707 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
708 {
709 Implementation overriddenImplementation = overriddenMessage.getImplementation();
710 if ( overriddenMessage.getClassDeclaration() != null )
711 {
712 overriddenImplementation = overriddenMessage.getClassDeclaration();
713 }
714
715 final Module moduleOfMessage =
716 validationContext.getModules().getModuleOfImplementation(
717 overriddenImplementation.getIdentifier() );
718
719 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_WARNING",
720 Level.WARNING, new ObjectFactory().createImplementation( impl ),
721 "implementationMessageOverrideWarning", impl.getIdentifier(),
722 moduleOfImpl.getName(), r.getName(),
723 overriddenImplementation.getIdentifier(),
724 moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
725
726 }
727 }
728
729 retainFinalNodes( overriddenMessages );
730
731 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
732 {
733 Implementation overriddenImplementation = overriddenMessage.getImplementation();
734 if ( overriddenMessage.getClassDeclaration() != null )
735 {
736 overriddenImplementation = overriddenMessage.getClassDeclaration();
737 }
738
739 final Module moduleOfMessage =
740 validationContext.getModules().getModuleOfImplementation(
741 overriddenImplementation.getIdentifier() );
742
743 addDetail( validationContext.getReport(),
744 "IMPLEMENTATION_MESSAGE_INHERITANCE_CONSTRAINT",
745 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
746 "implementationMessageFinalConstraint", impl.getIdentifier(),
747 moduleOfImpl.getName(), r.getName(),
748 overriddenImplementation.getIdentifier(),
749 moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
750
751 }
752 }
753 }
754 }
755
756 if ( impl.getProperties() != null )
757 {
758 for ( int j = 0, s1 = impl.getProperties().getProperty().size(); j < s1; j++ )
759 {
760 final Property p = impl.getProperties().getProperty().get( j );
761
762 if ( impl.getProperties().getReference( p.getName() ) != null )
763 {
764 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTIES_UNIQUENESS_CONSTRAINT",
765 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
766 "implementationPropertiesUniquenessConstraint", impl.getIdentifier(),
767 moduleOfImpl.getName(), p.getName() );
768
769 }
770
771 if ( p.getValue() != null && p.getAny() != null )
772 {
773 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_VALUE_CONSTRAINT",
774 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
775 "implementationPropertyValueConstraint", impl.getIdentifier(),
776 moduleOfImpl.getName(), p.getName() );
777
778 }
779
780 if ( p.getAny() != null && p.getType() == null )
781 {
782 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_TYPE_CONSTRAINT",
783 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
784 "implementationPropertyTypeConstraint", impl.getIdentifier(),
785 moduleOfImpl.getName(), p.getName() );
786
787 }
788
789 try
790 {
791 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
792 }
793 catch ( final PropertyException e )
794 {
795 final String message = getMessage( e );
796
797 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
798 {
799 validationContext.getModelContext().log( Level.FINE, message, e );
800 }
801
802 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_JAVA_VALUE_CONSTRAINT",
803 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
804 "implementationPropertyJavaValueConstraint", impl.getIdentifier(),
805 moduleOfImpl.getName(), p.getName(),
806 message != null && message.length() > 0 ? " " + message : "" );
807
808 }
809
810 final Set<InheritanceModel.Node<Property>> effProperties =
811 imodel.getPropertyNodes( impl.getIdentifier(), p.getName() );
812
813 for ( final InheritanceModel.Node<Property> effProperty : effProperties )
814 {
815 final Set<InheritanceModel.Node<Property>> overriddenProperties =
816 modifiableSet( effProperty.getOverriddenNodes() );
817
818 if ( p.isOverride() && overriddenProperties.isEmpty() )
819 {
820 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_OVERRIDE_CONSTRAINT",
821 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
822 "implementationPropertyOverrideConstraint", impl.getIdentifier(),
823 moduleOfImpl.getName(), p.getName() );
824
825 }
826
827 if ( !( p.isOverride() || overriddenProperties.isEmpty() ) )
828 {
829 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
830 {
831 if ( overriddenProperty.getSpecification() != null )
832 {
833 final Module moduleOfProperty =
834 validationContext.getModules().getModuleOfSpecification(
835 overriddenProperty.getSpecification().getIdentifier() );
836
837 addDetail( validationContext.getReport(),
838 "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
839 new ObjectFactory().createImplementation( impl ),
840 "implementationSpecificationPropertyOverrideWarning",
841 impl.getIdentifier(), moduleOfImpl.getName(), p.getName(),
842 overriddenProperty.getSpecification().getIdentifier(),
843 moduleOfProperty.getName(),
844 getNodePathString( overriddenProperty ) );
845
846 }
847 else
848 {
849 Implementation overriddenImplementation =
850 overriddenProperty.getImplementation();
851
852 if ( overriddenProperty.getClassDeclaration() != null )
853 {
854 overriddenImplementation = overriddenProperty.getClassDeclaration();
855 }
856
857 final Module moduleOfProperty =
858 validationContext.getModules().getModuleOfImplementation(
859 overriddenImplementation.getIdentifier() );
860
861 addDetail( validationContext.getReport(),
862 "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
863 new ObjectFactory().createImplementation( impl ),
864 "implementationPropertyOverrideWarning", impl.getIdentifier(),
865 moduleOfImpl.getName(), p.getName(),
866 overriddenImplementation.getIdentifier(),
867 moduleOfProperty.getName(),
868 getNodePathString( overriddenProperty ) );
869
870 }
871 }
872 }
873
874 retainFinalNodes( overriddenProperties );
875
876 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
877 {
878 Implementation overriddenImplementation = overriddenProperty.getImplementation();
879 if ( overriddenProperty.getClassDeclaration() != null )
880 {
881 overriddenImplementation = overriddenProperty.getClassDeclaration();
882 }
883
884 final Module moduleOfProperty =
885 validationContext.getModules().getModuleOfImplementation(
886 overriddenImplementation.getIdentifier() );
887
888 addDetail( validationContext.getReport(),
889 "IMPLEMENTATION_PROPERTY_INHERITANCE_CONSTRAINT",
890 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
891 "implementationPropertyFinalConstraint", impl.getIdentifier(),
892 moduleOfImpl.getName(), p.getName(),
893 overriddenImplementation.getIdentifier(),
894 moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
895
896 }
897 }
898 }
899
900 for ( int j = 0, s1 = impl.getProperties().getReference().size(); j < s1; j++ )
901 {
902 final PropertyReference r = impl.getProperties().getReference().get( j );
903
904 final Set<InheritanceModel.Node<Property>> effProperties =
905 imodel.getPropertyNodes( impl.getIdentifier(), r.getName() );
906
907 for ( final InheritanceModel.Node<Property> effProperty : effProperties )
908 {
909 final Set<InheritanceModel.Node<Property>> overriddenProperties =
910 modifiableSet( effProperty.getOverriddenNodes() );
911
912 if ( r.isOverride() && overriddenProperties.isEmpty() )
913 {
914 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_OVERRIDE_CONSTRAINT",
915 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
916 "implementationPropertyOverrideConstraint", impl.getIdentifier(),
917 moduleOfImpl.getName(), r.getName() );
918
919 }
920
921 if ( !( r.isOverride() || overriddenProperties.isEmpty() ) )
922 {
923 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
924 {
925 Implementation overriddenImplementation = overriddenProperty.getImplementation();
926 if ( overriddenProperty.getClassDeclaration() != null )
927 {
928 overriddenImplementation = overriddenProperty.getClassDeclaration();
929 }
930
931 final Module moduleOfProperty =
932 validationContext.getModules().getModuleOfImplementation(
933 overriddenImplementation.getIdentifier() );
934
935 addDetail( validationContext.getReport(),
936 "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
937 new ObjectFactory().createImplementation( impl ),
938 "implementationPropertyOverrideWarning", impl.getIdentifier(),
939 moduleOfImpl.getName(), r.getName(),
940 overriddenImplementation.getIdentifier(),
941 moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
942
943 }
944 }
945
946 retainFinalNodes( overriddenProperties );
947
948 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
949 {
950 Implementation overriddenImplementation = overriddenProperty.getImplementation();
951 if ( overriddenProperty.getClassDeclaration() != null )
952 {
953 overriddenImplementation = overriddenProperty.getClassDeclaration();
954 }
955
956 final Module moduleOfProperty =
957 validationContext.getModules().getModuleOfImplementation(
958 overriddenImplementation.getIdentifier() );
959
960 addDetail( validationContext.getReport(),
961 "IMPLEMENTATION_PROPERTY_INHERITANCE_CONSTRAINT",
962 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
963 "implementationPropertyFinalConstraint", impl.getIdentifier(),
964 moduleOfImpl.getName(), r.getName(),
965 overriddenImplementation.getIdentifier(),
966 moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
967
968 }
969 }
970 }
971 }
972
973 if ( impl.getSpecifications() != null )
974 {
975 for ( int j = 0, s1 = impl.getSpecifications().getSpecification().size(); j < s1; j++ )
976 {
977 final Specification s = impl.getSpecifications().getSpecification().get( j );
978
979 addDetail( validationContext.getReport(), "IMPLEMENTATION_SPECIFICATION_DECLARATION_CONSTRAINT",
980 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
981 "implementationSpecificationDeclarationConstraint", impl.getIdentifier(),
982 moduleOfImpl.getName(), s.getIdentifier() );
983
984 }
985
986 for ( int j = 0, s1 = impl.getSpecifications().getReference().size(); j < s1; j++ )
987 {
988 final SpecificationReference r = impl.getSpecifications().getReference().get( j );
989
990 final Set<InheritanceModel.Node<SpecificationReference>> effReferences =
991 imodel.getSpecificationReferenceNodes( impl.getIdentifier(), r.getIdentifier() );
992
993 for ( final InheritanceModel.Node<SpecificationReference> effReference : effReferences )
994 {
995 final Set<InheritanceModel.Node<SpecificationReference>> overriddenReferences =
996 modifiableSet( effReference.getOverriddenNodes() );
997
998 if ( r.isOverride() && overriddenReferences.isEmpty() )
999 {
1000 addDetail( validationContext.getReport(),
1001 "IMPLEMENTATION_SPECIFICATION_OVERRIDE_CONSTRAINT", Level.SEVERE,
1002 new ObjectFactory().createImplementation( impl ),
1003 "implementationSpecificationOverrideConstraint", impl.getIdentifier(),
1004 moduleOfImpl.getName(), r.getIdentifier() );
1005
1006 }
1007
1008 if ( !( r.isOverride() || overriddenReferences.isEmpty() ) )
1009 {
1010 for ( final InheritanceModel.Node<SpecificationReference> overriddenReference :
1011 overriddenReferences )
1012 {
1013 Implementation overriddenImplementation = overriddenReference.getImplementation();
1014 if ( overriddenReference.getClassDeclaration() != null )
1015 {
1016 overriddenImplementation = overriddenReference.getClassDeclaration();
1017 }
1018
1019 final Module moduleOfReference =
1020 validationContext.getModules().getModuleOfImplementation(
1021 overriddenImplementation.getIdentifier() );
1022
1023 addDetail( validationContext.getReport(),
1024 "IMPLEMENTATION_SPECIFICATION_REFERENCE_OVERRIDE_WARNING",
1025 Level.WARNING, new ObjectFactory().createImplementation( impl ),
1026 "implementationSpecificationOverrideWarning", impl.getIdentifier(),
1027 moduleOfImpl.getName(), r.getIdentifier(),
1028 overriddenImplementation.getIdentifier(),
1029 moduleOfReference.getName(), getNodePathString( overriddenReference ) );
1030
1031 }
1032 }
1033
1034 retainFinalNodes( overriddenReferences );
1035
1036 for ( final InheritanceModel.Node<SpecificationReference> overriddenReference :
1037 overriddenReferences )
1038 {
1039 Implementation overriddenImplementation = overriddenReference.getImplementation();
1040 if ( overriddenReference.getClassDeclaration() != null )
1041 {
1042 overriddenImplementation = overriddenReference.getClassDeclaration();
1043 }
1044
1045 final Module moduleOfReference =
1046 validationContext.getModules().getModuleOfImplementation(
1047 overriddenImplementation.getIdentifier() );
1048
1049 addDetail( validationContext.getReport(),
1050 "IMPLEMENTATION_SPECIFICATION_INHERITANCE_CONSTRAINT", Level.SEVERE,
1051 new ObjectFactory().createImplementation( impl ),
1052 "implementationSpecificationFinalConstraint", impl.getIdentifier(),
1053 moduleOfImpl.getName(), r.getIdentifier(),
1054 overriddenImplementation.getIdentifier(),
1055 moduleOfReference.getName(), getNodePathString( overriddenReference ) );
1056
1057 }
1058 }
1059 }
1060 }
1061
1062 if ( !impl.getAny().isEmpty() )
1063 {
1064 for ( int j = 0, s1 = impl.getAny().size(); j < s1; j++ )
1065 {
1066 final Object any = impl.getAny().get( j );
1067
1068 if ( any instanceof JAXBElement<?> )
1069 {
1070 final JAXBElement<?> jaxbElement = (JAXBElement<?>) any;
1071 boolean overrideNode = false;
1072
1073 if ( jaxbElement.getValue() instanceof Inheritable )
1074 {
1075 overrideNode = ( (Inheritable) jaxbElement.getValue() ).isOverride();
1076 }
1077
1078 final Set<InheritanceModel.Node<JAXBElement<?>>> effElements =
1079 imodel.getJaxbElementNodes( impl.getIdentifier(), jaxbElement.getName() );
1080
1081 for ( final InheritanceModel.Node<JAXBElement<?>> effElement : effElements )
1082 {
1083 final Set<InheritanceModel.Node<JAXBElement<?>>> overriddenElements =
1084 modifiableSet( effElement.getOverriddenNodes() );
1085
1086 if ( overrideNode && overriddenElements.isEmpty() )
1087 {
1088 addDetail( validationContext.getReport(),
1089 "IMPLEMENTATION_JAXB_ELEMENT_OVERRIDE_CONSTRAINT",
1090 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1091 "implementationJaxbElementOverrideConstraint", impl.getIdentifier(),
1092 moduleOfImpl.getName(), jaxbElement.getName().toString() );
1093
1094 }
1095
1096 if ( !( overrideNode || overriddenElements.isEmpty() ) )
1097 {
1098 for ( final InheritanceModel.Node<JAXBElement<?>> overriddenElement :
1099 overriddenElements )
1100 {
1101 Implementation overriddenImplementation = overriddenElement.getImplementation();
1102 if ( overriddenElement.getClassDeclaration() != null )
1103 {
1104 overriddenImplementation = overriddenElement.getClassDeclaration();
1105 }
1106
1107 final Module moduleOfElement =
1108 validationContext.getModules().getModuleOfImplementation(
1109 overriddenElement.getImplementation().getIdentifier() );
1110
1111 addDetail( validationContext.getReport(),
1112 "IMPLEMENTATION_JAXB_ELEMENT_OVERRIDE_WARNING",
1113 Level.WARNING, new ObjectFactory().createImplementation( impl ),
1114 "implementationJaxbElementOverrideWarning", impl.getIdentifier(),
1115 moduleOfImpl.getName(), jaxbElement.getName().toString(),
1116 overriddenImplementation.getIdentifier(),
1117 moduleOfElement.getName(), getNodePathString( overriddenElement ) );
1118
1119 }
1120 }
1121
1122 retainFinalNodes( overriddenElements );
1123
1124 for ( final InheritanceModel.Node<JAXBElement<?>> overriddenElement :
1125 overriddenElements )
1126 {
1127 Implementation overriddenImplementation = overriddenElement.getImplementation();
1128 if ( overriddenElement.getClassDeclaration() != null )
1129 {
1130 overriddenImplementation = overriddenElement.getClassDeclaration();
1131 }
1132
1133 final Module moduleOfElement =
1134 validationContext.getModules().getModuleOfImplementation(
1135 overriddenImplementation.getIdentifier() );
1136
1137 addDetail( validationContext.getReport(),
1138 "IMPLEMENTATION_JAXB_ELEMENT_INHERITANCE_CONSTRAINT",
1139 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1140 "implementationJaxbElementFinalConstraint", impl.getIdentifier(),
1141 moduleOfImpl.getName(), jaxbElement.getName().toString(),
1142 overriddenImplementation.getIdentifier(),
1143 moduleOfElement.getName(), getNodePathString( overriddenElement ) );
1144
1145 }
1146 }
1147 }
1148 }
1149 }
1150
1151 final Set<String> dependencyNames = imodel.getDependencyNames( impl.getIdentifier() );
1152
1153 for ( String dependencyName : dependencyNames )
1154 {
1155 final Set<InheritanceModel.Node<Dependency>> dependencyNodes =
1156 imodel.getDependencyNodes( impl.getIdentifier(), dependencyName );
1157
1158 if ( dependencyNodes.size() > 1 )
1159 {
1160 addDetail( validationContext.getReport(),
1161 "IMPLEMENTATION_DEPENDENCY_MULTIPLE_INHERITANCE_CONSTRAINT",
1162 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1163 "implementationMultipleInheritanceDependencyConstraint", impl.getIdentifier(),
1164 moduleOfImpl.getName(), dependencyName, getNodeListPathString( dependencyNodes ) );
1165
1166 }
1167 }
1168
1169 final Set<String> messageNames = imodel.getMessageNames( impl.getIdentifier() );
1170
1171 for ( String messageName : messageNames )
1172 {
1173 final Set<InheritanceModel.Node<Message>> messageNodes =
1174 imodel.getMessageNodes( impl.getIdentifier(), messageName );
1175
1176 if ( messageNodes.size() > 1 )
1177 {
1178 addDetail( validationContext.getReport(),
1179 "IMPLEMENTATION_MESSAGE_MULTIPLE_INHERITANCE_CONSTRAINT", Level.SEVERE,
1180 new ObjectFactory().createImplementation( impl ),
1181 "implementationMultipleInheritanceMessageConstraint", impl.getIdentifier(),
1182 moduleOfImpl.getName(), messageName, getNodeListPathString( messageNodes ) );
1183
1184 }
1185 }
1186
1187 final Set<String> propertyNames = imodel.getPropertyNames( impl.getIdentifier() );
1188
1189 for ( String propertyName : propertyNames )
1190 {
1191 final Set<InheritanceModel.Node<Property>> propertyNodes =
1192 imodel.getPropertyNodes( impl.getIdentifier(), propertyName );
1193
1194 if ( propertyNodes.size() > 1 )
1195 {
1196 addDetail( validationContext.getReport(),
1197 "IMPLEMENTATION_PROPERTY_MULTIPLE_INHERITANCE_CONSTRAINT", Level.SEVERE,
1198 new ObjectFactory().createImplementation( impl ),
1199 "implementationMultipleInheritancePropertyConstraint", impl.getIdentifier(),
1200 moduleOfImpl.getName(), propertyName, getNodeListPathString( propertyNodes ) );
1201
1202 }
1203 }
1204
1205 final Set<String> specificationReferenceIdentifiers =
1206 imodel.getSpecificationReferenceIdentifiers( impl.getIdentifier() );
1207
1208 for ( String specificationRefereneIdentifier : specificationReferenceIdentifiers )
1209 {
1210 final Set<InheritanceModel.Node<SpecificationReference>> specificationReferenceNodes =
1211 imodel.getSpecificationReferenceNodes( impl.getIdentifier(), specificationRefereneIdentifier );
1212
1213 if ( specificationReferenceNodes.size() > 1 )
1214 {
1215 addDetail( validationContext.getReport(),
1216 "IMPLEMENTATION_SPECIFICATION_MULTIPLE_INHERITANCE_CONSTRAINT",
1217 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1218 "implementationMultipleInheritanceSpecificationConstraint",
1219 impl.getIdentifier(), moduleOfImpl.getName(), specificationRefereneIdentifier,
1220 getNodeListPathString( specificationReferenceNodes ) );
1221
1222 }
1223 }
1224
1225 final Set<QName> xmlElementNames = imodel.getXmlElementNames( impl.getIdentifier() );
1226
1227 for ( QName xmlElementName : xmlElementNames )
1228 {
1229 final Set<InheritanceModel.Node<Element>> xmlElementNodes =
1230 imodel.getXmlElementNodes( impl.getIdentifier(), xmlElementName );
1231
1232 if ( xmlElementNodes.size() > 1 )
1233 {
1234 addDetail( validationContext.getReport(),
1235 "IMPLEMENTATION_XML_ELEMENT_MULTIPLE_INHERITANCE_CONSTRAINT",
1236 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1237 "implementationMultipleInheritanceXmlElementConstraint",
1238 impl.getIdentifier(), moduleOfImpl.getName(), xmlElementName.toString(),
1239 getNodeListPathString( xmlElementNodes ) );
1240
1241 }
1242 }
1243
1244 final Set<QName> jaxbElementNames = imodel.getJaxbElementNames( impl.getIdentifier() );
1245
1246 for ( QName jaxbElementName : jaxbElementNames )
1247 {
1248 final Set<InheritanceModel.Node<JAXBElement<?>>> jaxbElementNodes =
1249 imodel.getJaxbElementNodes( impl.getIdentifier(), jaxbElementName );
1250
1251 if ( jaxbElementNodes.size() > 1 )
1252 {
1253 addDetail( validationContext.getReport(),
1254 "IMPLEMENTATION_JAXB_ELEMENT_MULTIPLE_INHERITANCE_CONSTRAINT",
1255 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1256 "implementationMultipleInheritanceJaxbElementConstraint",
1257 impl.getIdentifier(), moduleOfImpl.getName(), jaxbElementName.toString(),
1258 getNodeListPathString( jaxbElementNodes ) );
1259
1260 }
1261 }
1262
1263 final Set<String> implementationReferenceIdentifiers =
1264 imodel.getImplementationReferenceIdentifiers( impl.getIdentifier() );
1265
1266 for ( String implementationReferenceIdentifier : implementationReferenceIdentifiers )
1267 {
1268 final Set<InheritanceModel.Node<ImplementationReference>> implementationReferenceNodes =
1269 imodel.getImplementationReferenceNodes( impl.getIdentifier(),
1270 implementationReferenceIdentifier );
1271
1272 for ( final InheritanceModel.Node<ImplementationReference> node : implementationReferenceNodes )
1273 {
1274 final ImplementationReference r = node.getModelObject();
1275
1276 final Implementation referenced =
1277 validationContext.getModules().getImplementation( r.getIdentifier() );
1278
1279 final Module moduleOfReferenced =
1280 validationContext.getModules().getModuleOfImplementation( referenced.getIdentifier() );
1281
1282 if ( r.getVersion() != null && referenced != null )
1283 {
1284 if ( referenced.getVersion() == null )
1285 {
1286 addDetail( validationContext.getReport(),
1287 "IMPLEMENTATION_IMPLEMENTATION_VERSIONING_CONSTRAINT", Level.SEVERE,
1288 new ObjectFactory().createImplementation( impl ),
1289 "implementationImplementationVersioningConstraint",
1290 impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
1291 moduleOfReferenced.getName() );
1292
1293 }
1294 else
1295 {
1296 try
1297 {
1298 if ( VersionParser.compare( r.getVersion(), referenced.getVersion() ) > 0 )
1299 {
1300 addDetail( validationContext.getReport(),
1301 "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_CONSTRAINT",
1302 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1303 "implementationInheritanceCompatibilityConstraint",
1304 impl.getIdentifier(), moduleOfImpl.getName(),
1305 referenced.getIdentifier(), moduleOfReferenced.getName(),
1306 r.getVersion(), referenced.getVersion() );
1307
1308 }
1309 }
1310 catch ( final ParseException ex )
1311 {
1312 final String message = getMessage( ex );
1313
1314 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1315 {
1316 validationContext.getModelContext().log( Level.FINE, message, ex );
1317 }
1318
1319 addDetail(
1320 validationContext.getReport(),
1321 "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
1322 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1323 "implementationInheritanceCompatibilityParseException",
1324 impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
1325 moduleOfReferenced.getName(), r.getVersion(),
1326 message != null && message.length() > 0 ? " " + message : "" );
1327
1328 }
1329 catch ( final TokenMgrError ex )
1330 {
1331 final String message = getMessage( ex );
1332
1333 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1334 {
1335 validationContext.getModelContext().log( Level.FINE, message, ex );
1336 }
1337
1338 addDetail(
1339 validationContext.getReport(),
1340 "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
1341 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1342 "implementationInheritanceCompatiblityVersioningTokenManagerError",
1343 impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
1344 moduleOfReferenced.getName(), r.getVersion(),
1345 message != null && message.length() > 0 ? " " + message : "" );
1346
1347 }
1348 }
1349 }
1350 }
1351 }
1352
1353 assertImplementationSpecificationCompatibility( validationContext, impl );
1354 }
1355 }
1356 }
1357
1358 private static void assertSpecificationsValid( final ValidationContext validationContext )
1359 {
1360 final Specifications specifications = validationContext.getModules().getSpecifications();
1361 final Map<String, Specification> specificationClassDeclarations = new HashMap<String, Specification>();
1362
1363 if ( specifications != null )
1364 {
1365 for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
1366 {
1367 final Specification s = specifications.getSpecification().get( i );
1368 final Implementations impls = validationContext.getModules().getImplementations( s.getIdentifier() );
1369 final Module moduleOfS = validationContext.getModules().getModuleOfSpecification( s.getIdentifier() );
1370
1371 if ( s.isClassDeclaration() )
1372 {
1373 if ( s.getClazz() == null )
1374 {
1375 addDetail( validationContext.getReport(), "SPECIFICATION_CLASS_CONSTRAINT", Level.SEVERE,
1376 new ObjectFactory().createSpecification( s ), "specificationClassConstraint",
1377 s.getIdentifier(), moduleOfS.getName() );
1378
1379 }
1380 else
1381 {
1382 final Specification prev = specificationClassDeclarations.get( s.getClazz() );
1383
1384 if ( prev != null && !prev.getIdentifier().equals( s.getIdentifier() ) )
1385 {
1386 final Module moduleOfPrev = validationContext.getModules().getModuleOfSpecification(
1387 prev.getIdentifier() );
1388
1389 addDetail( validationContext.getReport(), "SPECIFICATION_CLASS_DECLARATION_CONSTRAINT",
1390 Level.SEVERE, new ObjectFactory().createSpecification( s ),
1391 "specificationClassDeclarationConstraint", s.getIdentifier(),
1392 moduleOfS.getName(), s.getClazz(), prev.getIdentifier(),
1393 moduleOfPrev.getName() );
1394
1395 }
1396 else
1397 {
1398 specificationClassDeclarations.put( s.getClazz(), s );
1399 }
1400 }
1401 }
1402
1403 if ( impls != null )
1404 {
1405 final Map<String, Implementations> map = new HashMap<String, Implementations>();
1406
1407 for ( int j = 0, s1 = impls.getImplementation().size(); j < s1; j++ )
1408 {
1409 final Implementation impl = impls.getImplementation().get( j );
1410 Implementations implementations = map.get( impl.getName() );
1411
1412 if ( implementations == null )
1413 {
1414 implementations = new Implementations();
1415 map.put( impl.getName(), implementations );
1416 }
1417
1418 implementations.getImplementation().add( impl );
1419 }
1420
1421 for ( Map.Entry<String, Implementations> e : map.entrySet() )
1422 {
1423 if ( e.getValue().getImplementation().size() > 1 )
1424 {
1425 for ( int j = 0, s1 = e.getValue().getImplementation().size(); j < s1; j++ )
1426 {
1427 final Implementation impl = e.getValue().getImplementation().get( j );
1428 final Module moduleOfImpl = validationContext.getModules().getModuleOfImplementation(
1429 impl.getIdentifier() );
1430
1431 addDetail( validationContext.getReport(),
1432 "SPECIFICATION_IMPLEMENTATION_NAME_UNIQUENESS_CONSTRAINT",
1433 Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1434 "specificationImplementationNameConstraint", impl.getIdentifier(),
1435 moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName(),
1436 impl.getName() );
1437
1438 }
1439 }
1440 }
1441
1442 if ( s.getMultiplicity() == Multiplicity.ONE && impls.getImplementation().size() > 1 )
1443 {
1444 for ( int j = 0, s1 = impls.getImplementation().size(); j < s1; j++ )
1445 {
1446 final Implementation impl = impls.getImplementation().get( j );
1447 final Module moduleOfImpl = validationContext.getModules().getModuleOfImplementation(
1448 impl.getIdentifier() );
1449
1450 addDetail( validationContext.getReport(),
1451 "SPECIFICATION_IMPLEMENTATION_MULTIPLICITY_CONSTRAINT", Level.SEVERE,
1452 new ObjectFactory().createImplementation( impl ),
1453 "specificationMultiplicityConstraint", impl.getIdentifier(),
1454 moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName(),
1455 s.getMultiplicity() );
1456
1457 }
1458 }
1459 }
1460
1461 if ( s.getProperties() != null )
1462 {
1463 for ( int j = 0, s1 = s.getProperties().getProperty().size(); j < s1; j++ )
1464 {
1465 final Property p = s.getProperties().getProperty().get( j );
1466
1467 if ( p.getValue() != null && p.getAny() != null )
1468 {
1469 addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_VALUE_CONSTRAINT",
1470 Level.SEVERE, new ObjectFactory().createSpecification( s ),
1471 "specificationPropertyValueConstraint", s.getIdentifier(),
1472 moduleOfS.getName(), p.getName() );
1473
1474 }
1475
1476 if ( p.getAny() != null && p.getType() == null )
1477 {
1478 addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_TYPE_CONSTRAINT",
1479 Level.SEVERE, new ObjectFactory().createSpecification( s ),
1480 "specificationPropertyTypeConstraint", s.getIdentifier(),
1481 moduleOfS.getName(), p.getName() );
1482
1483 }
1484
1485 try
1486 {
1487 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
1488 }
1489 catch ( final PropertyException e )
1490 {
1491 final String message = getMessage( e );
1492
1493 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1494 {
1495 validationContext.getModelContext().log( Level.FINE, message, e );
1496 }
1497
1498 addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_JAVA_VALUE_CONSTRAINT",
1499 Level.SEVERE, new ObjectFactory().createSpecification( s ),
1500 "specificationPropertyJavaValueConstraint", s.getIdentifier(),
1501 moduleOfS.getName(), p.getName(),
1502 message != null && message.length() > 0 ? " " + message : "" );
1503
1504 }
1505 }
1506
1507 for ( int j = 0, s1 = s.getProperties().getReference().size(); j < s1; j++ )
1508 {
1509 final PropertyReference r = s.getProperties().getReference().get( j );
1510
1511 addDetail( validationContext.getReport(),
1512 "SPECIFICATION_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
1513 new ObjectFactory().createSpecification( s ),
1514 "specificationPropertyReferenceDeclarationConstraint", s.getIdentifier(),
1515 moduleOfS.getName(), r.getName() );
1516
1517 }
1518 }
1519 }
1520 }
1521 }
1522
1523 private static void assertDependencyValid( final ValidationContext validationContext,
1524 final Implementation implementation, final Dependency dependency )
1525 {
1526 final Specification s = validationContext.getModules().getSpecification( dependency.getIdentifier() );
1527 final Implementations available =
1528 validationContext.getModules().getImplementations( dependency.getIdentifier() );
1529
1530 final Module moduleOfImpl =
1531 validationContext.getModules().getModuleOfImplementation( implementation.getIdentifier() );
1532
1533 if ( !dependency.isOptional()
1534 && ( available == null || available.getImplementation().isEmpty()
1535 || ( dependency.getImplementationName() != null
1536 && available.getImplementationByName( dependency.getImplementationName() ) == null ) ) )
1537 {
1538 addDetail( validationContext.getReport(), "IMPLEMENTATION_MANDATORY_DEPENDENCY_CONSTRAINT", Level.SEVERE,
1539 new ObjectFactory().createImplementation( implementation ),
1540 "implementationMandatoryDependencyConstraint", implementation.getIdentifier(),
1541 moduleOfImpl.getName(), dependency.getName() );
1542
1543 }
1544
1545 if ( s != null )
1546 {
1547 final Module moduleOfS = validationContext.getModules().getModuleOfSpecification( s.getIdentifier() );
1548
1549 if ( s.getClazz() == null )
1550 {
1551 addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_CLASS_CONSTRAINT",
1552 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1553 "implementationDependencySpecificationClassConstraint", implementation.getIdentifier(),
1554 moduleOfImpl.getName(), dependency.getName(), dependency.getIdentifier(),
1555 moduleOfS.getName() );
1556
1557 }
1558
1559 if ( dependency.getVersion() != null )
1560 {
1561 if ( s.getVersion() == null )
1562 {
1563 addDetail( validationContext.getReport(),
1564 "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_VERSIONING_CONSTRAINT", Level.SEVERE,
1565 new ObjectFactory().createImplementation( implementation ),
1566 "implementationDependencySpecificationVersioningConstraint",
1567 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1568 s.getIdentifier(), moduleOfS.getName() );
1569
1570 }
1571 else
1572 {
1573
1574 try
1575 {
1576 if ( VersionParser.compare( dependency.getVersion(), s.getVersion() ) > 0 )
1577 {
1578 addDetail( validationContext.getReport(),
1579 "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_CONSTRAINT",
1580 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1581 "implementationDependencySpecificationCompatibilityConstraint",
1582 implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
1583 moduleOfS.getName(), dependency.getVersion(), s.getVersion() );
1584
1585 }
1586 }
1587 catch ( final ParseException e )
1588 {
1589 final String message = getMessage( e );
1590
1591 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1592 {
1593 validationContext.getModelContext().log( Level.FINE, message, e );
1594 }
1595
1596 addDetail( validationContext.getReport(),
1597 "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
1598 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1599 "implementationDependencySpecificationCompatibilityParseException",
1600 implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
1601 moduleOfS.getName(), dependency.getVersion(),
1602 message != null && message.length() > 0 ? " " + message : "" );
1603
1604 }
1605 catch ( final TokenMgrError e )
1606 {
1607 final String message = getMessage( e );
1608
1609 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1610 {
1611 validationContext.getModelContext().log( Level.FINE, message, e );
1612 }
1613
1614 addDetail( validationContext.getReport(),
1615 "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
1616 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1617 "implementationDependencySpecificationCompatibilityTokenMgrError",
1618 implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
1619 moduleOfS.getName(), dependency.getVersion(),
1620 message != null && message.length() > 0 ? " " + message : "" );
1621
1622 }
1623 }
1624 }
1625
1626 if ( s.getScope() != null )
1627 {
1628 if ( dependency.getDependencies() != null )
1629 {
1630 for ( int i = 0, s0 = dependency.getDependencies().getDependency().size(); i < s0; i++ )
1631 {
1632 final Dependency d = dependency.getDependencies().getDependency().get( i );
1633
1634 addDetail( validationContext.getReport(),
1635 "IMPLEMENTATION_DEPENDENCY_DEPENDENCIES_OVERRIDE_CONSTRAINT", Level.SEVERE,
1636 new ObjectFactory().createImplementation( implementation ),
1637 "implementationDependencyDependenciesOverrideConstraint",
1638 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1639 d.getName(), s.getIdentifier(), moduleOfS.getName(), s.getScope() );
1640
1641 }
1642 }
1643
1644 if ( dependency.getMessages() != null )
1645 {
1646 for ( int i = 0, s0 = dependency.getMessages().getMessage().size(); i < s0; i++ )
1647 {
1648 final Message m = dependency.getMessages().getMessage().get( i );
1649
1650 addDetail( validationContext.getReport(),
1651 "IMPLEMENTATION_DEPENDENCY_MESSAGES_OVERRIDE_CONSTRAINT", Level.SEVERE,
1652 new ObjectFactory().createImplementation( implementation ),
1653 "implementationDependencyMessagesOverrideConstraint", implementation.getIdentifier(),
1654 moduleOfImpl.getName(), dependency.getName(), m.getName(), s.getIdentifier(),
1655 moduleOfS.getName(), s.getScope() );
1656
1657 }
1658 }
1659
1660 if ( dependency.getProperties() != null )
1661 {
1662 for ( int i = 0, s0 = dependency.getProperties().getProperty().size(); i < s0; i++ )
1663 {
1664 final Property p = dependency.getProperties().getProperty().get( i );
1665 addDetail( validationContext.getReport(),
1666 "IMPLEMENTATION_DEPENDENCY_PROPERTIES_OVERRIDE_CONSTRAINT", Level.SEVERE,
1667 new ObjectFactory().createImplementation( implementation ),
1668 "implementationDependencyPropertiesOverrideConstraint",
1669 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1670 p.getName(), s.getIdentifier(), moduleOfS.getName(), s.getScope() );
1671
1672 }
1673 }
1674 }
1675 }
1676
1677 if ( dependency.getMessages() != null )
1678 {
1679 for ( int i = 0, s0 = dependency.getMessages().getReference().size(); i < s0; i++ )
1680 {
1681 final MessageReference r = dependency.getMessages().getReference().get( i );
1682
1683 addDetail( validationContext.getReport(),
1684 "IMPLEMENTATION_DEPENDENCY_MESSAGE_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
1685 new ObjectFactory().createImplementation( implementation ),
1686 "implementationDependencyMessageReferenceDeclarationConstraint",
1687 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(), r.getName() );
1688
1689 }
1690 }
1691
1692 if ( dependency.getProperties() != null )
1693 {
1694 for ( int i = 0, s0 = dependency.getProperties().getProperty().size(); i < s0; i++ )
1695 {
1696 final Property p = dependency.getProperties().getProperty().get( i );
1697
1698 if ( p.getValue() != null && p.getAny() != null )
1699 {
1700 addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_PROPERTY_VALUE_CONSTRAINT",
1701 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1702 "implementationDependencyPropertyValueConstraint", implementation.getIdentifier(),
1703 moduleOfImpl.getName(), dependency.getName(), p.getName() );
1704
1705 }
1706
1707 if ( p.getAny() != null && p.getType() == null )
1708 {
1709 addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_PROPERTY_TYPE_CONSTRAINT",
1710 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1711 "implementationDependencyPropertyTypeConstraint", implementation.getIdentifier(),
1712 moduleOfImpl.getName(), dependency.getName(), p.getName() );
1713
1714 }
1715
1716 try
1717 {
1718 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
1719 }
1720 catch ( final PropertyException e )
1721 {
1722 final String message = getMessage( e );
1723
1724 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1725 {
1726 validationContext.getModelContext().log( Level.FINE, message, e );
1727 }
1728
1729 addDetail( validationContext.getReport(),
1730 "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_VALUE_CONSTRAINT", Level.SEVERE,
1731 new ObjectFactory().createImplementation( implementation ),
1732 "implementationDependencyPropertyJavaValueConstraint", implementation.getIdentifier(),
1733 moduleOfImpl.getName(), dependency.getName(), p.getName(),
1734 message != null && message.length() > 0 ? " " + message : "" );
1735
1736 }
1737 }
1738
1739 for ( int i = 0, s0 = dependency.getProperties().getReference().size(); i < s0; i++ )
1740 {
1741 final PropertyReference r = dependency.getProperties().getReference().get( i );
1742
1743 addDetail( validationContext.getReport(),
1744 "IMPLEMENTATION_DEPENDENCY_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
1745 new ObjectFactory().createImplementation( implementation ),
1746 "implementationDependencyPropertyReferenceDeclarationConstraint",
1747 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(), r.getName() );
1748
1749 }
1750 }
1751
1752 if ( available != null )
1753 {
1754 for ( int i = 0, s0 = available.getImplementation().size(); i < s0; i++ )
1755 {
1756 final Implementation a = available.getImplementation().get( i );
1757
1758 if ( dependency.getImplementationName() != null
1759 && !dependency.getImplementationName().equals( a.getName() ) )
1760 {
1761 continue;
1762 }
1763
1764 final InheritanceModel imodel = validationContext.getInheritanceModel();
1765 final Module moduleOfA = validationContext.getModules().getModuleOfImplementation( a.getIdentifier() );
1766
1767 if ( dependency.getDependencies() != null )
1768 {
1769 for ( int j = 0, s1 = dependency.getDependencies().getDependency().size(); j < s1; j++ )
1770 {
1771 final Dependency override = dependency.getDependencies().getDependency().get( j );
1772
1773 final Set<InheritanceModel.Node<Dependency>> effDependencies =
1774 imodel.getDependencyNodes( a.getIdentifier(), override.getName() );
1775
1776 final Set<InheritanceModel.Node<Dependency>> overriddenDependencies =
1777 modifiableSet( effDependencies );
1778
1779 final boolean effectiveDependencyOverridden = !overriddenDependencies.isEmpty();
1780
1781 if ( override.isOverride() && overriddenDependencies.isEmpty() )
1782 {
1783 addDetail( validationContext.getReport(),
1784 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_DEPENDENCY_CONSTRAINT",
1785 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1786 "implementationDependencyOverrideDependencyConstraint",
1787 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1788 override.getName(), a.getIdentifier(), moduleOfA.getName() );
1789
1790 }
1791
1792 if ( !( override.isOverride() || overriddenDependencies.isEmpty() ) )
1793 {
1794 for ( final InheritanceModel.Node<Dependency> overriddenDependency :
1795 overriddenDependencies )
1796 {
1797 addDetail( validationContext.getReport(),
1798 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_DEPENDENCY_WARNING",
1799 Level.WARNING, new ObjectFactory().createImplementation( implementation ),
1800 "implementationDependencyOverrideDependencyWarning",
1801 implementation.getIdentifier(), moduleOfImpl.getName(),
1802 dependency.getName(), override.getName(), a.getIdentifier(),
1803 moduleOfA.getName(), getNodePathString( overriddenDependency ) );
1804
1805 }
1806 }
1807
1808 retainFinalNodes( overriddenDependencies );
1809
1810 for ( final InheritanceModel.Node<Dependency> overriddenDependency :
1811 overriddenDependencies )
1812 {
1813 addDetail( validationContext.getReport(),
1814 "IMPLEMENTATION_DEPENDENCY_FINAL_DEPENDENCY_CONSTRAINT",
1815 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
1816 "implementationDependencyFinalDependencyConstraint",
1817 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1818 override.getName(), a.getIdentifier(), moduleOfA.getName(),
1819 getNodePathString( overriddenDependency ) );
1820
1821 }
1822
1823 if ( effectiveDependencyOverridden )
1824 {
1825 for ( InheritanceModel.Node<Dependency> node : effDependencies )
1826 {
1827 final Dependency overridden = node.getModelObject();
1828
1829 final Specification overrideSpecification =
1830 validationContext.getModules().getSpecification( override.getIdentifier() );
1831
1832 final Specification overriddenSpecification =
1833 validationContext.getModules().getSpecification( overridden.getIdentifier() );
1834
1835 if ( overrideSpecification != null && overriddenSpecification != null )
1836 {
1837 if ( overrideSpecification.getMultiplicity()
1838 != overriddenSpecification.getMultiplicity() )
1839 {
1840 addDetail( validationContext.getReport(),
1841 "IMPLEMENTATION_DEPENDENCY_MULTIPLICITY_CONSTRAINT",
1842 Level.SEVERE,
1843 new ObjectFactory().createImplementation( implementation ),
1844 "implementationDependencyMultiplicityConstraint",
1845 implementation.getIdentifier(), moduleOfImpl.getName(),
1846 dependency.getName(), overridden.getName(),
1847 a.getIdentifier(), moduleOfA.getName(),
1848 overrideSpecification.getMultiplicity().value(),
1849 overriddenSpecification.getMultiplicity().value() );
1850
1851 }
1852
1853 if ( overrideSpecification.getScope() != null
1854 ? !overrideSpecification.getScope().equals(
1855 overriddenSpecification.getScope() )
1856 : overriddenSpecification.getScope() != null )
1857 {
1858 addDetail( validationContext.getReport(),
1859 "IMPLEMENTATION_DEPENDENCY_SCOPE_CONSTRAINT", Level.SEVERE,
1860 new ObjectFactory().createImplementation( implementation ),
1861 "implementationDependencyScopeConstraint",
1862 implementation.getIdentifier(), moduleOfImpl.getName(),
1863 dependency.getName(), override.getName(),
1864 a.getIdentifier(), moduleOfA.getName(),
1865 overrideSpecification.getScope() == null
1866 ? "Multiton" : overrideSpecification.getScope(),
1867 overriddenSpecification.getScope() == null
1868 ? "Multiton" : overriddenSpecification.getScope() );
1869
1870 }
1871
1872 if ( overriddenSpecification.getMultiplicity() == Multiplicity.MANY )
1873 {
1874 if ( override.getImplementationName() == null
1875 && overridden.getImplementationName() != null )
1876 {
1877 addDetail( validationContext.getReport(),
1878 "IMPLEMENTATION_DEPENDENCY_NO_IMPLEMENTATION_NAME_CONSTRAINT",
1879 Level.SEVERE,
1880 new ObjectFactory().createImplementation( implementation ),
1881 "implementationDependencyNoImplementationNameConstraint",
1882 implementation.getIdentifier(), moduleOfImpl.getName(),
1883 dependency.getName(), override.getName(),
1884 a.getIdentifier(), moduleOfA.getName() );
1885
1886 }
1887
1888 if ( override.getImplementationName() != null
1889 && overridden.getImplementationName() == null )
1890 {
1891 addDetail( validationContext.getReport(),
1892 "IMPLEMENTATION_DEPENDENCY_IMPLEMENTATION_NAME_CONSTRAINT",
1893 Level.SEVERE,
1894 new ObjectFactory().createImplementation( implementation ),
1895 "implementationDependencyImplementationNameConstraint",
1896 implementation.getIdentifier(), moduleOfImpl.getName(),
1897 dependency.getName(), overridden.getName(),
1898 a.getIdentifier(), moduleOfA.getName(),
1899 override.getImplementationName() );
1900
1901 }
1902 }
1903 }
1904
1905 if ( override.isOptional() != overridden.isOptional() )
1906 {
1907 addDetail( validationContext.getReport(),
1908 "IMPLEMENTATION_DEPENDENCY_OPTIONALITY_CONSTRAINT", Level.SEVERE,
1909 new ObjectFactory().createImplementation( implementation ),
1910 "implementationDependencyOptonalityConstraint",
1911 implementation.getIdentifier(), moduleOfImpl.getName(),
1912 dependency.getName(), overridden.getName(),
1913 a.getIdentifier(), moduleOfA.getName() );
1914
1915 }
1916 }
1917 }
1918 }
1919 }
1920
1921 if ( dependency.getMessages() != null )
1922 {
1923 for ( int j = 0, s1 = dependency.getMessages().getMessage().size(); j < s1; j++ )
1924 {
1925 final Message override = dependency.getMessages().getMessage().get( j );
1926
1927 final Set<InheritanceModel.Node<Message>> overriddenMessages =
1928 modifiableSet( imodel.getMessageNodes( a.getIdentifier(), override.getName() ) );
1929
1930 if ( override.isOverride() && overriddenMessages.isEmpty() )
1931 {
1932 addDetail( validationContext.getReport(),
1933 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_MESSAGE_CONSTRAINT", Level.SEVERE,
1934 new ObjectFactory().createImplementation( implementation ),
1935 "implementationDependencyOverrideMessageConstraint",
1936 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1937 override.getName(), a.getIdentifier(), moduleOfA.getName() );
1938
1939 }
1940
1941 if ( !( override.isOverride() || overriddenMessages.isEmpty() ) )
1942 {
1943 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1944 {
1945 addDetail( validationContext.getReport(),
1946 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_MESSAGE_WARNING", Level.WARNING,
1947 new ObjectFactory().createImplementation( implementation ),
1948 "implementationDependencyOverrideMessageWarning",
1949 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1950 override.getName(), a.getIdentifier(), moduleOfA.getName(),
1951 getNodePathString( overriddenMessage ) );
1952
1953 }
1954 }
1955
1956 retainFinalNodes( overriddenMessages );
1957
1958 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1959 {
1960 addDetail( validationContext.getReport(),
1961 "IMPLEMENTATION_DEPENDENCY_FINAL_MESSAGE_CONSTRAINT", Level.SEVERE,
1962 new ObjectFactory().createImplementation( implementation ),
1963 "implementationDependencyFinalMessageConstraint",
1964 implementation.getIdentifier(), moduleOfImpl.getName(),
1965 dependency.getName(), override.getName(), a.getIdentifier(),
1966 moduleOfA.getName(), getNodePathString( overriddenMessage ) );
1967
1968 }
1969 }
1970 }
1971
1972 if ( dependency.getProperties() != null )
1973 {
1974 for ( int j = 0, s1 = dependency.getProperties().getProperty().size(); j < s1; j++ )
1975 {
1976 final Property override = dependency.getProperties().getProperty().get( j );
1977
1978 final Set<InheritanceModel.Node<Property>> overriddenProperties =
1979 modifiableSet( imodel.getPropertyNodes( a.getIdentifier(), override.getName() ) );
1980
1981 if ( override.isOverride() && overriddenProperties.isEmpty() )
1982 {
1983 addDetail( validationContext.getReport(),
1984 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_PROPERTY_CONSTRAINT", Level.SEVERE,
1985 new ObjectFactory().createImplementation( implementation ),
1986 "implementationDependencyOverridePropertyConstraint",
1987 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
1988 override.getName(), a.getIdentifier(), moduleOfA.getName() );
1989
1990 }
1991
1992 if ( !( override.isOverride() || overriddenProperties.isEmpty() ) )
1993 {
1994 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1995 {
1996 addDetail( validationContext.getReport(),
1997 "IMPLEMENTATION_DEPENDENCY_OVERRIDE_PROPERTY_WARNING", Level.WARNING,
1998 new ObjectFactory().createImplementation( implementation ),
1999 "implementationDependencyOverridePropertyWarning",
2000 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
2001 override.getName(), a.getIdentifier(), moduleOfA.getName(),
2002 getNodePathString( overriddenProperty ) );
2003
2004 }
2005 }
2006
2007 retainFinalNodes( overriddenProperties );
2008
2009 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
2010 {
2011 addDetail( validationContext.getReport(),
2012 "IMPLEMENTATION_DEPENDENCY_FINAL_PROPERTY_CONSTRAINT", Level.SEVERE,
2013 new ObjectFactory().createImplementation( implementation ),
2014 "implementationDependencyFinalPropertyConstraint",
2015 implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
2016 override.getName(), a.getIdentifier(), moduleOfA.getName(),
2017 getNodePathString( overriddenProperty ) );
2018
2019 }
2020 }
2021 }
2022 }
2023 }
2024
2025 if ( dependency.getDependencies() != null )
2026 {
2027 for ( int i = 0, s0 = dependency.getDependencies().getDependency().size(); i < s0; i++ )
2028 {
2029 final Dependency d = dependency.getDependencies().getDependency().get( i );
2030 assertDependencyValid( validationContext, implementation, d );
2031 }
2032 }
2033 }
2034
2035 private static void assertImplementationSpecificationCompatibility(
2036 final ValidationContext validationContext, final Implementation implementation )
2037 {
2038 final Specifications specs = validationContext.getModules().getSpecifications( implementation.getIdentifier() );
2039 final Module moduleOfImpl =
2040 validationContext.getModules().getModuleOfImplementation( implementation.getIdentifier() );
2041
2042 if ( specs != null )
2043 {
2044 for ( int i = 0, s0 = specs.getReference().size(); i < s0; i++ )
2045 {
2046 final SpecificationReference r = specs.getReference().get( i );
2047 final Specification s = specs.getSpecification( r.getIdentifier() );
2048
2049 if ( s != null && r.getVersion() != null )
2050 {
2051 final Module moduleOfS =
2052 validationContext.getModules().getModuleOfSpecification( s.getIdentifier() );
2053
2054 if ( s.getVersion() == null )
2055 {
2056 addDetail( validationContext.getReport(),
2057 "IMPLEMENTATION_SPECIFICATION_VERSIONING_CONSTRAINT", Level.SEVERE,
2058 new ObjectFactory().createImplementation( implementation ),
2059 "implementationSpecificationVersioningConstraint", implementation.getIdentifier(),
2060 moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName() );
2061
2062 }
2063 else
2064 {
2065 try
2066 {
2067 if ( VersionParser.compare( r.getVersion(), s.getVersion() ) != 0 )
2068 {
2069 addDetail( validationContext.getReport(),
2070 "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_CONSTRAINT", Level.SEVERE,
2071 new ObjectFactory().createImplementation( implementation ),
2072 "implementationSpecificationCompatibilityConstraint",
2073 implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
2074 moduleOfS.getName(), r.getVersion(), s.getVersion() );
2075
2076 }
2077 }
2078 catch ( final ParseException e )
2079 {
2080 final String message = getMessage( e );
2081
2082 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2083 {
2084 validationContext.getModelContext().log( Level.FINE, message, e );
2085 }
2086
2087 addDetail( validationContext.getReport(),
2088 "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
2089 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
2090 "implementationSpecificationCompatibilityVersioningParseException",
2091 implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
2092 moduleOfS.getName(), r.getVersion(),
2093 message != null && message.length() > 0 ? " " + message : "" );
2094
2095 }
2096 catch ( final TokenMgrError e )
2097 {
2098 final String message = getMessage( e );
2099
2100 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2101 {
2102 validationContext.getModelContext().log( Level.FINE, message, e );
2103 }
2104
2105 addDetail( validationContext.getReport(),
2106 "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
2107 Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
2108 "implementationSpecificationCompatibilityVersioningTokenManagerError",
2109 implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
2110 moduleOfS.getName(), r.getVersion(),
2111 message != null && message.length() > 0 ? " " + message : "" );
2112
2113 }
2114 }
2115 }
2116 }
2117 }
2118 }
2119
2120 private static boolean isInheritanceCycle( final ValidationContext validationContext, final Implementation current,
2121 Map<String, Implementation> implementations, final List<String> path )
2122 {
2123 if ( implementations == null )
2124 {
2125 implementations = new HashMap<String, Implementation>();
2126 }
2127
2128 if ( current != null )
2129 {
2130 path.add( current.getIdentifier() );
2131
2132 if ( implementations.containsKey( current.getIdentifier() ) )
2133 {
2134 return true;
2135 }
2136
2137 implementations.put( current.getIdentifier(), current );
2138
2139 if ( current.getImplementations() != null )
2140 {
2141 for ( int i = 0, s0 = current.getImplementations().getReference().size(); i < s0; i++ )
2142 {
2143 final ImplementationReference r = current.getImplementations().getReference().get( i );
2144 return isInheritanceCycle(
2145 validationContext, validationContext.getModules().getImplementation( r.getIdentifier() ),
2146 implementations, path );
2147
2148 }
2149 }
2150
2151 path.remove( current.getIdentifier() );
2152 }
2153
2154 return false;
2155 }
2156
2157 private static <T> String getNodePathString( final InheritanceModel.Node<T> node )
2158 {
2159 final StringBuilder b = new StringBuilder( node.getPath().size() * 50 );
2160
2161 for ( int i = 0, s0 = node.getPath().size(); i < s0; i++ )
2162 {
2163 final InheritanceModel.Node<Implementation> pathNode = node.getPath().get( i );
2164
2165 if ( pathNode.getClassDeclaration() != null )
2166 {
2167 b.append( " -> [" ).append( pathNode.getClassDeclaration().getClazz() ).append( "] @ '" ).
2168 append( pathNode.getImplementation().getIdentifier() ).append( "'" );
2169
2170 }
2171 if ( pathNode.getSpecification() != null )
2172 {
2173 b.append( " -> <" ).append( pathNode.getSpecification().getIdentifier() ).append( "> @ '" ).
2174 append( pathNode.getImplementation().getIdentifier() ).append( "'" );
2175
2176 }
2177 else
2178 {
2179 b.append( " -> '" ).append( pathNode.getImplementation().getIdentifier() ).append( "'" );
2180 }
2181 }
2182
2183 if ( node.getClassDeclaration() != null )
2184 {
2185 b.append( " -> [" ).append( node.getClassDeclaration().getClazz() ).append( "] @ '" ).
2186 append( node.getImplementation().getIdentifier() ).append( "'" );
2187
2188 }
2189 if ( node.getSpecification() != null )
2190 {
2191 b.append( " -> <" ).append( node.getSpecification().getIdentifier() ).append( "> @ '" ).
2192 append( node.getImplementation().getIdentifier() ).append( "'" );
2193
2194 }
2195
2196 return b.length() > 0 ? b.substring( " -> ".length() ) : b.toString();
2197 }
2198
2199 private static <T> String getNodeListPathString( final Collection<? extends InheritanceModel.Node<T>> nodes )
2200 {
2201 final StringBuilder path = new StringBuilder( nodes.size() * 255 );
2202
2203 for ( final InheritanceModel.Node<T> node : nodes )
2204 {
2205 path.append( ", " ).append( getNodePathString( node ) );
2206 }
2207
2208 return path.length() > 1 ? path.substring( 2 ) : path.toString();
2209 }
2210
2211 private static <T> Set<InheritanceModel.Node<T>> retainFinalNodes( final Set<InheritanceModel.Node<T>> set )
2212 {
2213 if ( set != null )
2214 {
2215 for ( final Iterator<InheritanceModel.Node<T>> it = set.iterator(); it.hasNext(); )
2216 {
2217 if ( !it.next().isFinal() )
2218 {
2219 it.remove();
2220 }
2221 }
2222 }
2223
2224 return set;
2225 }
2226
2227 private static void addDetail(
2228 final ModelValidationReport report, final String identifier, final Level level,
2229 final JAXBElement<? extends ModelObject> element, final String messageKey, final Object... messageArguments )
2230 {
2231 report.getDetails().add( new ModelValidationReport.Detail(
2232 identifier, level, getMessage( messageKey, messageArguments ), element ) );
2233
2234 }
2235
2236 private static <T> Set<T> modifiableSet( final Collection<? extends T> col )
2237 {
2238 Set<T> set = Collections.emptySet();
2239
2240 if ( col != null )
2241 {
2242 set = new HashSet<T>( col );
2243 }
2244
2245 return set;
2246 }
2247
2248 private static String getMessage( final String key, final Object... messageArguments )
2249 {
2250 return MessageFormat.format( ResourceBundle.getBundle(
2251 DefaultModelValidator.class.getName().replace( '.', '/' ),
2252 Locale.getDefault() ).getString( key ), messageArguments );
2253
2254 }
2255
2256 private static String getMessage( final Throwable t )
2257 {
2258 return t != null ? t.getMessage() != null ? t.getMessage() : getMessage( t.getCause() ) : null;
2259 }
2260
2261
2262 private static final class ValidationContext
2263 {
2264
2265 private final ModelContext modelContext;
2266
2267 private final Modules modules;
2268
2269 private final ModelValidationReport report;
2270
2271 private final InheritanceModel inheritanceModel;
2272
2273 private ValidationContext( final ModelContext modelContext, final Modules modules,
2274 final ModelValidationReport report )
2275 {
2276 super();
2277 this.modelContext = modelContext;
2278 this.modules = modules;
2279 this.report = report;
2280 this.inheritanceModel = new InheritanceModel( modules );
2281 }
2282
2283 private ModelContext getModelContext()
2284 {
2285 return modelContext;
2286 }
2287
2288 private Modules getModules()
2289 {
2290 return modules;
2291 }
2292
2293 private ModelValidationReport getReport()
2294 {
2295 return report;
2296 }
2297
2298 private InheritanceModel getInheritanceModel()
2299 {
2300 return this.inheritanceModel;
2301 }
2302
2303 }
2304
2305 }