View Javadoc

1   /*
2    *   Copyright (C) Christian Schulte, 2005-206
3    *   All rights reserved.
4    *
5    *   Redistribution and use in source and binary forms, with or without
6    *   modification, are permitted provided that the following conditions
7    *   are met:
8    *
9    *     o Redistributions of source code must retain the above copyright
10   *       notice, this list of conditions and the following disclaimer.
11   *
12   *     o Redistributions in binary form must reproduce the above copyright
13   *       notice, this list of conditions and the following disclaimer in
14   *       the documentation and/or other materials provided with the
15   *       distribution.
16   *
17   *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18   *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19   *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20   *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21   *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   *
28   *   $JOMC: DefaultModelValidator.java 4937 2014-03-25 01:11:17Z schulte $
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.Locale;
40  import java.util.Map;
41  import java.util.ResourceBundle;
42  import java.util.Set;
43  import java.util.logging.Level;
44  import javax.xml.bind.JAXBElement;
45  import javax.xml.bind.JAXBException;
46  import javax.xml.bind.util.JAXBSource;
47  import javax.xml.namespace.QName;
48  import javax.xml.transform.Source;
49  import org.jomc.model.Argument;
50  import org.jomc.model.Dependency;
51  import org.jomc.model.Implementation;
52  import org.jomc.model.ImplementationReference;
53  import org.jomc.model.Implementations;
54  import org.jomc.model.Inheritable;
55  import org.jomc.model.InheritanceModel;
56  import org.jomc.model.JavaIdentifier;
57  import org.jomc.model.Message;
58  import org.jomc.model.MessageReference;
59  import org.jomc.model.ModelObject;
60  import org.jomc.model.ModelObjectException;
61  import org.jomc.model.Module;
62  import org.jomc.model.Modules;
63  import org.jomc.model.Multiplicity;
64  import org.jomc.model.ObjectFactory;
65  import org.jomc.model.Property;
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   * Default object management and configuration {@code ModelValidator} implementation.
83   *
84   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
85   * @version $JOMC: DefaultModelValidator.java 4937 2014-03-25 01:11:17Z schulte $
86   * @see ModelContext#validateModel(org.jomc.modlet.Model)
87   */
88  public class DefaultModelValidator implements ModelValidator
89  {
90  
91      /**
92       * Constant for the name of the model context attribute backing property {@code enabled}.
93       * @see #validateModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
94       * @see ModelContext#getAttribute(java.lang.String)
95       * @since 1.7
96       */
97      public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.model.modlet.DefaultModelValidator.enabledAttribute";
98  
99      /**
100      * Constant for the name of the system property controlling property {@code defaultEnabled}.
101      * @see #isDefaultEnabled()
102      * @since 1.7
103      */
104     private static final String DEFAULT_ENABLED_PROPERTY_NAME =
105         "org.jomc.model.modlet.DefaultModelValidator.defaultEnabled";
106 
107     /**
108      * Default value of the flag indicating the validator is enabled by default.
109      * @see #isDefaultEnabled()
110      * @since 1.7
111      */
112     private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
113 
114     /**
115      * Flag indicating the validator is enabled by default.
116      * @since 1.7
117      */
118     private static volatile Boolean defaultEnabled;
119 
120     /**
121      * Flag indicating the validator is enabled.
122      * @since 1.7
123      */
124     private Boolean enabled;
125 
126     /**
127      * Constant for the name of the model context attribute backing property {@code validateJava}.
128      * @see ModelContext#getAttribute(java.lang.String)
129      * @since 1.4
130      */
131     public static final String VALIDATE_JAVA_ATTRIBUTE_NAME =
132         "org.jomc.model.modlet.DefaultModelValidator.validateJavaAttribute";
133 
134     /**
135      * Constant for the name of the system property controlling property {@code defaultValidateJava}.
136      * @see #isDefaultValidateJava()
137      * @since 1.4
138      */
139     private static final String DEFAULT_VALIDATE_JAVA_PROPERTY_NAME =
140         "org.jomc.model.modlet.DefaultModelValidator.defaultValidateJava";
141 
142     /**
143      * Default value of the flag indicating the validator is performing Java related validation by default.
144      * @see #isDefaultValidateJava()
145      * @since 1.4
146      */
147     private static final Boolean DEFAULT_VALIDATE_JAVA = Boolean.TRUE;
148 
149     /**
150      * Flag indicating the validator is performing Java related validation by default.
151      * @since 1.4
152      */
153     private static volatile Boolean defaultValidateJava;
154 
155     /**
156      * Flag indicating the validator is performing Java related validation.
157      * @since 1.4
158      */
159     private Boolean validateJava;
160 
161     /** Creates a new {@code DefaultModelValidator} instance. */
162     public DefaultModelValidator()
163     {
164         super();
165     }
166 
167     /**
168      * Gets a flag indicating the validator is enabled by default.
169      * <p>
170      * The default enabled flag is controlled by system property
171      * {@code org.jomc.model.modlet.DefaultModelValidator.defaultEnabled} holding a value indicating the validator is
172      * enabled by default. If that property is not set, the {@code true} default is returned.
173      *
174      * @return {@code true}, if the validator is enabled by default; {@code false}, if the validator is disabled by
175      * default.
176      *
177      * @see #setDefaultEnabled(java.lang.Boolean)
178      * @since 1.7
179      */
180     public static boolean isDefaultEnabled()
181     {
182         if ( defaultEnabled == null )
183         {
184             defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
185                                                                   Boolean.toString( DEFAULT_ENABLED ) ) );
186 
187         }
188 
189         return defaultEnabled;
190     }
191 
192     /**
193      * Sets the flag indicating the validator is enabled by default.
194      *
195      * @param value The new value of the flag indicating the validator is enabled by default or {@code null}.
196      *
197      * @see #isDefaultEnabled()
198      * @since 1.7
199      */
200     public static void setDefaultEnabled( final Boolean value )
201     {
202         defaultEnabled = value;
203     }
204 
205     /**
206      * Gets a flag indicating the validator is enabled.
207      *
208      * @return {@code true}, if the validator is enabled; {@code false}, if the validator is disabled.
209      *
210      * @see #isDefaultEnabled()
211      * @see #setEnabled(java.lang.Boolean)
212      * @since 1.7
213      */
214     public final boolean isEnabled()
215     {
216         if ( this.enabled == null )
217         {
218             this.enabled = isDefaultEnabled();
219         }
220 
221         return this.enabled;
222     }
223 
224     /**
225      * Sets the flag indicating the validator is enabled.
226      *
227      * @param value The new value of the flag indicating the validator is enabled or {@code null}.
228      *
229      * @see #isEnabled()
230      * @since 1.7
231      */
232     public final void setEnabled( final Boolean value )
233     {
234         this.enabled = value;
235     }
236 
237     /**
238      * Gets a flag indicating the validator is performing Java related validation by default.
239      * <p>The default validate Java flag is controlled by system property
240      * {@code org.jomc.model.modlet.DefaultModelValidator.defaultValidateJava} holding a value indicating the validator
241      * is performing Java related validation by default. If that property is not set, the {@code true} default is
242      * returned.</p>
243      *
244      * @return {@code true}, if the validator is performing Java related validation by default; {@code false}, if the
245      * validator is not performing Java related validation by default.
246      *
247      * @see #setDefaultValidateJava(java.lang.Boolean)
248      *
249      * @since 1.4
250      */
251     public static boolean isDefaultValidateJava()
252     {
253         if ( defaultValidateJava == null )
254         {
255             defaultValidateJava = Boolean.valueOf( System.getProperty( DEFAULT_VALIDATE_JAVA_PROPERTY_NAME,
256                                                                        Boolean.toString( DEFAULT_VALIDATE_JAVA ) ) );
257 
258         }
259 
260         return defaultValidateJava;
261     }
262 
263     /**
264      * Sets the flag indicating the validator is performing Java related validation by default.
265      *
266      * @param value The new value of the flag indicating the validator is performing Java related validation by default
267      * or {@code null}.
268      *
269      * @see #isDefaultValidateJava()
270      *
271      * @since 1.4
272      */
273     public static void setDefaultValidateJava( final Boolean value )
274     {
275         defaultValidateJava = value;
276     }
277 
278     /**
279      * Gets a flag indicating the validator is performing Java related validation.
280      *
281      * @return {@code true}, if the validator is performing Java related validation; {@code false}, if the the validator
282      * is not performing Java related validation.
283      *
284      * @see #isDefaultValidateJava()
285      * @see #setValidateJava(java.lang.Boolean)
286      *
287      * @since 1.4
288      */
289     public final boolean isValidateJava()
290     {
291         if ( this.validateJava == null )
292         {
293             this.validateJava = isDefaultValidateJava();
294         }
295 
296         return this.validateJava;
297     }
298 
299     /**
300      * Sets the flag indicating the validator is performing Java related validation.
301      *
302      * @param value The new value of the flag indicating the validator is performing Java related validation or
303      * {@code null}.
304      *
305      * @see #isValidateJava()
306      *
307      * @since 1.4
308      */
309     public final void setValidateJava( final Boolean value )
310     {
311         this.validateJava = value;
312     }
313 
314     public ModelValidationReport validateModel( final ModelContext context, final Model model ) throws ModelException
315     {
316         if ( context == null )
317         {
318             throw new NullPointerException( "context" );
319         }
320         if ( model == null )
321         {
322             throw new NullPointerException( "model" );
323         }
324 
325         boolean contextEnabled = this.isEnabled();
326         if ( DEFAULT_ENABLED == contextEnabled
327                  && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
328         {
329             contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
330         }
331 
332         boolean contextValidateJava = this.isValidateJava();
333         if ( DEFAULT_VALIDATE_JAVA == contextValidateJava
334                  && context.getAttribute( VALIDATE_JAVA_ATTRIBUTE_NAME ) instanceof Boolean )
335         {
336             contextValidateJava = (Boolean) context.getAttribute( VALIDATE_JAVA_ATTRIBUTE_NAME );
337         }
338 
339         try
340         {
341             ModelValidationReport report = new ModelValidationReport();
342 
343             if ( contextEnabled )
344             {
345                 final Source source = new JAXBSource( context.createContext( model.getIdentifier() ),
346                                                       new org.jomc.modlet.ObjectFactory().createModel( model ) );
347 
348                 report = context.validateModel( model.getIdentifier(), source );
349 
350                 final Modules modules = ModelHelper.getModules( model );
351 
352                 if ( modules != null )
353                 {
354                     final ValidationContext validationContext =
355                         new ValidationContext( context, modules, report, contextValidateJava );
356 
357                     assertModulesValid( validationContext );
358                     assertSpecificationsValid( validationContext );
359                     assertImplementationsValid( validationContext );
360                 }
361             }
362             else if ( context.isLoggable( Level.FINER ) )
363             {
364                 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
365                                                       model.getIdentifier() ), null );
366 
367             }
368 
369             return report;
370         }
371         catch ( final JAXBException e )
372         {
373             String message = getMessage( e );
374             if ( message == null && e.getLinkedException() != null )
375             {
376                 message = getMessage( e.getLinkedException() );
377             }
378 
379             if ( context.isLoggable( Level.FINE ) )
380             {
381                 context.log( Level.FINE, message, e );
382             }
383 
384             throw new ModelException( message, e );
385         }
386     }
387 
388     private static void assertModulesValid( final ValidationContext validationContext )
389     {
390         for ( int i = 0, s0 = validationContext.getModules().getModule().size(); i < s0; i++ )
391         {
392             final Module m = validationContext.getModules().getModule().get( i );
393 
394             if ( m.getImplementations() != null )
395             {
396                 for ( int j = 0, s1 = m.getImplementations().getReference().size(); j < s1; j++ )
397                 {
398                     final ImplementationReference r = m.getImplementations().getReference().get( j );
399                     addDetail( validationContext.getReport(), "MODULE_IMPLEMENTATION_REFERENCE_DECLARATION_CONSTRAINT",
400                                Level.SEVERE, new ObjectFactory().createModule( m ),
401                                "moduleImplementationReferenceDeclarationConstraint", m.getName(), r.getIdentifier() );
402 
403                 }
404             }
405 
406             if ( m.getMessages() != null )
407             {
408                 for ( int j = 0, s1 = m.getMessages().getMessage().size(); j < s1; j++ )
409                 {
410                     final Message msg = m.getMessages().getMessage().get( j );
411 
412                     if ( msg.isFinal() )
413                     {
414                         addDetail( validationContext.getReport(), "MODULE_FINAL_MESSAGE_DECLARATION_CONSTRAINT",
415                                    Level.SEVERE, new ObjectFactory().createModule( m ), "moduleFinalMessageConstraint",
416                                    m.getName(), msg.getName() );
417 
418                     }
419 
420                     if ( msg.isOverride() )
421                     {
422                         addDetail( validationContext.getReport(), "MODULE_OVERRIDE_MESSAGE_DECLARATION_CONSTRAINT",
423                                    Level.SEVERE, new ObjectFactory().createModule( m ),
424                                    "moduleOverrideMessageConstraint", m.getName(), msg.getName() );
425 
426                     }
427 
428                     if ( validationContext.isValidateJava() )
429                     {
430                         try
431                         {
432                             msg.getJavaConstantName();
433                         }
434                         catch ( final ModelObjectException e )
435                         {
436                             final String message = getMessage( e );
437 
438                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
439                             {
440                                 validationContext.getModelContext().log( Level.FINE, message, e );
441                             }
442 
443                             addDetail( validationContext.getReport(),
444                                        "MODULE_MESSAGE_JAVA_CONSTANT_NAME_CONSTRAINT",
445                                        Level.SEVERE, new ObjectFactory().createModule( m ),
446                                        "moduleMessageJavaConstantNameConstraint", m.getName(), msg.getName(),
447                                        message != null && message.length() > 0 ? " " + message : "" );
448 
449                         }
450 
451                         try
452                         {
453                             msg.getJavaGetterMethodName();
454                         }
455                         catch ( final ModelObjectException e )
456                         {
457                             final String message = getMessage( e );
458 
459                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
460                             {
461                                 validationContext.getModelContext().log( Level.FINE, message, e );
462                             }
463 
464                             addDetail( validationContext.getReport(),
465                                        "MODULE_MESSAGE_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
466                                        Level.SEVERE, new ObjectFactory().createModule( m ),
467                                        "moduleMessageJavaGetterMethodNameConstraint", m.getName(), msg.getName(),
468                                        message != null && message.length() > 0 ? " " + message : "" );
469 
470                         }
471 
472                         try
473                         {
474                             msg.getJavaSetterMethodName();
475                         }
476                         catch ( final ModelObjectException e )
477                         {
478                             final String message = getMessage( e );
479 
480                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
481                             {
482                                 validationContext.getModelContext().log( Level.FINE, message, e );
483                             }
484 
485                             addDetail( validationContext.getReport(),
486                                        "MODULE_MESSAGE_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
487                                        Level.SEVERE, new ObjectFactory().createModule( m ),
488                                        "moduleMessageJavaSetterMethodNameConstraint", m.getName(), msg.getName(),
489                                        message != null && message.length() > 0 ? " " + message : "" );
490 
491                         }
492 
493                         try
494                         {
495                             msg.getJavaVariableName();
496                         }
497                         catch ( final ModelObjectException e )
498                         {
499                             final String message = getMessage( e );
500 
501                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
502                             {
503                                 validationContext.getModelContext().log( Level.FINE, message, e );
504                             }
505 
506                             addDetail( validationContext.getReport(),
507                                        "MODULE_MESSAGE_JAVA_VARIABLE_NAME_CONSTRAINT",
508                                        Level.SEVERE, new ObjectFactory().createModule( m ),
509                                        "moduleMessageJavaVariableNameConstraint", m.getName(), msg.getName(),
510                                        message != null && message.length() > 0 ? " " + message : "" );
511 
512                         }
513                     }
514 
515                     if ( msg.getTemplate() != null )
516                     {
517                         for ( int k = 0, s2 = msg.getTemplate().getText().size(); k < s2; k++ )
518                         {
519                             final Text t = msg.getTemplate().getText().get( k );
520 
521                             try
522                             {
523                                 t.getMimeType();
524                             }
525                             catch ( final ModelObjectException e )
526                             {
527                                 final String message = getMessage( e );
528 
529                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
530                                 {
531                                     validationContext.getModelContext().log( Level.FINE, message, e );
532                                 }
533 
534                                 addDetail( validationContext.getReport(),
535                                            "MODULE_MESSAGE_TEMPLATE_MIME_TYPE_CONSTRAINT",
536                                            Level.SEVERE, new ObjectFactory().createModule( m ),
537                                            "moduleMessageTemplateMimeTypeConstraint", m.getName(), msg.getName(),
538                                            t.getLanguage(),
539                                            message != null && message.length() > 0 ? " " + message : "" );
540 
541                             }
542 
543                             if ( validationContext.isValidateJava() )
544                             {
545                                 try
546                                 {
547                                     new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
548                                 }
549                                 catch ( final IllegalArgumentException e )
550                                 {
551                                     final String message = getMessage( e );
552 
553                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
554                                     {
555                                         validationContext.getModelContext().log( Level.FINE, message, e );
556                                     }
557 
558                                     addDetail( validationContext.getReport(), "MODULE_MESSAGE_TEMPLATE_CONSTRAINT",
559                                                Level.SEVERE, new ObjectFactory().createModule( m ),
560                                                "moduleMessageTemplateConstraint", m.getName(), msg.getName(),
561                                                t.getValue(),
562                                                message != null && message.length() > 0 ? " " + message : "" );
563 
564                                 }
565                             }
566                         }
567                     }
568 
569                     if ( msg.getArguments() != null )
570                     {
571                         final Map<JavaIdentifier, Argument> javaVariableNames =
572                             new HashMap<JavaIdentifier, Argument>( msg.getArguments().getArgument().size() );
573 
574                         for ( int k = 0, s2 = msg.getArguments().getArgument().size(); k < s2; k++ )
575                         {
576                             final Argument a = msg.getArguments().getArgument( k );
577 
578                             if ( validationContext.isValidateJava() )
579                             {
580                                 try
581                                 {
582                                     a.getJavaTypeName();
583                                 }
584                                 catch ( final ModelObjectException e )
585                                 {
586                                     final String message = getMessage( e );
587 
588                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
589                                     {
590                                         validationContext.getModelContext().log( Level.FINE, message, e );
591                                     }
592 
593                                     addDetail( validationContext.getReport(),
594                                                "MODULE_MESSAGE_ARGUMENT_JAVA_TYPE_NAME_CONSTRAINT",
595                                                Level.SEVERE, new ObjectFactory().createModule( m ),
596                                                "moduleMessageArgumentJavaTypeNameConstraint", m.getName(),
597                                                msg.getName(), a.getIndex(),
598                                                message != null && message.length() > 0 ? " " + message : "" );
599 
600                                 }
601 
602                                 try
603                                 {
604                                     final JavaIdentifier javaIdentifier = a.getJavaVariableName();
605 
606                                     if ( javaVariableNames.containsKey( javaIdentifier ) )
607                                     {
608                                         addDetail( validationContext.getReport(),
609                                                    "MODULE_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
610                                                    Level.SEVERE, new ObjectFactory().createModule( m ),
611                                                    "moduleMessageArgumentJavaVariableNameUniquenessConstraint",
612                                                    m.getName(), msg.getName(), a.getName(),
613                                                    javaIdentifier, javaVariableNames.get( javaIdentifier ).getName() );
614 
615                                     }
616                                     else
617                                     {
618                                         javaVariableNames.put( javaIdentifier, a );
619                                     }
620                                 }
621                                 catch ( final ModelObjectException e )
622                                 {
623                                     final String message = getMessage( e );
624 
625                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
626                                     {
627                                         validationContext.getModelContext().log( Level.FINE, message, e );
628                                     }
629 
630                                     addDetail( validationContext.getReport(),
631                                                "MODULE_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_CONSTRAINT",
632                                                Level.SEVERE, new ObjectFactory().createModule( m ),
633                                                "moduleMessageArgumentJavaVariableNameConstraint", m.getName(),
634                                                msg.getName(), a.getIndex(),
635                                                message != null && message.length() > 0 ? " " + message : "" );
636 
637                                 }
638                             }
639                         }
640                     }
641                 }
642 
643                 for ( int j = 0, s1 = m.getMessages().getReference().size(); j < s1; j++ )
644                 {
645                     final MessageReference r = m.getMessages().getReference().get( j );
646                     addDetail( validationContext.getReport(), "MODULE_MESSAGE_REFERENCE_DECLARATION_CONSTRAINT",
647                                Level.SEVERE, new ObjectFactory().createModule( m ),
648                                "moduleMessageReferenceDeclarationConstraint", m.getName(), r.getName() );
649 
650                 }
651             }
652 
653             if ( m.getProperties() != null )
654             {
655                 for ( int j = 0, s1 = m.getProperties().getProperty().size(); j < s1; j++ )
656                 {
657                     final Property p = m.getProperties().getProperty().get( j );
658 
659                     if ( p.isFinal() )
660                     {
661                         addDetail( validationContext.getReport(), "MODULE_FINAL_PROPERTY_DECLARATION_CONSTRAINT",
662                                    Level.SEVERE, new ObjectFactory().createModule( m ), "moduleFinalPropertyConstraint",
663                                    m.getName(), p.getName() );
664 
665                     }
666 
667                     if ( p.isOverride() )
668                     {
669                         addDetail( validationContext.getReport(), "MODULE_OVERRIDE_PROPERTY_DECLARATION_CONSTRAINT",
670                                    Level.SEVERE, new ObjectFactory().createModule( m ),
671                                    "moduleOverridePropertyConstraint", m.getName(), p.getName() );
672 
673                     }
674 
675                     if ( p.getValue() != null && p.getAny() != null )
676                     {
677                         addDetail( validationContext.getReport(), "MODULE_PROPERTY_VALUE_CONSTRAINT", Level.SEVERE,
678                                    new ObjectFactory().createModule( m ), "modulePropertyValueConstraint", m.getName(),
679                                    p.getName() );
680 
681                     }
682 
683                     if ( p.getAny() != null && p.getType() == null )
684                     {
685                         addDetail( validationContext.getReport(), "MODULE_PROPERTY_TYPE_CONSTRAINT", Level.SEVERE,
686                                    new ObjectFactory().createModule( m ), "modulePropertyTypeConstraint", m.getName(),
687                                    p.getName() );
688 
689                     }
690 
691                     if ( validationContext.isValidateJava() )
692                     {
693                         try
694                         {
695                             p.getJavaConstantName();
696                         }
697                         catch ( final ModelObjectException e )
698                         {
699                             final String message = getMessage( e );
700 
701                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
702                             {
703                                 validationContext.getModelContext().log( Level.FINE, message, e );
704                             }
705 
706                             addDetail( validationContext.getReport(),
707                                        "MODULE_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT",
708                                        Level.SEVERE, new ObjectFactory().createModule( m ),
709                                        "modulePropertyJavaConstantNameConstraint", m.getName(), p.getName(),
710                                        message != null && message.length() > 0 ? " " + message : "" );
711 
712                         }
713 
714                         try
715                         {
716                             p.getJavaGetterMethodName();
717                         }
718                         catch ( final ModelObjectException e )
719                         {
720                             final String message = getMessage( e );
721 
722                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
723                             {
724                                 validationContext.getModelContext().log( Level.FINE, message, e );
725                             }
726 
727                             addDetail( validationContext.getReport(),
728                                        "MODULE_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
729                                        Level.SEVERE, new ObjectFactory().createModule( m ),
730                                        "modulePropertyJavaGetterMethodNameConstraint", m.getName(), p.getName(),
731                                        message != null && message.length() > 0 ? " " + message : "" );
732 
733                         }
734 
735                         try
736                         {
737                             p.getJavaSetterMethodName();
738                         }
739                         catch ( final ModelObjectException e )
740                         {
741                             final String message = getMessage( e );
742 
743                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
744                             {
745                                 validationContext.getModelContext().log( Level.FINE, message, e );
746                             }
747 
748                             addDetail( validationContext.getReport(),
749                                        "MODULE_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
750                                        Level.SEVERE, new ObjectFactory().createModule( m ),
751                                        "modulePropertyJavaSetterMethodNameConstraint", m.getName(), p.getName(),
752                                        message != null && message.length() > 0 ? " " + message : "" );
753 
754                         }
755 
756                         try
757                         {
758                             p.getJavaTypeName();
759                         }
760                         catch ( final ModelObjectException e )
761                         {
762                             final String message = getMessage( e );
763 
764                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
765                             {
766                                 validationContext.getModelContext().log( Level.FINE, message, e );
767                             }
768 
769                             addDetail( validationContext.getReport(),
770                                        "MODULE_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
771                                        Level.SEVERE, new ObjectFactory().createModule( m ),
772                                        "modulePropertyJavaTypeNameConstraint", m.getName(), p.getName(),
773                                        message != null && message.length() > 0 ? " " + message : "" );
774 
775                         }
776 
777                         try
778                         {
779                             p.getJavaVariableName();
780                         }
781                         catch ( final ModelObjectException e )
782                         {
783                             final String message = getMessage( e );
784 
785                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
786                             {
787                                 validationContext.getModelContext().log( Level.FINE, message, e );
788                             }
789 
790                             addDetail( validationContext.getReport(),
791                                        "MODULE_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
792                                        Level.SEVERE, new ObjectFactory().createModule( m ),
793                                        "modulePropertyJavaVariableNameConstraint", m.getName(), p.getName(),
794                                        message != null && message.length() > 0 ? " " + message : "" );
795 
796                         }
797 
798                         try
799                         {
800                             p.getJavaValue( validationContext.getModelContext().getClassLoader() );
801                         }
802                         catch ( final ModelObjectException e )
803                         {
804                             final String message = getMessage( e );
805 
806                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
807                             {
808                                 validationContext.getModelContext().log( Level.FINE, message, e );
809                             }
810 
811                             addDetail( validationContext.getReport(), "MODULE_PROPERTY_JAVA_VALUE_CONSTRAINT",
812                                        Level.SEVERE, new ObjectFactory().createModule( m ),
813                                        "modulePropertyJavaValueConstraint", m.getName(), p.getName(),
814                                        message != null && message.length() > 0 ? " " + message : "" );
815 
816                         }
817                     }
818                 }
819 
820                 for ( int j = 0, s1 = m.getProperties().getReference().size(); j < s1; j++ )
821                 {
822                     final PropertyReference r = m.getProperties().getReference().get( j );
823                     addDetail( validationContext.getReport(), "MODULE_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT",
824                                Level.SEVERE, new ObjectFactory().createModule( m ),
825                                "modulePropertyReferenceDeclarationConstraint", m.getName(), r.getName() );
826 
827                 }
828             }
829 
830             if ( m.getSpecifications() != null )
831             {
832                 for ( int j = 0, s1 = m.getSpecifications().getReference().size(); j < s1; j++ )
833                 {
834                     final SpecificationReference r = m.getSpecifications().getReference().get( j );
835                     addDetail( validationContext.getReport(), "MODULE_SPECIFICATION_REFERENCE_DECLARATION_CONSTRAINT",
836                                Level.SEVERE, new ObjectFactory().createModule( m ),
837                                "moduleSpecificationReferenceDeclarationConstraint", m.getName(), r.getIdentifier() );
838 
839                 }
840             }
841         }
842     }
843 
844     private static void assertImplementationsValid( final ValidationContext validationContext )
845     {
846         final Implementations implementations = validationContext.getAllImplementations();
847 
848         if ( implementations != null )
849         {
850             final Map<String, Implementation> implementationClassDeclarations = new HashMap<String, Implementation>();
851             final Map<String, Implementation> implementationJavaClassDeclarations =
852                 new HashMap<String, Implementation>();
853 
854             for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
855             {
856                 final Implementation impl = implementations.getImplementation().get( i );
857                 final InheritanceModel imodel = validationContext.getInheritanceModel();
858                 final Module moduleOfImpl = validationContext.getModuleOfImplementation( impl.getIdentifier() );
859                 final Set<InheritanceModel.Node<ImplementationReference>> cyclicImplementationReferenceNodes =
860                     imodel.getCycleNodes( impl.getIdentifier() );
861 
862                 for ( final InheritanceModel.Node<ImplementationReference> node : cyclicImplementationReferenceNodes )
863                 {
864                     addDetail( validationContext.getReport(), "IMPLEMENTATION_INHERITANCE_CYCLE_CONSTRAINT",
865                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
866                                "implementationInheritanceCycleConstraint", impl.getIdentifier(),
867                                moduleOfImpl.getName(), getNodePathString( node ) );
868 
869                 }
870 
871                 if ( validationContext.isValidateJava() )
872                 {
873                     try
874                     {
875                         impl.getJavaTypeName();
876                     }
877                     catch ( final ModelObjectException e )
878                     {
879                         final String message = getMessage( e );
880 
881                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
882                         {
883                             validationContext.getModelContext().log( Level.FINE, message, e );
884                         }
885 
886                         addDetail( validationContext.getReport(),
887                                    "IMPLEMENTATION_JAVA_TYPE_NAME_CONSTRAINT",
888                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
889                                    "implementationJavaTypeNameConstraint", impl.getIdentifier(),
890                                    moduleOfImpl.getName(), impl.getClazz(),
891                                    message != null && message.length() > 0 ? " " + message : "" );
892 
893                     }
894                 }
895 
896                 if ( impl.isClassDeclaration() )
897                 {
898                     if ( impl.getClazz() == null )
899                     {
900                         addDetail( validationContext.getReport(), "IMPLEMENTATION_CLASS_CONSTRAINT", Level.SEVERE,
901                                    new ObjectFactory().createImplementation( impl ), "implementationClassConstraint",
902                                    impl.getIdentifier(), moduleOfImpl.getName() );
903 
904                     }
905                     else
906                     {
907                         final Implementation prev = implementationClassDeclarations.get( impl.getClazz() );
908 
909                         if ( prev != null && !prev.getIdentifier().equals( impl.getIdentifier() ) )
910                         {
911                             final Module moduleOfPrev =
912                                 validationContext.getModuleOfImplementation( prev.getIdentifier() );
913 
914                             addDetail( validationContext.getReport(), "IMPLEMENTATION_CLASS_DECLARATION_CONSTRAINT",
915                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
916                                        "implementationClassDeclarationConstraint", impl.getIdentifier(),
917                                        moduleOfImpl.getName(), impl.getClazz(), prev.getIdentifier(),
918                                        moduleOfPrev.getName() );
919 
920                         }
921                         else
922                         {
923                             implementationClassDeclarations.put( impl.getClazz(), impl );
924                         }
925 
926                         if ( validationContext.isValidateJava() )
927                         {
928                             try
929                             {
930                                 final Implementation java =
931                                     implementationJavaClassDeclarations.get( impl.getJavaTypeName().getClassName() );
932 
933                                 if ( java != null && !java.getIdentifier().equals( impl.getIdentifier() ) )
934                                 {
935                                     final Module moduleOfJava =
936                                         validationContext.getModuleOfImplementation( java.getIdentifier() );
937 
938                                     addDetail( validationContext.getReport(),
939                                                "IMPLEMENTATION_JAVA_CLASS_DECLARATION_CONSTRAINT",
940                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
941                                                "implementationJavaClassDeclarationConstraint", impl.getIdentifier(),
942                                                moduleOfImpl.getName(), impl.getJavaTypeName().getClassName(),
943                                                java.getIdentifier(), moduleOfJava.getName() );
944 
945                                 }
946                                 else
947                                 {
948                                     implementationJavaClassDeclarations.put( impl.getJavaTypeName().getClassName(),
949                                                                              impl );
950 
951                                 }
952                             }
953                             catch ( final ModelObjectException e )
954                             {
955                                 // Already validated above.
956                             }
957                         }
958                     }
959                 }
960 
961                 if ( impl.isAbstract() && impl.getLocation() != null )
962                 {
963                     addDetail( validationContext.getReport(), "IMPLEMENTATION_ABSTRACT_LOCATION_DECLARATION_CONSTRAINT",
964                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
965                                "implementationAbstractLocationDeclarationConstraint", impl.getIdentifier(),
966                                moduleOfImpl.getName(), impl.getLocation() );
967 
968                 }
969 
970                 if ( impl.getDependencies() != null )
971                 {
972                     for ( int j = 0, s1 = impl.getDependencies().getDependency().size(); j < s1; j++ )
973                     {
974                         final Dependency d = impl.getDependencies().getDependency().get( j );
975 
976                         final Set<InheritanceModel.Node<Dependency>> effDependencies =
977                             imodel.getDependencyNodes( impl.getIdentifier(), d.getName() );
978 
979                         for ( final InheritanceModel.Node<Dependency> effDependency : effDependencies )
980                         {
981                             final Set<InheritanceModel.Node<Dependency>> overriddenDependencies =
982                                 modifiableSet( effDependency.getOverriddenNodes() );
983 
984                             if ( d.isOverride() && effDependency.getOverriddenNodes().isEmpty() )
985                             {
986                                 addDetail( validationContext.getReport(),
987                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_CONSTRAINT",
988                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
989                                            "implementationDependencyOverrideConstraint", impl.getIdentifier(),
990                                            moduleOfImpl.getName(), d.getName() );
991 
992                             }
993 
994                             if ( !( d.isOverride() || overriddenDependencies.isEmpty() ) )
995                             {
996                                 for ( final InheritanceModel.Node<Dependency> overriddenDependency
997                                       : overriddenDependencies )
998                                 {
999                                     Implementation overriddenImplementation = overriddenDependency.getImplementation();
1000                                     if ( overriddenDependency.getClassDeclaration() != null )
1001                                     {
1002                                         overriddenImplementation = overriddenDependency.getClassDeclaration();
1003                                     }
1004 
1005                                     final Module moduleOfDependency =
1006                                         validationContext.getModuleOfImplementation(
1007                                             overriddenImplementation.getIdentifier() );
1008 
1009                                     addDetail( validationContext.getReport(),
1010                                                "IMPLEMENTATION_DEPENDENCY_OVERRIDE_WARNING",
1011                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1012                                                "implementationDependencyOverrideWarning", impl.getIdentifier(),
1013                                                moduleOfImpl.getName(), d.getName(),
1014                                                overriddenImplementation.getIdentifier(),
1015                                                moduleOfDependency.getName(),
1016                                                getNodePathString( overriddenDependency ) );
1017 
1018                                 }
1019                             }
1020 
1021                             retainFinalNodes( overriddenDependencies );
1022 
1023                             for ( final InheritanceModel.Node<Dependency> overriddenDependency : overriddenDependencies )
1024                             {
1025                                 Implementation overriddenImplementation = overriddenDependency.getImplementation();
1026                                 if ( overriddenDependency.getClassDeclaration() != null )
1027                                 {
1028                                     overriddenImplementation = overriddenDependency.getClassDeclaration();
1029                                 }
1030 
1031                                 final Module moduleOfDependency =
1032                                     validationContext.getModuleOfImplementation(
1033                                     overriddenImplementation.getIdentifier() );
1034 
1035                                 addDetail( validationContext.getReport(),
1036                                            "IMPLEMENTATION_DEPENDENCY_INHERITANCE_CONSTRAINT", Level.SEVERE,
1037                                            new ObjectFactory().createImplementation( impl ),
1038                                            "implementationDependencyFinalConstraint", impl.getIdentifier(),
1039                                            moduleOfImpl.getName(), d.getName(),
1040                                            overriddenImplementation.getIdentifier(),
1041                                            moduleOfDependency.getName(),
1042                                            getNodePathString( overriddenDependency ) );
1043 
1044                             }
1045                         }
1046 
1047                         if ( validationContext.isValidateJava() )
1048                         {
1049                             try
1050                             {
1051                                 d.getJavaConstantName();
1052                             }
1053                             catch ( final ModelObjectException e )
1054                             {
1055                                 final String message = getMessage( e );
1056 
1057                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1058                                 {
1059                                     validationContext.getModelContext().log( Level.FINE, message, e );
1060                                 }
1061 
1062                                 addDetail( validationContext.getReport(),
1063                                            "IMPLEMENTATION_DEPENDENCY_JAVA_CONSTANT_NAME_CONSTRAINT",
1064                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1065                                            "implementationDependencyJavaConstantNameConstraint", impl.getIdentifier(),
1066                                            moduleOfImpl.getName(), d.getName(),
1067                                            message != null && message.length() > 0 ? " " + message : "" );
1068 
1069                             }
1070 
1071                             try
1072                             {
1073                                 d.getJavaGetterMethodName();
1074                             }
1075                             catch ( final ModelObjectException e )
1076                             {
1077                                 final String message = getMessage( e );
1078 
1079                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1080                                 {
1081                                     validationContext.getModelContext().log( Level.FINE, message, e );
1082                                 }
1083 
1084                                 addDetail( validationContext.getReport(),
1085                                            "IMPLEMENTATION_DEPENDENCY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
1086                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1087                                            "implementationDependencyJavaGetterMethodNameConstraint",
1088                                            impl.getIdentifier(), moduleOfImpl.getName(), d.getName(),
1089                                            message != null && message.length() > 0 ? " " + message : "" );
1090 
1091                             }
1092 
1093                             try
1094                             {
1095                                 d.getJavaSetterMethodName();
1096                             }
1097                             catch ( final ModelObjectException e )
1098                             {
1099                                 final String message = getMessage( e );
1100 
1101                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1102                                 {
1103                                     validationContext.getModelContext().log( Level.FINE, message, e );
1104                                 }
1105 
1106                                 addDetail( validationContext.getReport(),
1107                                            "IMPLEMENTATION_DEPENDENCY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
1108                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1109                                            "implementationDependencyJavaSetterMethodNameConstraint",
1110                                            impl.getIdentifier(), moduleOfImpl.getName(), d.getName(),
1111                                            message != null && message.length() > 0 ? " " + message : "" );
1112 
1113                             }
1114 
1115                             try
1116                             {
1117                                 d.getJavaVariableName();
1118                             }
1119                             catch ( final ModelObjectException e )
1120                             {
1121                                 final String message = getMessage( e );
1122 
1123                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1124                                 {
1125                                     validationContext.getModelContext().log( Level.FINE, message, e );
1126                                 }
1127 
1128                                 addDetail( validationContext.getReport(),
1129                                            "IMPLEMENTATION_DEPENDENCY_JAVA_VARIABLE_NAME_CONSTRAINT",
1130                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1131                                            "implementationDependencyJavaVariableNameConstraint",
1132                                            impl.getIdentifier(), moduleOfImpl.getName(), d.getName(),
1133                                            message != null && message.length() > 0 ? " " + message : "" );
1134 
1135                             }
1136                         }
1137 
1138                         assertDependencyValid( validationContext, impl, d );
1139                     }
1140                 }
1141 
1142                 if ( impl.getImplementations() != null )
1143                 {
1144                     final Set<String> effImplementationReferences =
1145                         imodel.getImplementationReferenceIdentifiers( impl.getIdentifier() );
1146 
1147                     for ( final String effImplementationReference : effImplementationReferences )
1148                     {
1149                         final Implementation ancestorImplementation =
1150                             validationContext.getImplementation( effImplementationReference );
1151 
1152                         if ( ancestorImplementation != null && ancestorImplementation.isFinal() )
1153                         {
1154                             final Module moduleOfFinal =
1155                                 validationContext.getModuleOfImplementation( ancestorImplementation.getIdentifier() );
1156 
1157                             addDetail( validationContext.getReport(),
1158                                        "IMPLEMENTATION_IMPLEMENTATION_INHERITANCE_CONSTRAINT", Level.SEVERE,
1159                                        new ObjectFactory().createImplementation( impl ),
1160                                        "implementationFinalImplementationConstraint", impl.getIdentifier(),
1161                                        moduleOfImpl.getName(), ancestorImplementation.getIdentifier(),
1162                                        moduleOfFinal.getName() );
1163 
1164                         }
1165                     }
1166 
1167                     for ( int j = 0, s1 = impl.getImplementations().getImplementation().size(); j < s1; j++ )
1168                     {
1169                         final Implementation pi = impl.getImplementations().getImplementation().get( j );
1170 
1171                         addDetail( validationContext.getReport(),
1172                                    "IMPLEMENTATION_IMPLEMENTATION_DECLARATION_CONSTRAINT", Level.SEVERE,
1173                                    new ObjectFactory().createImplementation( impl ),
1174                                    "implementationImplementationDeclarationConstraint", impl.getIdentifier(),
1175                                    moduleOfImpl.getName(), pi.getIdentifier() );
1176 
1177                     }
1178 
1179                     for ( int j = 0, s1 = impl.getImplementations().getReference().size(); j < s1; j++ )
1180                     {
1181                         final ImplementationReference r = impl.getImplementations().getReference().get( j );
1182 
1183                         final Set<InheritanceModel.Node<ImplementationReference>> effReferences =
1184                             imodel.getImplementationReferenceNodes( impl.getIdentifier(), r.getIdentifier() );
1185 
1186                         for ( final InheritanceModel.Node<ImplementationReference> effReference : effReferences )
1187                         {
1188                             final Set<InheritanceModel.Node<ImplementationReference>> overriddenReferences =
1189                                 modifiableSet( effReference.getOverriddenNodes() );
1190 
1191                             if ( r.isOverride() && overriddenReferences.isEmpty() )
1192                             {
1193                                 addDetail( validationContext.getReport(),
1194                                            "IMPLEMENTATION_IMPLEMENTATION_OVERRIDE_CONSTRAINT", Level.SEVERE,
1195                                            new ObjectFactory().createImplementation( impl ),
1196                                            "implementationImplementationOverrideConstraint", impl.getIdentifier(),
1197                                            moduleOfImpl.getName(), r.getIdentifier() );
1198 
1199                             }
1200 
1201                             if ( !( r.isOverride() || overriddenReferences.isEmpty() ) )
1202                             {
1203                                 for ( final InheritanceModel.Node<ImplementationReference> overriddenReference
1204                                       : overriddenReferences )
1205                                 {
1206                                     Implementation overriddenImplementation = overriddenReference.getImplementation();
1207                                     if ( overriddenReference.getClassDeclaration() != null )
1208                                     {
1209                                         overriddenImplementation = overriddenReference.getClassDeclaration();
1210                                     }
1211 
1212                                     final Module moduleOfReference =
1213                                         validationContext.getModuleOfImplementation(
1214                                         overriddenImplementation.getIdentifier() );
1215 
1216                                     addDetail( validationContext.getReport(),
1217                                                "IMPLEMENTATION_IMPLEMENTATION_REFERENCE_OVERRIDE_WARNING",
1218                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1219                                                "implementationImplementationOverrideWarning", impl.getIdentifier(),
1220                                                moduleOfImpl.getName(), r.getIdentifier(),
1221                                                overriddenImplementation.getIdentifier(),
1222                                                moduleOfReference.getName(),
1223                                                getNodePathString( overriddenReference ) );
1224 
1225                                 }
1226                             }
1227 
1228                             retainFinalNodes( overriddenReferences );
1229 
1230                             for ( final InheritanceModel.Node<ImplementationReference> overriddenReference
1231                                   : overriddenReferences )
1232                             {
1233                                 Implementation overriddenImplementation = overriddenReference.getImplementation();
1234                                 if ( overriddenReference.getClassDeclaration() != null )
1235                                 {
1236                                     overriddenImplementation = overriddenReference.getClassDeclaration();
1237                                 }
1238 
1239                                 final Module moduleOfReference =
1240                                     validationContext.getModuleOfImplementation(
1241                                     overriddenImplementation.getIdentifier() );
1242 
1243                                 addDetail( validationContext.getReport(),
1244                                            "IMPLEMENTATION_IMPLEMENTATION_REFERENCE_INHERITANCE_CONSTRAINT",
1245                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1246                                            "implementationFinalImplementatioReferenceConstraint", impl.getIdentifier(),
1247                                            moduleOfImpl.getName(), r.getIdentifier(),
1248                                            overriddenImplementation.getIdentifier(),
1249                                            moduleOfReference.getName(), getNodePathString( overriddenReference ) );
1250 
1251                             }
1252                         }
1253                     }
1254                 }
1255 
1256                 if ( impl.getMessages() != null )
1257                 {
1258                     for ( int j = 0, s1 = impl.getMessages().getMessage().size(); j < s1; j++ )
1259                     {
1260                         final Message m = impl.getMessages().getMessage().get( j );
1261 
1262                         if ( impl.getMessages().getReference( m.getName() ) != null )
1263                         {
1264                             addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGES_UNIQUENESS_CONSTRAINT",
1265                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1266                                        "implementationMessagesUniquenessConstraint", impl.getIdentifier(),
1267                                        moduleOfImpl.getName(), m.getName() );
1268 
1269                         }
1270 
1271                         if ( validationContext.isValidateJava() )
1272                         {
1273                             try
1274                             {
1275                                 m.getJavaConstantName();
1276                             }
1277                             catch ( final ModelObjectException e )
1278                             {
1279                                 final String message = getMessage( e );
1280 
1281                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1282                                 {
1283                                     validationContext.getModelContext().log( Level.FINE, message, e );
1284                                 }
1285 
1286                                 addDetail( validationContext.getReport(),
1287                                            "IMPLEMENTATION_MESSAGE_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
1288                                            new ObjectFactory().createImplementation( impl ),
1289                                            "implementationMessageJavaConstantNameConstraint", impl.getIdentifier(),
1290                                            moduleOfImpl.getName(), m.getName(),
1291                                            message != null && message.length() > 0 ? " " + message : "" );
1292 
1293                             }
1294 
1295                             try
1296                             {
1297                                 m.getJavaGetterMethodName();
1298                             }
1299                             catch ( final ModelObjectException e )
1300                             {
1301                                 final String message = getMessage( e );
1302 
1303                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1304                                 {
1305                                     validationContext.getModelContext().log( Level.FINE, message, e );
1306                                 }
1307 
1308                                 addDetail( validationContext.getReport(),
1309                                            "IMPLEMENTATION_MESSAGE_JAVA_GETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
1310                                            new ObjectFactory().createImplementation( impl ),
1311                                            "implementationMessageJavaGetterMethodNameConstraint", impl.getIdentifier(),
1312                                            moduleOfImpl.getName(), m.getName(),
1313                                            message != null && message.length() > 0 ? " " + message : "" );
1314 
1315                             }
1316 
1317                             try
1318                             {
1319                                 m.getJavaSetterMethodName();
1320                             }
1321                             catch ( final ModelObjectException e )
1322                             {
1323                                 final String message = getMessage( e );
1324 
1325                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1326                                 {
1327                                     validationContext.getModelContext().log( Level.FINE, message, e );
1328                                 }
1329 
1330                                 addDetail( validationContext.getReport(),
1331                                            "IMPLEMENTATION_MESSAGE_JAVA_SETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
1332                                            new ObjectFactory().createImplementation( impl ),
1333                                            "implementationMessageJavaSetterMethodNameConstraint", impl.getIdentifier(),
1334                                            moduleOfImpl.getName(), m.getName(),
1335                                            message != null && message.length() > 0 ? " " + message : "" );
1336 
1337                             }
1338 
1339                             try
1340                             {
1341                                 m.getJavaVariableName();
1342                             }
1343                             catch ( final ModelObjectException e )
1344                             {
1345                                 final String message = getMessage( e );
1346 
1347                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1348                                 {
1349                                     validationContext.getModelContext().log( Level.FINE, message, e );
1350                                 }
1351 
1352                                 addDetail( validationContext.getReport(),
1353                                            "IMPLEMENTATION_MESSAGE_JAVA_VARIABLE_NAME_CONSTRAINT", Level.SEVERE,
1354                                            new ObjectFactory().createImplementation( impl ),
1355                                            "implementationMessageJavaVariableNameConstraint", impl.getIdentifier(),
1356                                            moduleOfImpl.getName(), m.getName(),
1357                                            message != null && message.length() > 0 ? " " + message : "" );
1358 
1359                             }
1360                         }
1361 
1362                         if ( m.getTemplate() != null )
1363                         {
1364                             for ( int k = 0, s2 = m.getTemplate().getText().size(); k < s2; k++ )
1365                             {
1366                                 final Text t = m.getTemplate().getText().get( k );
1367 
1368                                 try
1369                                 {
1370                                     t.getMimeType();
1371                                 }
1372                                 catch ( final ModelObjectException e )
1373                                 {
1374                                     final String message = getMessage( e );
1375 
1376                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1377                                     {
1378                                         validationContext.getModelContext().log( Level.FINE, message, e );
1379                                     }
1380 
1381                                     addDetail( validationContext.getReport(),
1382                                                "IMPLEMENTATION_MESSAGE_TEMPLATE_MIME_TYPE_CONSTRAINT", Level.SEVERE,
1383                                                new ObjectFactory().createImplementation( impl ),
1384                                                "implementationMessageTemplateMimeTypeConstraint", impl.getIdentifier(),
1385                                                moduleOfImpl.getName(), m.getName(), t.getLanguage(),
1386                                                message != null && message.length() > 0 ? " " + message : "" );
1387 
1388                                 }
1389 
1390                                 if ( validationContext.isValidateJava() )
1391                                 {
1392                                     try
1393                                     {
1394                                         new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
1395                                     }
1396                                     catch ( final IllegalArgumentException e )
1397                                     {
1398                                         final String message = getMessage( e );
1399 
1400                                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1401                                         {
1402                                             validationContext.getModelContext().log( Level.FINE, message, e );
1403                                         }
1404 
1405                                         addDetail( validationContext.getReport(),
1406                                                    "IMPLEMENTATION_MESSAGE_TEMPLATE_CONSTRAINT", Level.SEVERE,
1407                                                    new ObjectFactory().createImplementation( impl ),
1408                                                    "implementationMessageTemplateConstraint", impl.getIdentifier(),
1409                                                    moduleOfImpl.getName(), m.getName(), t.getLanguage(),
1410                                                    message != null && message.length() > 0 ? " " + message : "" );
1411 
1412                                     }
1413                                 }
1414                             }
1415                         }
1416 
1417                         final Set<InheritanceModel.Node<Message>> effMessages =
1418                             imodel.getMessageNodes( impl.getIdentifier(), m.getName() );
1419 
1420                         for ( final InheritanceModel.Node<Message> effMessage : effMessages )
1421                         {
1422                             final Set<InheritanceModel.Node<Message>> overriddenMessages =
1423                                 modifiableSet( effMessage.getOverriddenNodes() );
1424 
1425                             if ( m.isOverride() && overriddenMessages.isEmpty() )
1426                             {
1427                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_CONSTRAINT",
1428                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1429                                            "implementationMessageOverrideConstraint", impl.getIdentifier(),
1430                                            moduleOfImpl.getName(), m.getName() );
1431 
1432                             }
1433 
1434                             if ( !( m.isOverride() || overriddenMessages.isEmpty() ) )
1435                             {
1436                                 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1437                                 {
1438                                     Implementation overriddenImplementation = overriddenMessage.getImplementation();
1439                                     if ( overriddenMessage.getClassDeclaration() != null )
1440                                     {
1441                                         overriddenImplementation = overriddenMessage.getClassDeclaration();
1442                                     }
1443 
1444                                     final Module moduleOfMessage =
1445                                         validationContext.getModuleOfImplementation(
1446                                         overriddenImplementation.getIdentifier() );
1447 
1448                                     addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_WARNING",
1449                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1450                                                "implementationMessageOverrideWarning", impl.getIdentifier(),
1451                                                moduleOfImpl.getName(), m.getName(),
1452                                                overriddenImplementation.getIdentifier(),
1453                                                moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1454 
1455                                 }
1456                             }
1457 
1458                             retainFinalNodes( overriddenMessages );
1459 
1460                             for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1461                             {
1462                                 Implementation overriddenImplementation = overriddenMessage.getImplementation();
1463                                 if ( overriddenMessage.getClassDeclaration() != null )
1464                                 {
1465                                     overriddenImplementation = overriddenMessage.getClassDeclaration();
1466                                 }
1467 
1468                                 final Module moduleOfMessage = validationContext.getModuleOfImplementation(
1469                                     overriddenImplementation.getIdentifier() );
1470 
1471                                 addDetail( validationContext.getReport(),
1472                                            "IMPLEMENTATION_MESSAGE_INHERITANCE_CONSTRAINT",
1473                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1474                                            "implementationMessageFinalConstraint", impl.getIdentifier(),
1475                                            moduleOfImpl.getName(), m.getName(),
1476                                            overriddenImplementation.getIdentifier(),
1477                                            moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1478 
1479                             }
1480                         }
1481 
1482                         if ( m.getArguments() != null )
1483                         {
1484                             final Map<JavaIdentifier, Argument> javaVariableNames =
1485                                 new HashMap<JavaIdentifier, Argument>( m.getArguments().getArgument().size() );
1486 
1487                             for ( int k = 0, s2 = m.getArguments().getArgument().size(); k < s2; k++ )
1488                             {
1489                                 final Argument a = m.getArguments().getArgument().get( k );
1490 
1491                                 if ( validationContext.isValidateJava() )
1492                                 {
1493                                     try
1494                                     {
1495                                         a.getJavaTypeName();
1496                                     }
1497                                     catch ( final ModelObjectException e )
1498                                     {
1499                                         final String message = getMessage( e );
1500 
1501                                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1502                                         {
1503                                             validationContext.getModelContext().log( Level.FINE, message, e );
1504                                         }
1505 
1506                                         addDetail( validationContext.getReport(),
1507                                                    "IMPLEMENTATION_MESSAGE_ARGUMENT_JAVA_TYPE_NAME_CONSTRAINT",
1508                                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1509                                                    "implementationMessageArgumentJavaTypeNameConstraint",
1510                                                    impl.getIdentifier(), moduleOfImpl.getName(), m.getName(),
1511                                                    a.getName(),
1512                                                    message != null && message.length() > 0 ? " " + message : "" );
1513 
1514                                     }
1515 
1516                                     try
1517                                     {
1518                                         final JavaIdentifier javaIdentifier = a.getJavaVariableName();
1519 
1520                                         if ( javaVariableNames.containsKey( javaIdentifier ) )
1521                                         {
1522                                             addDetail( validationContext.getReport(),
1523                                                        "IMPLEMENTATION_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
1524                                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1525                                                        "implementationMessageArgumentJavaVariableNameUniquenessConstraint",
1526                                                        impl.getIdentifier(), moduleOfImpl.getName(), m.getName(),
1527                                                        a.getName(), javaIdentifier,
1528                                                        javaVariableNames.get( javaIdentifier ).getName() );
1529 
1530                                         }
1531                                         else
1532                                         {
1533                                             javaVariableNames.put( javaIdentifier, a );
1534                                         }
1535                                     }
1536                                     catch ( final ModelObjectException e )
1537                                     {
1538                                         final String message = getMessage( e );
1539 
1540                                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1541                                         {
1542                                             validationContext.getModelContext().log( Level.FINE, message, e );
1543                                         }
1544 
1545                                         addDetail( validationContext.getReport(),
1546                                                    "IMPLEMENTATION_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_CONSTRAINT",
1547                                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1548                                                    "implementationMessageArgumentJavaVariableNameConstraint",
1549                                                    impl.getIdentifier(), moduleOfImpl.getName(), m.getName(),
1550                                                    a.getIndex(),
1551                                                    message != null && message.length() > 0 ? " " + message : "" );
1552 
1553                                     }
1554                                 }
1555                             }
1556                         }
1557                     }
1558 
1559                     for ( int j = 0, s1 = impl.getMessages().getReference().size(); j < s1; j++ )
1560                     {
1561                         final MessageReference r = impl.getMessages().getReference().get( j );
1562 
1563                         final Set<InheritanceModel.Node<Message>> effMessages =
1564                             imodel.getMessageNodes( impl.getIdentifier(), r.getName() );
1565 
1566                         for ( final InheritanceModel.Node<Message> effMessage : effMessages )
1567                         {
1568                             final Set<InheritanceModel.Node<Message>> overriddenMessages =
1569                                 modifiableSet( effMessage.getOverriddenNodes() );
1570 
1571                             if ( r.isOverride() && overriddenMessages.isEmpty() )
1572                             {
1573                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_CONSTRAINT",
1574                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1575                                            "implementationMessageOverrideConstraint", impl.getIdentifier(),
1576                                            moduleOfImpl.getName(), r.getName() );
1577 
1578                             }
1579 
1580                             if ( !( r.isOverride() || overriddenMessages.isEmpty() ) )
1581                             {
1582                                 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1583                                 {
1584                                     Implementation overriddenImplementation = overriddenMessage.getImplementation();
1585                                     if ( overriddenMessage.getClassDeclaration() != null )
1586                                     {
1587                                         overriddenImplementation = overriddenMessage.getClassDeclaration();
1588                                     }
1589 
1590                                     final Module moduleOfMessage =
1591                                         validationContext.getModuleOfImplementation(
1592                                         overriddenImplementation.getIdentifier() );
1593 
1594                                     addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_WARNING",
1595                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1596                                                "implementationMessageOverrideWarning", impl.getIdentifier(),
1597                                                moduleOfImpl.getName(), r.getName(),
1598                                                overriddenImplementation.getIdentifier(),
1599                                                moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1600 
1601                                 }
1602                             }
1603 
1604                             retainFinalNodes( overriddenMessages );
1605 
1606                             for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1607                             {
1608                                 Implementation overriddenImplementation = overriddenMessage.getImplementation();
1609                                 if ( overriddenMessage.getClassDeclaration() != null )
1610                                 {
1611                                     overriddenImplementation = overriddenMessage.getClassDeclaration();
1612                                 }
1613 
1614                                 final Module moduleOfMessage =
1615                                     validationContext.getModuleOfImplementation(
1616                                     overriddenImplementation.getIdentifier() );
1617 
1618                                 addDetail( validationContext.getReport(),
1619                                            "IMPLEMENTATION_MESSAGE_INHERITANCE_CONSTRAINT",
1620                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1621                                            "implementationMessageFinalConstraint", impl.getIdentifier(),
1622                                            moduleOfImpl.getName(), r.getName(),
1623                                            overriddenImplementation.getIdentifier(),
1624                                            moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1625 
1626                             }
1627                         }
1628                     }
1629                 }
1630 
1631                 if ( impl.getProperties() != null )
1632                 {
1633                     for ( int j = 0, s1 = impl.getProperties().getProperty().size(); j < s1; j++ )
1634                     {
1635                         final Property p = impl.getProperties().getProperty().get( j );
1636 
1637                         if ( impl.getProperties().getReference( p.getName() ) != null )
1638                         {
1639                             addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTIES_UNIQUENESS_CONSTRAINT",
1640                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1641                                        "implementationPropertiesUniquenessConstraint", impl.getIdentifier(),
1642                                        moduleOfImpl.getName(), p.getName() );
1643 
1644                         }
1645 
1646                         if ( p.getValue() != null && p.getAny() != null )
1647                         {
1648                             addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_VALUE_CONSTRAINT",
1649                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1650                                        "implementationPropertyValueConstraint", impl.getIdentifier(),
1651                                        moduleOfImpl.getName(), p.getName() );
1652 
1653                         }
1654 
1655                         if ( p.getAny() != null && p.getType() == null )
1656                         {
1657                             addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_TYPE_CONSTRAINT",
1658                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1659                                        "implementationPropertyTypeConstraint", impl.getIdentifier(),
1660                                        moduleOfImpl.getName(), p.getName() );
1661 
1662                         }
1663 
1664                         if ( validationContext.isValidateJava() )
1665                         {
1666                             try
1667                             {
1668                                 p.getJavaConstantName();
1669                             }
1670                             catch ( final ModelObjectException e )
1671                             {
1672                                 final String message = getMessage( e );
1673 
1674                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1675                                 {
1676                                     validationContext.getModelContext().log( Level.FINE, message, e );
1677                                 }
1678 
1679                                 addDetail( validationContext.getReport(),
1680                                            "IMPLEMENTATION_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT",
1681                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1682                                            "implementationPropertyJavaConstantNameConstraint", impl.getIdentifier(),
1683                                            moduleOfImpl.getName(), p.getName(),
1684                                            message != null && message.length() > 0 ? " " + message : "" );
1685 
1686                             }
1687 
1688                             try
1689                             {
1690                                 p.getJavaGetterMethodName();
1691                             }
1692                             catch ( final ModelObjectException e )
1693                             {
1694                                 final String message = getMessage( e );
1695 
1696                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1697                                 {
1698                                     validationContext.getModelContext().log( Level.FINE, message, e );
1699                                 }
1700 
1701                                 addDetail( validationContext.getReport(),
1702                                            "IMPLEMENTATION_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
1703                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1704                                            "implementationPropertyJavaGetterMethodNameConstraint", impl.getIdentifier(),
1705                                            moduleOfImpl.getName(), p.getName(),
1706                                            message != null && message.length() > 0 ? " " + message : "" );
1707 
1708                             }
1709 
1710                             try
1711                             {
1712                                 p.getJavaSetterMethodName();
1713                             }
1714                             catch ( final ModelObjectException e )
1715                             {
1716                                 final String message = getMessage( e );
1717 
1718                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1719                                 {
1720                                     validationContext.getModelContext().log( Level.FINE, message, e );
1721                                 }
1722 
1723                                 addDetail( validationContext.getReport(),
1724                                            "IMPLEMENTATION_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
1725                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1726                                            "implementationPropertyJavaSetterMethodNameConstraint", impl.getIdentifier(),
1727                                            moduleOfImpl.getName(), p.getName(),
1728                                            message != null && message.length() > 0 ? " " + message : "" );
1729 
1730                             }
1731 
1732                             try
1733                             {
1734                                 p.getJavaTypeName();
1735                             }
1736                             catch ( final ModelObjectException e )
1737                             {
1738                                 final String message = getMessage( e );
1739 
1740                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1741                                 {
1742                                     validationContext.getModelContext().log( Level.FINE, message, e );
1743                                 }
1744 
1745                                 addDetail( validationContext.getReport(),
1746                                            "IMPLEMENTATION_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
1747                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1748                                            "implementationPropertyJavaTypeNameConstraint", impl.getIdentifier(),
1749                                            moduleOfImpl.getName(), p.getName(),
1750                                            message != null && message.length() > 0 ? " " + message : "" );
1751 
1752                             }
1753 
1754                             try
1755                             {
1756                                 p.getJavaVariableName();
1757                             }
1758                             catch ( final ModelObjectException e )
1759                             {
1760                                 final String message = getMessage( e );
1761 
1762                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1763                                 {
1764                                     validationContext.getModelContext().log( Level.FINE, message, e );
1765                                 }
1766 
1767                                 addDetail( validationContext.getReport(),
1768                                            "IMPLEMENTATION_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
1769                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1770                                            "implementationPropertyJavaVariableNameConstraint", impl.getIdentifier(),
1771                                            moduleOfImpl.getName(), p.getName(),
1772                                            message != null && message.length() > 0 ? " " + message : "" );
1773 
1774                             }
1775 
1776                             try
1777                             {
1778                                 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
1779                             }
1780                             catch ( final ModelObjectException e )
1781                             {
1782                                 final String message = getMessage( e );
1783 
1784                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1785                                 {
1786                                     validationContext.getModelContext().log( Level.FINE, message, e );
1787                                 }
1788 
1789                                 addDetail( validationContext.getReport(),
1790                                            "IMPLEMENTATION_PROPERTY_JAVA_VALUE_CONSTRAINT",
1791                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1792                                            "implementationPropertyJavaValueConstraint", impl.getIdentifier(),
1793                                            moduleOfImpl.getName(), p.getName(),
1794                                            message != null && message.length() > 0 ? " " + message : "" );
1795 
1796                             }
1797                         }
1798 
1799                         final Set<InheritanceModel.Node<Property>> effProperties =
1800                             imodel.getPropertyNodes( impl.getIdentifier(), p.getName() );
1801 
1802                         for ( final InheritanceModel.Node<Property> effProperty : effProperties )
1803                         {
1804                             final Set<InheritanceModel.Node<Property>> overriddenProperties =
1805                                 modifiableSet( effProperty.getOverriddenNodes() );
1806 
1807                             if ( p.isOverride() && overriddenProperties.isEmpty() )
1808                             {
1809                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_OVERRIDE_CONSTRAINT",
1810                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1811                                            "implementationPropertyOverrideConstraint", impl.getIdentifier(),
1812                                            moduleOfImpl.getName(), p.getName() );
1813 
1814                             }
1815 
1816                             if ( !( p.isOverride() || overriddenProperties.isEmpty() ) )
1817                             {
1818                                 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1819                                 {
1820                                     if ( overriddenProperty.getSpecification() != null )
1821                                     {
1822                                         final Module moduleOfProperty =
1823                                             validationContext.getModuleOfSpecification(
1824                                             overriddenProperty.getSpecification().getIdentifier() );
1825 
1826                                         addDetail( validationContext.getReport(),
1827                                                    "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
1828                                                    new ObjectFactory().createImplementation( impl ),
1829                                                    "implementationSpecificationPropertyOverrideWarning",
1830                                                    impl.getIdentifier(), moduleOfImpl.getName(), p.getName(),
1831                                                    overriddenProperty.getSpecification().getIdentifier(),
1832                                                    moduleOfProperty.getName(),
1833                                                    getNodePathString( overriddenProperty ) );
1834 
1835                                     }
1836                                     else
1837                                     {
1838                                         Implementation overriddenImplementation =
1839                                             overriddenProperty.getImplementation();
1840 
1841                                         if ( overriddenProperty.getClassDeclaration() != null )
1842                                         {
1843                                             overriddenImplementation = overriddenProperty.getClassDeclaration();
1844                                         }
1845 
1846                                         final Module moduleOfProperty =
1847                                             validationContext.getModuleOfImplementation(
1848                                             overriddenImplementation.getIdentifier() );
1849 
1850                                         addDetail( validationContext.getReport(),
1851                                                    "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
1852                                                    new ObjectFactory().createImplementation( impl ),
1853                                                    "implementationPropertyOverrideWarning", impl.getIdentifier(),
1854                                                    moduleOfImpl.getName(), p.getName(),
1855                                                    overriddenImplementation.getIdentifier(),
1856                                                    moduleOfProperty.getName(),
1857                                                    getNodePathString( overriddenProperty ) );
1858 
1859                                     }
1860                                 }
1861                             }
1862 
1863                             retainFinalNodes( overriddenProperties );
1864 
1865                             for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1866                             {
1867                                 Implementation overriddenImplementation = overriddenProperty.getImplementation();
1868                                 if ( overriddenProperty.getClassDeclaration() != null )
1869                                 {
1870                                     overriddenImplementation = overriddenProperty.getClassDeclaration();
1871                                 }
1872 
1873                                 final Module moduleOfProperty =
1874                                     validationContext.getModuleOfImplementation(
1875                                     overriddenImplementation.getIdentifier() );
1876 
1877                                 addDetail( validationContext.getReport(),
1878                                            "IMPLEMENTATION_PROPERTY_INHERITANCE_CONSTRAINT",
1879                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1880                                            "implementationPropertyFinalConstraint", impl.getIdentifier(),
1881                                            moduleOfImpl.getName(), p.getName(),
1882                                            overriddenImplementation.getIdentifier(),
1883                                            moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
1884 
1885                             }
1886                         }
1887                     }
1888 
1889                     for ( int j = 0, s1 = impl.getProperties().getReference().size(); j < s1; j++ )
1890                     {
1891                         final PropertyReference r = impl.getProperties().getReference().get( j );
1892 
1893                         final Set<InheritanceModel.Node<Property>> effProperties =
1894                             imodel.getPropertyNodes( impl.getIdentifier(), r.getName() );
1895 
1896                         for ( final InheritanceModel.Node<Property> effProperty : effProperties )
1897                         {
1898                             final Set<InheritanceModel.Node<Property>> overriddenProperties =
1899                                 modifiableSet( effProperty.getOverriddenNodes() );
1900 
1901                             if ( r.isOverride() && overriddenProperties.isEmpty() )
1902                             {
1903                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_OVERRIDE_CONSTRAINT",
1904                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1905                                            "implementationPropertyOverrideConstraint", impl.getIdentifier(),
1906                                            moduleOfImpl.getName(), r.getName() );
1907 
1908                             }
1909 
1910                             if ( !( r.isOverride() || overriddenProperties.isEmpty() ) )
1911                             {
1912                                 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1913                                 {
1914                                     Implementation overriddenImplementation = overriddenProperty.getImplementation();
1915                                     if ( overriddenProperty.getClassDeclaration() != null )
1916                                     {
1917                                         overriddenImplementation = overriddenProperty.getClassDeclaration();
1918                                     }
1919 
1920                                     final Module moduleOfProperty =
1921                                         validationContext.getModuleOfImplementation(
1922                                         overriddenImplementation.getIdentifier() );
1923 
1924                                     addDetail( validationContext.getReport(),
1925                                                "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
1926                                                new ObjectFactory().createImplementation( impl ),
1927                                                "implementationPropertyOverrideWarning", impl.getIdentifier(),
1928                                                moduleOfImpl.getName(), r.getName(),
1929                                                overriddenImplementation.getIdentifier(),
1930                                                moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
1931 
1932                                 }
1933                             }
1934 
1935                             retainFinalNodes( overriddenProperties );
1936 
1937                             for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1938                             {
1939                                 Implementation overriddenImplementation = overriddenProperty.getImplementation();
1940                                 if ( overriddenProperty.getClassDeclaration() != null )
1941                                 {
1942                                     overriddenImplementation = overriddenProperty.getClassDeclaration();
1943                                 }
1944 
1945                                 final Module moduleOfProperty =
1946                                     validationContext.getModuleOfImplementation(
1947                                     overriddenImplementation.getIdentifier() );
1948 
1949                                 addDetail( validationContext.getReport(),
1950                                            "IMPLEMENTATION_PROPERTY_INHERITANCE_CONSTRAINT",
1951                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1952                                            "implementationPropertyFinalConstraint", impl.getIdentifier(),
1953                                            moduleOfImpl.getName(), r.getName(),
1954                                            overriddenImplementation.getIdentifier(),
1955                                            moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
1956 
1957                             }
1958                         }
1959                     }
1960                 }
1961 
1962                 if ( impl.getSpecifications() != null )
1963                 {
1964                     for ( int j = 0, s1 = impl.getSpecifications().getSpecification().size(); j < s1; j++ )
1965                     {
1966                         final Specification s = impl.getSpecifications().getSpecification().get( j );
1967 
1968                         addDetail( validationContext.getReport(), "IMPLEMENTATION_SPECIFICATION_DECLARATION_CONSTRAINT",
1969                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1970                                    "implementationSpecificationDeclarationConstraint", impl.getIdentifier(),
1971                                    moduleOfImpl.getName(), s.getIdentifier() );
1972 
1973                     }
1974 
1975                     for ( int j = 0, s1 = impl.getSpecifications().getReference().size(); j < s1; j++ )
1976                     {
1977                         final SpecificationReference r = impl.getSpecifications().getReference().get( j );
1978 
1979                         final Set<InheritanceModel.Node<SpecificationReference>> effReferences =
1980                             imodel.getSpecificationReferenceNodes( impl.getIdentifier(), r.getIdentifier() );
1981 
1982                         for ( final InheritanceModel.Node<SpecificationReference> effReference : effReferences )
1983                         {
1984                             final Set<InheritanceModel.Node<SpecificationReference>> overriddenReferences =
1985                                 modifiableSet( effReference.getOverriddenNodes() );
1986 
1987                             if ( r.isOverride() && overriddenReferences.isEmpty() )
1988                             {
1989                                 addDetail( validationContext.getReport(),
1990                                            "IMPLEMENTATION_SPECIFICATION_OVERRIDE_CONSTRAINT", Level.SEVERE,
1991                                            new ObjectFactory().createImplementation( impl ),
1992                                            "implementationSpecificationOverrideConstraint", impl.getIdentifier(),
1993                                            moduleOfImpl.getName(), r.getIdentifier() );
1994 
1995                             }
1996 
1997                             if ( !( r.isOverride() || overriddenReferences.isEmpty() ) )
1998                             {
1999                                 for ( final InheritanceModel.Node<SpecificationReference> overriddenReference
2000                                       : overriddenReferences )
2001                                 {
2002                                     Implementation overriddenImplementation = overriddenReference.getImplementation();
2003                                     if ( overriddenReference.getClassDeclaration() != null )
2004                                     {
2005                                         overriddenImplementation = overriddenReference.getClassDeclaration();
2006                                     }
2007 
2008                                     final Module moduleOfReference =
2009                                         validationContext.getModuleOfImplementation(
2010                                         overriddenImplementation.getIdentifier() );
2011 
2012                                     addDetail( validationContext.getReport(),
2013                                                "IMPLEMENTATION_SPECIFICATION_REFERENCE_OVERRIDE_WARNING",
2014                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
2015                                                "implementationSpecificationOverrideWarning", impl.getIdentifier(),
2016                                                moduleOfImpl.getName(), r.getIdentifier(),
2017                                                overriddenImplementation.getIdentifier(),
2018                                                moduleOfReference.getName(), getNodePathString( overriddenReference ) );
2019 
2020                                 }
2021                             }
2022 
2023                             retainFinalNodes( overriddenReferences );
2024 
2025                             for ( final InheritanceModel.Node<SpecificationReference> overriddenReference
2026                                   : overriddenReferences )
2027                             {
2028                                 Implementation overriddenImplementation = overriddenReference.getImplementation();
2029                                 if ( overriddenReference.getClassDeclaration() != null )
2030                                 {
2031                                     overriddenImplementation = overriddenReference.getClassDeclaration();
2032                                 }
2033 
2034                                 final Module moduleOfReference =
2035                                     validationContext.getModuleOfImplementation(
2036                                     overriddenImplementation.getIdentifier() );
2037 
2038                                 addDetail( validationContext.getReport(),
2039                                            "IMPLEMENTATION_SPECIFICATION_INHERITANCE_CONSTRAINT", Level.SEVERE,
2040                                            new ObjectFactory().createImplementation( impl ),
2041                                            "implementationSpecificationFinalConstraint", impl.getIdentifier(),
2042                                            moduleOfImpl.getName(), r.getIdentifier(),
2043                                            overriddenImplementation.getIdentifier(),
2044                                            moduleOfReference.getName(), getNodePathString( overriddenReference ) );
2045 
2046                             }
2047                         }
2048                     }
2049                 }
2050 
2051                 if ( !impl.getAny().isEmpty() )
2052                 {
2053                     for ( int j = 0, s1 = impl.getAny().size(); j < s1; j++ )
2054                     {
2055                         final Object any = impl.getAny().get( j );
2056 
2057                         if ( any instanceof JAXBElement<?> )
2058                         {
2059                             final JAXBElement<?> jaxbElement = (JAXBElement<?>) any;
2060                             boolean overrideNode = false;
2061 
2062                             if ( jaxbElement.getValue() instanceof Inheritable )
2063                             {
2064                                 overrideNode = ( (Inheritable) jaxbElement.getValue() ).isOverride();
2065                             }
2066 
2067                             final Set<InheritanceModel.Node<JAXBElement<?>>> effElements =
2068                                 imodel.getJaxbElementNodes( impl.getIdentifier(), jaxbElement.getName() );
2069 
2070                             for ( final InheritanceModel.Node<JAXBElement<?>> effElement : effElements )
2071                             {
2072                                 final Set<InheritanceModel.Node<JAXBElement<?>>> overriddenElements =
2073                                     modifiableSet( effElement.getOverriddenNodes() );
2074 
2075                                 if ( overrideNode && overriddenElements.isEmpty() )
2076                                 {
2077                                     addDetail( validationContext.getReport(),
2078                                                "IMPLEMENTATION_JAXB_ELEMENT_OVERRIDE_CONSTRAINT",
2079                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2080                                                "implementationJaxbElementOverrideConstraint", impl.getIdentifier(),
2081                                                moduleOfImpl.getName(), jaxbElement.getName().toString() );
2082 
2083                                 }
2084 
2085                                 if ( !( overrideNode || overriddenElements.isEmpty() ) )
2086                                 {
2087                                     for ( final InheritanceModel.Node<JAXBElement<?>> overriddenElement
2088                                           : overriddenElements )
2089                                     {
2090                                         Implementation overriddenImplementation = overriddenElement.getImplementation();
2091                                         if ( overriddenElement.getClassDeclaration() != null )
2092                                         {
2093                                             overriddenImplementation = overriddenElement.getClassDeclaration();
2094                                         }
2095 
2096                                         final Module moduleOfElement =
2097                                             validationContext.getModuleOfImplementation(
2098                                             overriddenElement.getImplementation().getIdentifier() );
2099 
2100                                         addDetail( validationContext.getReport(),
2101                                                    "IMPLEMENTATION_JAXB_ELEMENT_OVERRIDE_WARNING",
2102                                                    Level.WARNING, new ObjectFactory().createImplementation( impl ),
2103                                                    "implementationJaxbElementOverrideWarning", impl.getIdentifier(),
2104                                                    moduleOfImpl.getName(), jaxbElement.getName().toString(),
2105                                                    overriddenImplementation.getIdentifier(),
2106                                                    moduleOfElement.getName(), getNodePathString( overriddenElement ) );
2107 
2108                                     }
2109                                 }
2110 
2111                                 retainFinalNodes( overriddenElements );
2112 
2113                                 for ( final InheritanceModel.Node<JAXBElement<?>> overriddenElement : overriddenElements )
2114                                 {
2115                                     Implementation overriddenImplementation = overriddenElement.getImplementation();
2116                                     if ( overriddenElement.getClassDeclaration() != null )
2117                                     {
2118                                         overriddenImplementation = overriddenElement.getClassDeclaration();
2119                                     }
2120 
2121                                     final Module moduleOfElement =
2122                                         validationContext.getModuleOfImplementation(
2123                                         overriddenImplementation.getIdentifier() );
2124 
2125                                     addDetail( validationContext.getReport(),
2126                                                "IMPLEMENTATION_JAXB_ELEMENT_INHERITANCE_CONSTRAINT",
2127                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2128                                                "implementationJaxbElementFinalConstraint", impl.getIdentifier(),
2129                                                moduleOfImpl.getName(), jaxbElement.getName().toString(),
2130                                                overriddenImplementation.getIdentifier(),
2131                                                moduleOfElement.getName(), getNodePathString( overriddenElement ) );
2132 
2133                                 }
2134                             }
2135                         }
2136                     }
2137                 }
2138 
2139                 final Set<String> dependencyNames = imodel.getDependencyNames( impl.getIdentifier() );
2140 
2141                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaConstantNames =
2142                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2143 
2144                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaGetterMethodNames =
2145                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2146 
2147                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaSetterMethodNames =
2148                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2149 
2150                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaVariableNames =
2151                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2152 
2153                 for ( String dependencyName : dependencyNames )
2154                 {
2155                     final Set<InheritanceModel.Node<Dependency>> dependencyNodes =
2156                         imodel.getDependencyNodes( impl.getIdentifier(), dependencyName );
2157 
2158                     if ( dependencyNodes.size() > 1 )
2159                     {
2160                         addDetail( validationContext.getReport(),
2161                                    "IMPLEMENTATION_DEPENDENCY_MULTIPLE_INHERITANCE_CONSTRAINT",
2162                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2163                                    "implementationMultipleInheritanceDependencyConstraint", impl.getIdentifier(),
2164                                    moduleOfImpl.getName(), dependencyName, getNodeListPathString( dependencyNodes ) );
2165 
2166                     }
2167 
2168                     if ( validationContext.isValidateJava() )
2169                     {
2170                         for ( final InheritanceModel.Node<Dependency> node : dependencyNodes )
2171                         {
2172                             try
2173                             {
2174                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaConstantName();
2175                                 final InheritanceModel.Node<Dependency> existingNode =
2176                                     dependencyJavaConstantNames.get( javaIdentifier );
2177 
2178                                 if ( existingNode != null )
2179                                 {
2180                                     addDetail( validationContext.getReport(),
2181                                                "IMPLEMENTATION_DEPENDENCY_JAVA_CONSTANT_NAME_UNIQUENESS_CONSTRAINT",
2182                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2183                                                "implementationDependencyJavaConstantNameUniquenessConstraint",
2184                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2185                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2186                                                getNodePathString( existingNode ), javaIdentifier );
2187 
2188                                 }
2189                                 else
2190                                 {
2191                                     dependencyJavaConstantNames.put( javaIdentifier, node );
2192                                 }
2193                             }
2194                             catch ( final ModelObjectException e )
2195                             {
2196                                 // Validated above.
2197                             }
2198 
2199                             try
2200                             {
2201                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaGetterMethodName();
2202                                 final InheritanceModel.Node<Dependency> existingNode =
2203                                     dependencyJavaGetterMethodNames.get( javaIdentifier );
2204 
2205                                 if ( existingNode != null )
2206                                 {
2207                                     addDetail( validationContext.getReport(),
2208                                                "IMPLEMENTATION_DEPENDENCY_JAVA_GETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2209                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2210                                                "implementationDependencyJavaGetterMethodNameUniquenessConstraint",
2211                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2212                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2213                                                getNodePathString( existingNode ), javaIdentifier );
2214 
2215                                 }
2216                                 else
2217                                 {
2218                                     dependencyJavaGetterMethodNames.put( javaIdentifier, node );
2219                                 }
2220                             }
2221                             catch ( final ModelObjectException e )
2222                             {
2223                                 // Validated above.
2224                             }
2225 
2226                             try
2227                             {
2228                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2229                                 final InheritanceModel.Node<Dependency> existingNode =
2230                                     dependencyJavaSetterMethodNames.get( javaIdentifier );
2231 
2232                                 if ( existingNode != null )
2233                                 {
2234                                     addDetail( validationContext.getReport(),
2235                                                "IMPLEMENTATION_DEPENDENCY_JAVA_SETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2236                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2237                                                "implementationDependencyJavaSetterMethodNameUniquenessConstraint",
2238                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2239                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2240                                                getNodePathString( existingNode ), javaIdentifier );
2241 
2242                                 }
2243                                 else
2244                                 {
2245                                     dependencyJavaSetterMethodNames.put( javaIdentifier, node );
2246                                 }
2247                             }
2248                             catch ( final ModelObjectException e )
2249                             {
2250                                 // Validated above.
2251                             }
2252 
2253                             try
2254                             {
2255                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2256                                 final InheritanceModel.Node<Dependency> existingNode =
2257                                     dependencyJavaVariableNames.get( javaIdentifier );
2258 
2259                                 if ( existingNode != null )
2260                                 {
2261                                     addDetail( validationContext.getReport(),
2262                                                "IMPLEMENTATION_DEPENDENCY_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
2263                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2264                                                "implementationDependencyJavaVariableNameUniquenessConstraint",
2265                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2266                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2267                                                getNodePathString( existingNode ), javaIdentifier );
2268 
2269                                 }
2270                                 else
2271                                 {
2272                                     dependencyJavaVariableNames.put( javaIdentifier, node );
2273                                 }
2274                             }
2275                             catch ( final ModelObjectException e )
2276                             {
2277                                 // Validated above.
2278                             }
2279                         }
2280                     }
2281                 }
2282 
2283                 final Set<String> messageNames = imodel.getMessageNames( impl.getIdentifier() );
2284 
2285                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaConstantNames =
2286                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2287 
2288                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaGetterMethodNames =
2289                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2290 
2291                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaSetterMethodNames =
2292                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2293 
2294                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaVariableNames =
2295                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2296 
2297                 for ( String messageName : messageNames )
2298                 {
2299                     final Set<InheritanceModel.Node<Message>> messageNodes =
2300                         imodel.getMessageNodes( impl.getIdentifier(), messageName );
2301 
2302                     if ( messageNodes.size() > 1 )
2303                     {
2304                         addDetail( validationContext.getReport(),
2305                                    "IMPLEMENTATION_MESSAGE_MULTIPLE_INHERITANCE_CONSTRAINT", Level.SEVERE,
2306                                    new ObjectFactory().createImplementation( impl ),
2307                                    "implementationMultipleInheritanceMessageConstraint", impl.getIdentifier(),
2308                                    moduleOfImpl.getName(), messageName, getNodeListPathString( messageNodes ) );
2309 
2310                     }
2311 
2312                     if ( validationContext.isValidateJava() )
2313                     {
2314                         for ( final InheritanceModel.Node<Message> node : messageNodes )
2315                         {
2316                             try
2317                             {
2318                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaConstantName();
2319                                 final InheritanceModel.Node<Message> existingNode =
2320                                     messageJavaConstantNames.get( javaIdentifier );
2321 
2322                                 if ( existingNode != null )
2323                                 {
2324                                     addDetail( validationContext.getReport(),
2325                                                "IMPLEMENTATION_MESSAGE_JAVA_CONSTANT_NAME_UNIQUENESS_CONSTRAINT",
2326                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2327                                                "implementationMessageJavaConstantNameUniquenessConstraint",
2328                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2329                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2330                                                getNodePathString( existingNode ), javaIdentifier );
2331 
2332                                 }
2333                                 else
2334                                 {
2335                                     messageJavaConstantNames.put( javaIdentifier, node );
2336                                 }
2337                             }
2338                             catch ( final ModelObjectException e )
2339                             {
2340                                 // Validated above.
2341                             }
2342 
2343                             try
2344                             {
2345                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaGetterMethodName();
2346                                 final InheritanceModel.Node<Message> existingNode =
2347                                     messageJavaGetterMethodNames.get( javaIdentifier );
2348 
2349                                 if ( existingNode != null )
2350                                 {
2351                                     addDetail( validationContext.getReport(),
2352                                                "IMPLEMENTATION_MESSAGE_JAVA_GETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2353                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2354                                                "implementationMessageJavaGetterMethodNameUniquenessConstraint",
2355                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2356                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2357                                                getNodePathString( existingNode ), javaIdentifier );
2358 
2359                                 }
2360                                 else
2361                                 {
2362                                     messageJavaGetterMethodNames.put( javaIdentifier, node );
2363                                 }
2364                             }
2365                             catch ( final ModelObjectException e )
2366                             {
2367                                 // Validated above.
2368                             }
2369 
2370                             try
2371                             {
2372                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2373                                 final InheritanceModel.Node<Message> existingNode =
2374                                     messageJavaSetterMethodNames.get( javaIdentifier );
2375 
2376                                 if ( existingNode != null )
2377                                 {
2378                                     addDetail( validationContext.getReport(),
2379                                                "IMPLEMENTATION_MESSAGE_JAVA_SETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2380                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2381                                                "implementationMessageJavaSetterMethodNameUniquenessConstraint",
2382                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2383                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2384                                                getNodePathString( existingNode ), javaIdentifier );
2385 
2386                                 }
2387                                 else
2388                                 {
2389                                     messageJavaSetterMethodNames.put( javaIdentifier, node );
2390                                 }
2391                             }
2392                             catch ( final ModelObjectException e )
2393                             {
2394                                 // Validated above.
2395                             }
2396 
2397                             try
2398                             {
2399                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2400                                 final InheritanceModel.Node<Message> existingNode =
2401                                     messageJavaVariableNames.get( javaIdentifier );
2402 
2403                                 if ( existingNode != null )
2404                                 {
2405                                     addDetail( validationContext.getReport(),
2406                                                "IMPLEMENTATION_MESSAGE_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
2407                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2408                                                "implementationMessageJavaVariableNameUniquenessConstraint",
2409                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2410                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2411                                                getNodePathString( existingNode ), javaIdentifier );
2412 
2413                                 }
2414                                 else
2415                                 {
2416                                     messageJavaVariableNames.put( javaIdentifier, node );
2417                                 }
2418                             }
2419                             catch ( final ModelObjectException e )
2420                             {
2421                                 // Validated above.
2422                             }
2423                         }
2424                     }
2425                 }
2426 
2427                 final Set<String> propertyNames = imodel.getPropertyNames( impl.getIdentifier() );
2428 
2429                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaConstantNames =
2430                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2431 
2432                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaGetterMethodNames =
2433                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2434 
2435                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaSetterMethodNames =
2436                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2437 
2438                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaVariableNames =
2439                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2440 
2441                 for ( String propertyName : propertyNames )
2442                 {
2443                     final Set<InheritanceModel.Node<Property>> propertyNodes =
2444                         imodel.getPropertyNodes( impl.getIdentifier(), propertyName );
2445 
2446                     if ( propertyNodes.size() > 1 )
2447                     {
2448                         addDetail( validationContext.getReport(),
2449                                    "IMPLEMENTATION_PROPERTY_MULTIPLE_INHERITANCE_CONSTRAINT", Level.SEVERE,
2450                                    new ObjectFactory().createImplementation( impl ),
2451                                    "implementationMultipleInheritancePropertyConstraint", impl.getIdentifier(),
2452                                    moduleOfImpl.getName(), propertyName, getNodeListPathString( propertyNodes ) );
2453 
2454                     }
2455 
2456                     if ( validationContext.isValidateJava() )
2457                     {
2458                         for ( final InheritanceModel.Node<Property> node : propertyNodes )
2459                         {
2460                             try
2461                             {
2462                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaConstantName();
2463                                 final InheritanceModel.Node<Property> existingNode =
2464                                     propertyJavaConstantNames.get( javaIdentifier );
2465 
2466                                 if ( existingNode != null )
2467                                 {
2468                                     addDetail( validationContext.getReport(),
2469                                                "IMPLEMENTATION_PROPERTY_JAVA_CONSTANT_NAME_UNIQUENESS_CONSTRAINT",
2470                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2471                                                "implementationPropertyJavaConstantNameUniquenessConstraint",
2472                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2473                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2474                                                getNodePathString( existingNode ), javaIdentifier );
2475 
2476                                 }
2477                                 else
2478                                 {
2479                                     propertyJavaConstantNames.put( javaIdentifier, node );
2480                                 }
2481                             }
2482                             catch ( final ModelObjectException e )
2483                             {
2484                                 // Validated above.
2485                             }
2486 
2487                             try
2488                             {
2489                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaGetterMethodName();
2490                                 final InheritanceModel.Node<Property> existingNode =
2491                                     propertyJavaGetterMethodNames.get( javaIdentifier );
2492 
2493                                 if ( existingNode != null )
2494                                 {
2495                                     addDetail( validationContext.getReport(),
2496                                                "IMPLEMENTATION_PROPERTY_JAVA_GETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2497                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2498                                                "implementationPropertyJavaGetterMethodNameUniquenessConstraint",
2499                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2500                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2501                                                getNodePathString( existingNode ), javaIdentifier );
2502 
2503                                 }
2504                                 else
2505                                 {
2506                                     propertyJavaGetterMethodNames.put( javaIdentifier, node );
2507                                 }
2508                             }
2509                             catch ( final ModelObjectException e )
2510                             {
2511                                 // Validated above.
2512                             }
2513 
2514                             try
2515                             {
2516                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2517                                 final InheritanceModel.Node<Property> existingNode =
2518                                     propertyJavaSetterMethodNames.get( javaIdentifier );
2519 
2520                                 if ( existingNode != null )
2521                                 {
2522                                     addDetail( validationContext.getReport(),
2523                                                "IMPLEMENTATION_PROPERTY_JAVA_SETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2524                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2525                                                "implementationPropertyJavaSetterMethodNameUniquenessConstraint",
2526                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2527                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2528                                                getNodePathString( existingNode ), javaIdentifier );
2529 
2530                                 }
2531                                 else
2532                                 {
2533                                     propertyJavaSetterMethodNames.put( javaIdentifier, node );
2534                                 }
2535                             }
2536                             catch ( final ModelObjectException e )
2537                             {
2538                                 // Validated above.
2539                             }
2540 
2541                             try
2542                             {
2543                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2544                                 final InheritanceModel.Node<Property> existingNode =
2545                                     propertyJavaVariableNames.get( javaIdentifier );
2546 
2547                                 if ( existingNode != null )
2548                                 {
2549                                     addDetail( validationContext.getReport(),
2550                                                "IMPLEMENTATION_PROPERTY_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
2551                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2552                                                "implementationPropertyJavaVariableNameUniquenessConstraint",
2553                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2554                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2555                                                getNodePathString( existingNode ), javaIdentifier );
2556 
2557                                 }
2558                                 else
2559                                 {
2560                                     propertyJavaVariableNames.put( javaIdentifier, node );
2561                                 }
2562                             }
2563                             catch ( final ModelObjectException e )
2564                             {
2565                                 // Validated above.
2566                             }
2567                         }
2568                     }
2569                 }
2570 
2571                 final Set<String> specificationReferenceIdentifiers =
2572                     imodel.getSpecificationReferenceIdentifiers( impl.getIdentifier() );
2573 
2574                 for ( String specificationRefereneIdentifier : specificationReferenceIdentifiers )
2575                 {
2576                     final Set<InheritanceModel.Node<SpecificationReference>> specificationReferenceNodes =
2577                         imodel.getSpecificationReferenceNodes( impl.getIdentifier(), specificationRefereneIdentifier );
2578 
2579                     if ( specificationReferenceNodes.size() > 1 )
2580                     {
2581                         addDetail( validationContext.getReport(),
2582                                    "IMPLEMENTATION_SPECIFICATION_MULTIPLE_INHERITANCE_CONSTRAINT",
2583                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2584                                    "implementationMultipleInheritanceSpecificationConstraint",
2585                                    impl.getIdentifier(), moduleOfImpl.getName(), specificationRefereneIdentifier,
2586                                    getNodeListPathString( specificationReferenceNodes ) );
2587 
2588                     }
2589                 }
2590 
2591                 final Set<QName> xmlElementNames = imodel.getXmlElementNames( impl.getIdentifier() );
2592 
2593                 for ( QName xmlElementName : xmlElementNames )
2594                 {
2595                     final Set<InheritanceModel.Node<Element>> xmlElementNodes =
2596                         imodel.getXmlElementNodes( impl.getIdentifier(), xmlElementName );
2597 
2598                     if ( xmlElementNodes.size() > 1 )
2599                     {
2600                         addDetail( validationContext.getReport(),
2601                                    "IMPLEMENTATION_XML_ELEMENT_MULTIPLE_INHERITANCE_CONSTRAINT",
2602                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2603                                    "implementationMultipleInheritanceXmlElementConstraint",
2604                                    impl.getIdentifier(), moduleOfImpl.getName(), xmlElementName.toString(),
2605                                    getNodeListPathString( xmlElementNodes ) );
2606 
2607                     }
2608                 }
2609 
2610                 final Set<QName> jaxbElementNames = imodel.getJaxbElementNames( impl.getIdentifier() );
2611 
2612                 for ( QName jaxbElementName : jaxbElementNames )
2613                 {
2614                     final Set<InheritanceModel.Node<JAXBElement<?>>> jaxbElementNodes =
2615                         imodel.getJaxbElementNodes( impl.getIdentifier(), jaxbElementName );
2616 
2617                     if ( jaxbElementNodes.size() > 1 )
2618                     {
2619                         addDetail( validationContext.getReport(),
2620                                    "IMPLEMENTATION_JAXB_ELEMENT_MULTIPLE_INHERITANCE_CONSTRAINT",
2621                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2622                                    "implementationMultipleInheritanceJaxbElementConstraint",
2623                                    impl.getIdentifier(), moduleOfImpl.getName(), jaxbElementName.toString(),
2624                                    getNodeListPathString( jaxbElementNodes ) );
2625 
2626                     }
2627                 }
2628 
2629                 final Set<String> implementationReferenceIdentifiers =
2630                     imodel.getImplementationReferenceIdentifiers( impl.getIdentifier() );
2631 
2632                 for ( String implementationReferenceIdentifier : implementationReferenceIdentifiers )
2633                 {
2634                     final Set<InheritanceModel.Node<ImplementationReference>> implementationReferenceNodes =
2635                         imodel.getImplementationReferenceNodes( impl.getIdentifier(),
2636                                                                 implementationReferenceIdentifier );
2637 
2638                     for ( final InheritanceModel.Node<ImplementationReference> node : implementationReferenceNodes )
2639                     {
2640                         final ImplementationReference r = node.getModelObject();
2641 
2642                         final Implementation referenced =
2643                             validationContext.getImplementation( r.getIdentifier() );
2644 
2645                         final Module moduleOfReferenced =
2646                             validationContext.getModuleOfImplementation( referenced.getIdentifier() );
2647 
2648                         if ( r.getVersion() != null && referenced != null )
2649                         {
2650                             if ( referenced.getVersion() == null )
2651                             {
2652                                 addDetail( validationContext.getReport(),
2653                                            "IMPLEMENTATION_IMPLEMENTATION_VERSIONING_CONSTRAINT", Level.SEVERE,
2654                                            new ObjectFactory().createImplementation( impl ),
2655                                            "implementationImplementationVersioningConstraint",
2656                                            impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
2657                                            moduleOfReferenced.getName() );
2658 
2659                             }
2660                             else
2661                             {
2662                                 try
2663                                 {
2664                                     if ( VersionParser.compare( r.getVersion(), referenced.getVersion() ) > 0 )
2665                                     {
2666                                         addDetail( validationContext.getReport(),
2667                                                    "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_CONSTRAINT",
2668                                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2669                                                    "implementationInheritanceCompatibilityConstraint",
2670                                                    impl.getIdentifier(), moduleOfImpl.getName(),
2671                                                    referenced.getIdentifier(), moduleOfReferenced.getName(),
2672                                                    r.getVersion(), referenced.getVersion() );
2673 
2674                                     }
2675                                 }
2676                                 catch ( final ParseException ex )
2677                                 {
2678                                     final String message = getMessage( ex );
2679 
2680                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2681                                     {
2682                                         validationContext.getModelContext().log( Level.FINE, message, ex );
2683                                     }
2684 
2685                                     addDetail(
2686                                         validationContext.getReport(),
2687                                         "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
2688                                         Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2689                                         "implementationInheritanceCompatibilityParseException",
2690                                         impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
2691                                         moduleOfReferenced.getName(), r.getVersion(),
2692                                         message != null && message.length() > 0 ? " " + message : "" );
2693 
2694                                 }
2695                                 catch ( final TokenMgrError ex )
2696                                 {
2697                                     final String message = getMessage( ex );
2698 
2699                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2700                                     {
2701                                         validationContext.getModelContext().log( Level.FINE, message, ex );
2702                                     }
2703 
2704                                     addDetail(
2705                                         validationContext.getReport(),
2706                                         "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
2707                                         Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2708                                         "implementationInheritanceCompatiblityVersioningTokenManagerError",
2709                                         impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
2710                                         moduleOfReferenced.getName(), r.getVersion(),
2711                                         message != null && message.length() > 0 ? " " + message : "" );
2712 
2713                                 }
2714                             }
2715                         }
2716                     }
2717                 }
2718 
2719                 assertImplementationSpecificationCompatibility( validationContext, impl );
2720             }
2721         }
2722     }
2723 
2724     private static void assertSpecificationsValid( final ValidationContext validationContext )
2725     {
2726         final Specifications specifications = validationContext.getAllSpecifications();
2727         final Map<String, Specification> specificationClassDeclarations = new HashMap<String, Specification>();
2728         final Map<String, Specification> specificationJavaClassDeclarations =
2729             new HashMap<String, Specification>();
2730 
2731         if ( specifications != null )
2732         {
2733             for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
2734             {
2735                 final Specification s = specifications.getSpecification().get( i );
2736                 final Implementations impls = validationContext.getImplementations( s.getIdentifier() );
2737                 final Module moduleOfS = validationContext.getModuleOfSpecification( s.getIdentifier() );
2738 
2739                 if ( validationContext.isValidateJava() )
2740                 {
2741                     try
2742                     {
2743                         s.getJavaTypeName();
2744                     }
2745                     catch ( final ModelObjectException e )
2746                     {
2747                         final String message = getMessage( e );
2748 
2749                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2750                         {
2751                             validationContext.getModelContext().log( Level.FINE, message, e );
2752                         }
2753 
2754                         addDetail( validationContext.getReport(),
2755                                    "SPECIFICATION_JAVA_TYPE_NAME_CONSTRAINT",
2756                                    Level.SEVERE, new ObjectFactory().createSpecification( s ),
2757                                    "specificationJavaTypeNameConstraint", s.getIdentifier(),
2758                                    moduleOfS.getName(), s.getClazz(),
2759                                    message != null && message.length() > 0 ? " " + message : "" );
2760 
2761                     }
2762                 }
2763 
2764                 if ( s.isClassDeclaration() )
2765                 {
2766                     if ( s.getClazz() == null )
2767                     {
2768                         addDetail( validationContext.getReport(), "SPECIFICATION_CLASS_CONSTRAINT", Level.SEVERE,
2769                                    new ObjectFactory().createSpecification( s ), "specificationClassConstraint",
2770                                    s.getIdentifier(), moduleOfS.getName() );
2771 
2772                     }
2773                     else
2774                     {
2775                         final Specification prev = specificationClassDeclarations.get( s.getClazz() );
2776 
2777                         if ( prev != null && !prev.getIdentifier().equals( s.getIdentifier() ) )
2778                         {
2779                             final Module moduleOfPrev =
2780                                 validationContext.getModuleOfSpecification( prev.getIdentifier() );
2781 
2782                             addDetail( validationContext.getReport(), "SPECIFICATION_CLASS_DECLARATION_CONSTRAINT",
2783                                        Level.SEVERE, new ObjectFactory().createSpecification( s ),
2784                                        "specificationClassDeclarationConstraint", s.getIdentifier(),
2785                                        moduleOfS.getName(), s.getClazz(), prev.getIdentifier(),
2786                                        moduleOfPrev.getName() );
2787 
2788                         }
2789                         else
2790                         {
2791                             specificationClassDeclarations.put( s.getClazz(), s );
2792                         }
2793 
2794                         if ( validationContext.isValidateJava() )
2795                         {
2796                             try
2797                             {
2798                                 final Specification java =
2799                                     specificationJavaClassDeclarations.get( s.getJavaTypeName().getClassName() );
2800 
2801                                 if ( java != null && !java.getIdentifier().equals( s.getIdentifier() ) )
2802                                 {
2803                                     final Module moduleOfJava =
2804                                         validationContext.getModuleOfSpecification( java.getIdentifier() );
2805 
2806                                     addDetail( validationContext.getReport(),
2807                                                "SPECIFICATION_JAVA_CLASS_DECLARATION_CONSTRAINT",
2808                                                Level.SEVERE, new ObjectFactory().createSpecification( s ),
2809                                                "specificationJavaClassDeclarationConstraint", s.getIdentifier(),
2810                                                moduleOfS.getName(), s.getJavaTypeName().getClassName(),
2811                                                java.getIdentifier(), moduleOfJava.getName() );
2812 
2813                                 }
2814                                 else
2815                                 {
2816                                     specificationJavaClassDeclarations.put( s.getJavaTypeName().getClassName(), s );
2817                                 }
2818                             }
2819                             catch ( final ModelObjectException e )
2820                             {
2821                                 // Already validated above.
2822                             }
2823                         }
2824                     }
2825                 }
2826 
2827                 if ( impls != null )
2828                 {
2829                     final Map<String, Implementations> map = new HashMap<String, Implementations>();
2830 
2831                     for ( int j = 0, s1 = impls.getImplementation().size(); j < s1; j++ )
2832                     {
2833                         final Implementation impl = impls.getImplementation().get( j );
2834                         Implementations implementations = map.get( impl.getName() );
2835 
2836                         if ( implementations == null )
2837                         {
2838                             implementations = new Implementations();
2839                             map.put( impl.getName(), implementations );
2840                         }
2841 
2842                         implementations.getImplementation().add( impl );
2843                     }
2844 
2845                     for ( Map.Entry<String, Implementations> e : map.entrySet() )
2846                     {
2847                         if ( e.getValue().getImplementation().size() > 1 )
2848                         {
2849                             for ( int j = 0, s1 = e.getValue().getImplementation().size(); j < s1; j++ )
2850                             {
2851                                 final Implementation impl = e.getValue().getImplementation().get( j );
2852                                 final Module moduleOfImpl =
2853                                     validationContext.getModuleOfImplementation( impl.getIdentifier() );
2854 
2855                                 addDetail( validationContext.getReport(),
2856                                            "SPECIFICATION_IMPLEMENTATION_NAME_UNIQUENESS_CONSTRAINT",
2857                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2858                                            "specificationImplementationNameConstraint", impl.getIdentifier(),
2859                                            moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName(),
2860                                            impl.getName() );
2861 
2862                             }
2863                         }
2864                     }
2865 
2866                     if ( s.getMultiplicity() == Multiplicity.ONE && impls.getImplementation().size() > 1 )
2867                     {
2868                         for ( int j = 0, s1 = impls.getImplementation().size(); j < s1; j++ )
2869                         {
2870                             final Implementation impl = impls.getImplementation().get( j );
2871                             final Module moduleOfImpl =
2872                                 validationContext.getModuleOfImplementation( impl.getIdentifier() );
2873 
2874                             addDetail( validationContext.getReport(),
2875                                        "SPECIFICATION_IMPLEMENTATION_MULTIPLICITY_CONSTRAINT", Level.SEVERE,
2876                                        new ObjectFactory().createImplementation( impl ),
2877                                        "specificationMultiplicityConstraint", impl.getIdentifier(),
2878                                        moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName(),
2879                                        s.getMultiplicity() );
2880 
2881                         }
2882                     }
2883                 }
2884 
2885                 if ( s.getProperties() != null )
2886                 {
2887                     for ( int j = 0, s1 = s.getProperties().getProperty().size(); j < s1; j++ )
2888                     {
2889                         final Property p = s.getProperties().getProperty().get( j );
2890 
2891                         if ( p.getValue() != null && p.getAny() != null )
2892                         {
2893                             addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_VALUE_CONSTRAINT",
2894                                        Level.SEVERE, new ObjectFactory().createSpecification( s ),
2895                                        "specificationPropertyValueConstraint", s.getIdentifier(),
2896                                        moduleOfS.getName(), p.getName() );
2897 
2898                         }
2899 
2900                         if ( p.getAny() != null && p.getType() == null )
2901                         {
2902                             addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_TYPE_CONSTRAINT",
2903                                        Level.SEVERE, new ObjectFactory().createSpecification( s ),
2904                                        "specificationPropertyTypeConstraint", s.getIdentifier(),
2905                                        moduleOfS.getName(), p.getName() );
2906 
2907                         }
2908 
2909                         if ( validationContext.isValidateJava() )
2910                         {
2911                             try
2912                             {
2913                                 p.getJavaConstantName();
2914                             }
2915                             catch ( final ModelObjectException e )
2916                             {
2917                                 final String message = getMessage( e );
2918 
2919                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2920                                 {
2921                                     validationContext.getModelContext().log( Level.FINE, message, e );
2922                                 }
2923 
2924                                 addDetail( validationContext.getReport(),
2925                                            "SPECIFICATION_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT",
2926                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2927                                            "specificationPropertyJavaConstantNameConstraint", s.getIdentifier(),
2928                                            moduleOfS.getName(), p.getName(),
2929                                            message != null && message.length() > 0 ? " " + message : "" );
2930 
2931                             }
2932 
2933                             try
2934                             {
2935                                 p.getJavaGetterMethodName();
2936                             }
2937                             catch ( final ModelObjectException e )
2938                             {
2939                                 final String message = getMessage( e );
2940 
2941                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2942                                 {
2943                                     validationContext.getModelContext().log( Level.FINE, message, e );
2944                                 }
2945 
2946                                 addDetail( validationContext.getReport(),
2947                                            "SPECIFICATION_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
2948                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2949                                            "specificationPropertyJavaGetterMethodNameConstraint", s.getIdentifier(),
2950                                            moduleOfS.getName(), p.getName(),
2951                                            message != null && message.length() > 0 ? " " + message : "" );
2952 
2953                             }
2954 
2955                             try
2956                             {
2957                                 p.getJavaSetterMethodName();
2958                             }
2959                             catch ( final ModelObjectException e )
2960                             {
2961                                 final String message = getMessage( e );
2962 
2963                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2964                                 {
2965                                     validationContext.getModelContext().log( Level.FINE, message, e );
2966                                 }
2967 
2968                                 addDetail( validationContext.getReport(),
2969                                            "SPECIFICATION_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
2970                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2971                                            "specificationPropertyJavaSetterMethodNameConstraint", s.getIdentifier(),
2972                                            moduleOfS.getName(), p.getName(),
2973                                            message != null && message.length() > 0 ? " " + message : "" );
2974 
2975                             }
2976 
2977                             try
2978                             {
2979                                 p.getJavaTypeName();
2980                             }
2981                             catch ( final ModelObjectException e )
2982                             {
2983                                 final String message = getMessage( e );
2984 
2985                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2986                                 {
2987                                     validationContext.getModelContext().log( Level.FINE, message, e );
2988                                 }
2989 
2990                                 addDetail( validationContext.getReport(),
2991                                            "SPECIFICATION_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
2992                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2993                                            "specificationPropertyJavaTypeNameConstraint", s.getIdentifier(),
2994                                            moduleOfS.getName(), p.getName(),
2995                                            message != null && message.length() > 0 ? " " + message : "" );
2996 
2997                             }
2998 
2999                             try
3000                             {
3001                                 p.getJavaVariableName();
3002                             }
3003                             catch ( final ModelObjectException e )
3004                             {
3005                                 final String message = getMessage( e );
3006 
3007                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3008                                 {
3009                                     validationContext.getModelContext().log( Level.FINE, message, e );
3010                                 }
3011 
3012                                 addDetail( validationContext.getReport(),
3013                                            "SPECIFICATION_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
3014                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
3015                                            "specificationPropertyJavaVariableNameConstraint", s.getIdentifier(),
3016                                            moduleOfS.getName(), p.getName(),
3017                                            message != null && message.length() > 0 ? " " + message : "" );
3018 
3019                             }
3020 
3021                             try
3022                             {
3023                                 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
3024                             }
3025                             catch ( final ModelObjectException e )
3026                             {
3027                                 final String message = getMessage( e );
3028 
3029                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3030                                 {
3031                                     validationContext.getModelContext().log( Level.FINE, message, e );
3032                                 }
3033 
3034                                 addDetail( validationContext.getReport(),
3035                                            "SPECIFICATION_PROPERTY_JAVA_VALUE_CONSTRAINT",
3036                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
3037                                            "specificationPropertyJavaValueConstraint", s.getIdentifier(),
3038                                            moduleOfS.getName(), p.getName(),
3039                                            message != null && message.length() > 0 ? " " + message : "" );
3040 
3041                             }
3042                         }
3043                     }
3044 
3045                     for ( int j = 0, s1 = s.getProperties().getReference().size(); j < s1; j++ )
3046                     {
3047                         final PropertyReference r = s.getProperties().getReference().get( j );
3048 
3049                         addDetail( validationContext.getReport(),
3050                                    "SPECIFICATION_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
3051                                    new ObjectFactory().createSpecification( s ),
3052                                    "specificationPropertyReferenceDeclarationConstraint", s.getIdentifier(),
3053                                    moduleOfS.getName(), r.getName() );
3054 
3055                     }
3056                 }
3057             }
3058         }
3059     }
3060 
3061     private static void assertDependencyValid( final ValidationContext validationContext,
3062                                                final Implementation implementation, final Dependency dependency )
3063     {
3064         final Specification s = validationContext.getSpecification( dependency.getIdentifier() );
3065         final Implementations available = validationContext.getImplementations( dependency.getIdentifier() );
3066         final Module moduleOfImpl =
3067             validationContext.getModuleOfImplementation( implementation.getIdentifier() );
3068 
3069         if ( !dependency.isOptional()
3070              && ( available == null || available.getImplementation().isEmpty()
3071                   || ( dependency.getImplementationName() != null
3072                        && available.getImplementationByName( dependency.getImplementationName() ) == null ) ) )
3073         {
3074             addDetail( validationContext.getReport(), "IMPLEMENTATION_MANDATORY_DEPENDENCY_CONSTRAINT", Level.SEVERE,
3075                        new ObjectFactory().createImplementation( implementation ),
3076                        "implementationMandatoryDependencyConstraint", implementation.getIdentifier(),
3077                        moduleOfImpl.getName(), dependency.getName() );
3078 
3079         }
3080 
3081         if ( s != null )
3082         {
3083             final Module moduleOfS = validationContext.getModuleOfSpecification( s.getIdentifier() );
3084 
3085             if ( s.getClazz() == null )
3086             {
3087                 addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_CLASS_CONSTRAINT",
3088                            Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3089                            "implementationDependencySpecificationClassConstraint", implementation.getIdentifier(),
3090                            moduleOfImpl.getName(), dependency.getName(), dependency.getIdentifier(),
3091                            moduleOfS.getName() );
3092 
3093             }
3094 
3095             if ( dependency.getVersion() != null )
3096             {
3097                 if ( s.getVersion() == null )
3098                 {
3099                     addDetail( validationContext.getReport(),
3100                                "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_VERSIONING_CONSTRAINT", Level.SEVERE,
3101                                new ObjectFactory().createImplementation( implementation ),
3102                                "implementationDependencySpecificationVersioningConstraint",
3103                                implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3104                                s.getIdentifier(), moduleOfS.getName() );
3105 
3106                 }
3107                 else
3108                 {
3109                     try
3110                     {
3111                         if ( VersionParser.compare( dependency.getVersion(), s.getVersion() ) > 0 )
3112                         {
3113                             addDetail( validationContext.getReport(),
3114                                        "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_CONSTRAINT",
3115                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3116                                        "implementationDependencySpecificationCompatibilityConstraint",
3117                                        implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
3118                                        moduleOfS.getName(), dependency.getVersion(), s.getVersion() );
3119 
3120                         }
3121                     }
3122                     catch ( final ParseException e )
3123                     {
3124                         final String message = getMessage( e );
3125 
3126                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3127                         {
3128                             validationContext.getModelContext().log( Level.FINE, message, e );
3129                         }
3130 
3131                         addDetail( validationContext.getReport(),
3132                                    "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
3133                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3134                                    "implementationDependencySpecificationCompatibilityParseException",
3135                                    implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
3136                                    moduleOfS.getName(), dependency.getVersion(),
3137                                    message != null && message.length() > 0 ? " " + message : "" );
3138 
3139                     }
3140                     catch ( final TokenMgrError e )
3141                     {
3142                         final String message = getMessage( e );
3143 
3144                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3145                         {
3146                             validationContext.getModelContext().log( Level.FINE, message, e );
3147                         }
3148 
3149                         addDetail( validationContext.getReport(),
3150                                    "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
3151                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3152                                    "implementationDependencySpecificationCompatibilityTokenMgrError",
3153                                    implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
3154                                    moduleOfS.getName(), dependency.getVersion(),
3155                                    message != null && message.length() > 0 ? " " + message : "" );
3156 
3157                     }
3158                 }
3159             }
3160 
3161             if ( s.getScope() != null )
3162             {
3163                 if ( dependency.getDependencies() != null )
3164                 {
3165                     for ( int i = 0, s0 = dependency.getDependencies().getDependency().size(); i < s0; i++ )
3166                     {
3167                         final Dependency d = dependency.getDependencies().getDependency().get( i );
3168 
3169                         addDetail( validationContext.getReport(),
3170                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCIES_OVERRIDE_CONSTRAINT", Level.SEVERE,
3171                                    new ObjectFactory().createImplementation( implementation ),
3172                                    "implementationDependencyDependenciesOverrideConstraint",
3173                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3174                                    d.getName(), s.getIdentifier(), moduleOfS.getName(), s.getScope() );
3175 
3176                     }
3177                 }
3178 
3179                 if ( dependency.getMessages() != null )
3180                 {
3181                     for ( int i = 0, s0 = dependency.getMessages().getMessage().size(); i < s0; i++ )
3182                     {
3183                         final Message m = dependency.getMessages().getMessage().get( i );
3184 
3185                         addDetail( validationContext.getReport(),
3186                                    "IMPLEMENTATION_DEPENDENCY_MESSAGES_OVERRIDE_CONSTRAINT", Level.SEVERE,
3187                                    new ObjectFactory().createImplementation( implementation ),
3188                                    "implementationDependencyMessagesOverrideConstraint", implementation.getIdentifier(),
3189                                    moduleOfImpl.getName(), dependency.getName(), m.getName(), s.getIdentifier(),
3190                                    moduleOfS.getName(), s.getScope() );
3191 
3192                     }
3193                 }
3194 
3195                 if ( dependency.getProperties() != null )
3196                 {
3197                     for ( int i = 0, s0 = dependency.getProperties().getProperty().size(); i < s0; i++ )
3198                     {
3199                         final Property p = dependency.getProperties().getProperty().get( i );
3200                         addDetail( validationContext.getReport(),
3201                                    "IMPLEMENTATION_DEPENDENCY_PROPERTIES_OVERRIDE_CONSTRAINT", Level.SEVERE,
3202                                    new ObjectFactory().createImplementation( implementation ),
3203                                    "implementationDependencyPropertiesOverrideConstraint",
3204                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3205                                    p.getName(), s.getIdentifier(), moduleOfS.getName(), s.getScope() );
3206 
3207                     }
3208                 }
3209             }
3210         }
3211 
3212         if ( dependency.getMessages() != null )
3213         {
3214             for ( int i = 0, s0 = dependency.getMessages().getMessage().size(); i < s0; i++ )
3215             {
3216                 final Message m = dependency.getMessages().getMessage().get( i );
3217 
3218                 if ( validationContext.isValidateJava() )
3219                 {
3220                     try
3221                     {
3222                         m.getJavaConstantName();
3223                     }
3224                     catch ( final ModelObjectException e )
3225                     {
3226                         final String message = getMessage( e );
3227 
3228                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3229                         {
3230                             validationContext.getModelContext().log( Level.FINE, message, e );
3231                         }
3232 
3233                         addDetail( validationContext.getReport(),
3234                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
3235                                    new ObjectFactory().createImplementation( implementation ),
3236                                    "implementationDependencyMessageJavaConstantNameConstraint",
3237                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3238                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3239                     }
3240 
3241                     try
3242                     {
3243                         m.getJavaGetterMethodName();
3244                     }
3245                     catch ( final ModelObjectException e )
3246                     {
3247                         final String message = getMessage( e );
3248 
3249                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3250                         {
3251                             validationContext.getModelContext().log( Level.FINE, message, e );
3252                         }
3253 
3254                         addDetail( validationContext.getReport(),
3255                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_GETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
3256                                    new ObjectFactory().createImplementation( implementation ),
3257                                    "implementationDependencyMessageJavaGetterMethodNameConstraint",
3258                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3259                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3260                     }
3261 
3262                     try
3263                     {
3264                         m.getJavaSetterMethodName();
3265                     }
3266                     catch ( final ModelObjectException e )
3267                     {
3268                         final String message = getMessage( e );
3269 
3270                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3271                         {
3272                             validationContext.getModelContext().log( Level.FINE, message, e );
3273                         }
3274 
3275                         addDetail( validationContext.getReport(),
3276                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_SETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
3277                                    new ObjectFactory().createImplementation( implementation ),
3278                                    "implementationDependencyMessageJavaSetterMethodNameConstraint",
3279                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3280                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3281                     }
3282 
3283                     try
3284                     {
3285                         m.getJavaVariableName();
3286                     }
3287                     catch ( final ModelObjectException e )
3288                     {
3289                         final String message = getMessage( e );
3290 
3291                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3292                         {
3293                             validationContext.getModelContext().log( Level.FINE, message, e );
3294                         }
3295 
3296                         addDetail( validationContext.getReport(),
3297                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_VARIABLE_NAME_CONSTRAINT", Level.SEVERE,
3298                                    new ObjectFactory().createImplementation( implementation ),
3299                                    "implementationDependencyMessageJavaVariableNameConstraint",
3300                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3301                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3302                     }
3303                 }
3304 
3305                 if ( m.getTemplate() != null )
3306                 {
3307                     for ( int j = 0, s1 = m.getTemplate().getText().size(); j < s1; j++ )
3308                     {
3309                         final Text t = m.getTemplate().getText().get( j );
3310 
3311                         try
3312                         {
3313                             t.getMimeType();
3314                         }
3315                         catch ( final ModelObjectException e )
3316                         {
3317                             final String message = getMessage( e );
3318 
3319                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3320                             {
3321                                 validationContext.getModelContext().log( Level.FINE, message, e );
3322                             }
3323 
3324                             addDetail( validationContext.getReport(),
3325                                        "IMPLEMENTATION_DEPENDENCY_MESSAGE_TEMPLATE_MIME_TYPE_CONSTRAINT", Level.SEVERE,
3326                                        new ObjectFactory().createImplementation( implementation ),
3327                                        "implementationDependencyMessageTemplateMimeTypeConstraint",
3328                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3329                                        m.getName(), t.getLanguage(),
3330                                        message != null && message.length() > 0 ? " " + message : "" );
3331 
3332                         }
3333 
3334                         if ( validationContext.isValidateJava() )
3335                         {
3336                             try
3337                             {
3338                                 new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
3339                             }
3340                             catch ( final IllegalArgumentException e )
3341                             {
3342                                 final String message = getMessage( e );
3343 
3344                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3345                                 {
3346                                     validationContext.getModelContext().log( Level.FINE, message, e );
3347                                 }
3348 
3349                                 addDetail( validationContext.getReport(),
3350                                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_TEMPLATE_CONSTRAINT", Level.SEVERE,
3351                                            new ObjectFactory().createImplementation( implementation ),
3352                                            "implementationDependencyMessageTemplateConstraint",
3353                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3354                                            m.getName(), t.getLanguage(),
3355                                            message != null && message.length() > 0 ? " " + message : "" );
3356 
3357                             }
3358                         }
3359                     }
3360                 }
3361 
3362                 if ( m.getArguments() != null )
3363                 {
3364                     final Map<JavaIdentifier, Argument> javaVariableNames =
3365                         new HashMap<JavaIdentifier, Argument>( m.getArguments().getArgument().size() );
3366 
3367                     for ( int j = 0, s1 = m.getArguments().getArgument().size(); j < s1; j++ )
3368                     {
3369                         final Argument a = m.getArguments().getArgument().get( j );
3370 
3371                         if ( validationContext.isValidateJava() )
3372                         {
3373                             try
3374                             {
3375                                 a.getJavaTypeName();
3376                             }
3377                             catch ( final ModelObjectException e )
3378                             {
3379                                 final String message = getMessage( e );
3380 
3381                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3382                                 {
3383                                     validationContext.getModelContext().log( Level.FINE, message, e );
3384                                 }
3385 
3386                                 addDetail( validationContext.getReport(),
3387                                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_ARGUMENT_JAVA_TYPE_NAME_CONSTRAINT",
3388                                            Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3389                                            "implementationDependencyMessageArgumentJavaTypeNameConstraint",
3390                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3391                                            m.getName(), a.getName(),
3392                                            message != null && message.length() > 0 ? " " + message : "" );
3393 
3394                             }
3395 
3396                             try
3397                             {
3398                                 final JavaIdentifier javaIdentifier = a.getJavaVariableName();
3399 
3400                                 if ( javaVariableNames.containsKey( javaIdentifier ) )
3401                                 {
3402                                     addDetail( validationContext.getReport(),
3403                                                "IMPLEMENTATION_DEPENDENCY_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
3404                                                Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3405                                                "implementationDependencyMessageArgumentJavaVariableNameUniquenessConstraint",
3406                                                implementation.getIdentifier(), moduleOfImpl.getName(),
3407                                                dependency.getName(), m.getName(), a.getName(), javaIdentifier,
3408                                                javaVariableNames.get( javaIdentifier ).getName() );
3409 
3410                                 }
3411                                 else
3412                                 {
3413                                     javaVariableNames.put( javaIdentifier, a );
3414                                 }
3415                             }
3416                             catch ( final ModelObjectException e )
3417                             {
3418                                 final String message = getMessage( e );
3419 
3420                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3421                                 {
3422                                     validationContext.getModelContext().log( Level.FINE, message, e );
3423                                 }
3424 
3425                                 addDetail( validationContext.getReport(),
3426                                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_CONSTRAINT",
3427                                            Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3428                                            "implementationDependencyMessageArgumentJavaVariableNameConstraint",
3429                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3430                                            m.getName(), a.getIndex(),
3431                                            message != null && message.length() > 0 ? " " + message : "" );
3432 
3433                             }
3434                         }
3435                     }
3436                 }
3437             }
3438 
3439             for ( int i = 0, s0 = dependency.getMessages().getReference().size(); i < s0; i++ )
3440             {
3441                 final MessageReference r = dependency.getMessages().getReference().get( i );
3442 
3443                 addDetail( validationContext.getReport(),
3444                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
3445                            new ObjectFactory().createImplementation( implementation ),
3446                            "implementationDependencyMessageReferenceDeclarationConstraint",
3447                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(), r.getName() );
3448 
3449             }
3450         }
3451 
3452         if ( dependency.getProperties() != null )
3453         {
3454             for ( int i = 0, s0 = dependency.getProperties().getProperty().size(); i < s0; i++ )
3455             {
3456                 final Property p = dependency.getProperties().getProperty().get( i );
3457 
3458                 if ( p.getValue() != null && p.getAny() != null )
3459                 {
3460                     addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_PROPERTY_VALUE_CONSTRAINT",
3461                                Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3462                                "implementationDependencyPropertyValueConstraint", implementation.getIdentifier(),
3463                                moduleOfImpl.getName(), dependency.getName(), p.getName() );
3464 
3465                 }
3466 
3467                 if ( p.getAny() != null && p.getType() == null )
3468                 {
3469                     addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_PROPERTY_TYPE_CONSTRAINT",
3470                                Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3471                                "implementationDependencyPropertyTypeConstraint", implementation.getIdentifier(),
3472                                moduleOfImpl.getName(), dependency.getName(), p.getName() );
3473 
3474                 }
3475 
3476                 if ( validationContext.isValidateJava() )
3477                 {
3478                     try
3479                     {
3480                         p.getJavaConstantName();
3481                     }
3482                     catch ( final ModelObjectException e )
3483                     {
3484                         final String message = getMessage( e );
3485 
3486                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3487                         {
3488                             validationContext.getModelContext().log( Level.FINE, message, e );
3489                         }
3490 
3491                         addDetail( validationContext.getReport(),
3492                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
3493                                    new ObjectFactory().createImplementation( implementation ),
3494                                    "implementationDependencyPropertyJavaConstantNameConstraint",
3495                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3496                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3497 
3498                     }
3499 
3500                     try
3501                     {
3502                         p.getJavaGetterMethodName();
3503                     }
3504                     catch ( final ModelObjectException e )
3505                     {
3506                         final String message = getMessage( e );
3507 
3508                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3509                         {
3510                             validationContext.getModelContext().log( Level.FINE, message, e );
3511                         }
3512 
3513                         addDetail( validationContext.getReport(),
3514                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
3515                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3516                                    "implementationDependencyPropertyJavaGetterMethodNameConstraint",
3517                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3518                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3519 
3520                     }
3521 
3522                     try
3523                     {
3524                         p.getJavaSetterMethodName();
3525                     }
3526                     catch ( final ModelObjectException e )
3527                     {
3528                         final String message = getMessage( e );
3529 
3530                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3531                         {
3532                             validationContext.getModelContext().log( Level.FINE, message, e );
3533                         }
3534 
3535                         addDetail( validationContext.getReport(),
3536                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
3537                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3538                                    "implementationDependencyPropertyJavaSetterMethodNameConstraint",
3539                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3540                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3541 
3542                     }
3543 
3544                     try
3545                     {
3546                         p.getJavaTypeName();
3547                     }
3548                     catch ( final ModelObjectException e )
3549                     {
3550                         final String message = getMessage( e );
3551 
3552                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3553                         {
3554                             validationContext.getModelContext().log( Level.FINE, message, e );
3555                         }
3556 
3557                         addDetail( validationContext.getReport(),
3558                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
3559                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3560                                    "implementationDependencyPropertyJavaTypeNameConstraint",
3561                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3562                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3563 
3564                     }
3565 
3566                     try
3567                     {
3568                         p.getJavaVariableName();
3569                     }
3570                     catch ( final ModelObjectException e )
3571                     {
3572                         final String message = getMessage( e );
3573 
3574                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3575                         {
3576                             validationContext.getModelContext().log( Level.FINE, message, e );
3577                         }
3578 
3579                         addDetail( validationContext.getReport(),
3580                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
3581                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3582                                    "implementationDependencyPropertyJavaVariableNameConstraint",
3583                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3584                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3585 
3586                     }
3587 
3588                     try
3589                     {
3590                         p.getJavaValue( validationContext.getModelContext().getClassLoader() );
3591                     }
3592                     catch ( final ModelObjectException e )
3593                     {
3594                         final String message = getMessage( e );
3595 
3596                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3597                         {
3598                             validationContext.getModelContext().log( Level.FINE, message, e );
3599                         }
3600 
3601                         addDetail( validationContext.getReport(),
3602                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_VALUE_CONSTRAINT", Level.SEVERE,
3603                                    new ObjectFactory().createImplementation( implementation ),
3604                                    "implementationDependencyPropertyJavaValueConstraint",
3605                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3606                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3607 
3608                     }
3609                 }
3610             }
3611 
3612             for ( int i = 0, s0 = dependency.getProperties().getReference().size(); i < s0; i++ )
3613             {
3614                 final PropertyReference r = dependency.getProperties().getReference().get( i );
3615 
3616                 addDetail( validationContext.getReport(),
3617                            "IMPLEMENTATION_DEPENDENCY_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
3618                            new ObjectFactory().createImplementation( implementation ),
3619                            "implementationDependencyPropertyReferenceDeclarationConstraint",
3620                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(), r.getName() );
3621 
3622             }
3623         }
3624 
3625         if ( available != null )
3626         {
3627             for ( int i = 0, s0 = available.getImplementation().size(); i < s0; i++ )
3628             {
3629                 final Implementation a = available.getImplementation().get( i );
3630 
3631                 if ( dependency.getImplementationName() != null
3632                      && !dependency.getImplementationName().equals( a.getName() ) )
3633                 {
3634                     continue;
3635                 }
3636 
3637                 final InheritanceModel imodel = validationContext.getInheritanceModel();
3638                 final Module moduleOfA = validationContext.getModuleOfImplementation( a.getIdentifier() );
3639 
3640                 if ( dependency.getDependencies() != null )
3641                 {
3642                     for ( int j = 0, s1 = dependency.getDependencies().getDependency().size(); j < s1; j++ )
3643                     {
3644                         final Dependency override = dependency.getDependencies().getDependency().get( j );
3645 
3646                         final Set<InheritanceModel.Node<Dependency>> effDependencies =
3647                             imodel.getDependencyNodes( a.getIdentifier(), override.getName() );
3648 
3649                         final Set<InheritanceModel.Node<Dependency>> overriddenDependencies =
3650                             modifiableSet( effDependencies );
3651 
3652                         final boolean effectiveDependencyOverridden = !overriddenDependencies.isEmpty();
3653 
3654                         if ( override.isOverride() && overriddenDependencies.isEmpty() )
3655                         {
3656                             addDetail( validationContext.getReport(),
3657                                        "IMPLEMENTATION_DEPENDENCY_OVERRIDE_DEPENDENCY_CONSTRAINT",
3658                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3659                                        "implementationDependencyOverrideDependencyConstraint",
3660                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3661                                        override.getName(), a.getIdentifier(), moduleOfA.getName() );
3662 
3663                         }
3664 
3665                         if ( !( override.isOverride() || overriddenDependencies.isEmpty() ) )
3666                         {
3667                             for ( final InheritanceModel.Node<Dependency> overriddenDependency : overriddenDependencies )
3668                             {
3669                                 addDetail( validationContext.getReport(),
3670                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_DEPENDENCY_WARNING",
3671                                            Level.WARNING, new ObjectFactory().createImplementation( implementation ),
3672                                            "implementationDependencyOverrideDependencyWarning",
3673                                            implementation.getIdentifier(), moduleOfImpl.getName(),
3674                                            dependency.getName(), override.getName(), a.getIdentifier(),
3675                                            moduleOfA.getName(), getNodePathString( overriddenDependency ) );
3676 
3677                             }
3678                         }
3679 
3680                         retainFinalNodes( overriddenDependencies );
3681 
3682                         for ( final InheritanceModel.Node<Dependency> overriddenDependency : overriddenDependencies )
3683                         {
3684                             addDetail( validationContext.getReport(),
3685                                        "IMPLEMENTATION_DEPENDENCY_FINAL_DEPENDENCY_CONSTRAINT",
3686                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3687                                        "implementationDependencyFinalDependencyConstraint",
3688                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3689                                        override.getName(), a.getIdentifier(), moduleOfA.getName(),
3690                                        getNodePathString( overriddenDependency ) );
3691 
3692                         }
3693 
3694                         if ( effectiveDependencyOverridden )
3695                         {
3696                             for ( InheritanceModel.Node<Dependency> node : effDependencies )
3697                             {
3698                                 final Dependency overridden = node.getModelObject();
3699 
3700                                 final Specification overrideSpecification =
3701                                     validationContext.getSpecification( override.getIdentifier() );
3702 
3703                                 final Specification overriddenSpecification =
3704                                     validationContext.getSpecification( overridden.getIdentifier() );
3705 
3706                                 if ( overrideSpecification != null && overriddenSpecification != null )
3707                                 {
3708                                     if ( overrideSpecification.getMultiplicity()
3709                                          != overriddenSpecification.getMultiplicity() )
3710                                     {
3711                                         addDetail( validationContext.getReport(),
3712                                                    "IMPLEMENTATION_DEPENDENCY_MULTIPLICITY_CONSTRAINT",
3713                                                    Level.SEVERE,
3714                                                    new ObjectFactory().createImplementation( implementation ),
3715                                                    "implementationDependencyMultiplicityConstraint",
3716                                                    implementation.getIdentifier(), moduleOfImpl.getName(),
3717                                                    dependency.getName(), overridden.getName(),
3718                                                    a.getIdentifier(), moduleOfA.getName(),
3719                                                    overrideSpecification.getMultiplicity().value(),
3720                                                    overriddenSpecification.getMultiplicity().value() );
3721 
3722                                     }
3723 
3724                                     if ( overrideSpecification.getScope() != null
3725                                          ? !overrideSpecification.getScope().equals(
3726                                         overriddenSpecification.getScope() )
3727                                          : overriddenSpecification.getScope() != null )
3728                                     {
3729                                         addDetail( validationContext.getReport(),
3730                                                    "IMPLEMENTATION_DEPENDENCY_SCOPE_CONSTRAINT", Level.SEVERE,
3731                                                    new ObjectFactory().createImplementation( implementation ),
3732                                                    "implementationDependencyScopeConstraint",
3733                                                    implementation.getIdentifier(), moduleOfImpl.getName(),
3734                                                    dependency.getName(), override.getName(),
3735                                                    a.getIdentifier(), moduleOfA.getName(),
3736                                                    overrideSpecification.getScope() == null
3737                                                    ? "Multiton" : overrideSpecification.getScope(),
3738                                                    overriddenSpecification.getScope() == null
3739                                                    ? "Multiton" : overriddenSpecification.getScope() );
3740 
3741                                     }
3742 
3743                                     if ( overriddenSpecification.getMultiplicity() == Multiplicity.MANY )
3744                                     {
3745                                         if ( override.getImplementationName() == null
3746                                              && overridden.getImplementationName() != null )
3747                                         {
3748                                             addDetail( validationContext.getReport(),
3749                                                        "IMPLEMENTATION_DEPENDENCY_NO_IMPLEMENTATION_NAME_CONSTRAINT",
3750                                                        Level.SEVERE,
3751                                                        new ObjectFactory().createImplementation( implementation ),
3752                                                        "implementationDependencyNoImplementationNameConstraint",
3753                                                        implementation.getIdentifier(), moduleOfImpl.getName(),
3754                                                        dependency.getName(), override.getName(),
3755                                                        a.getIdentifier(), moduleOfA.getName() );
3756 
3757                                         }
3758 
3759                                         if ( override.getImplementationName() != null
3760                                              && overridden.getImplementationName() == null )
3761                                         {
3762                                             addDetail( validationContext.getReport(),
3763                                                        "IMPLEMENTATION_DEPENDENCY_IMPLEMENTATION_NAME_CONSTRAINT",
3764                                                        Level.SEVERE,
3765                                                        new ObjectFactory().createImplementation( implementation ),
3766                                                        "implementationDependencyImplementationNameConstraint",
3767                                                        implementation.getIdentifier(), moduleOfImpl.getName(),
3768                                                        dependency.getName(), overridden.getName(),
3769                                                        a.getIdentifier(), moduleOfA.getName(),
3770                                                        override.getImplementationName() );
3771 
3772                                         }
3773                                     }
3774                                 }
3775 
3776                                 if ( override.isOptional() != overridden.isOptional() )
3777                                 {
3778                                     addDetail( validationContext.getReport(),
3779                                                "IMPLEMENTATION_DEPENDENCY_OPTIONALITY_CONSTRAINT", Level.SEVERE,
3780                                                new ObjectFactory().createImplementation( implementation ),
3781                                                "implementationDependencyOptonalityConstraint",
3782                                                implementation.getIdentifier(), moduleOfImpl.getName(),
3783                                                dependency.getName(), overridden.getName(),
3784                                                a.getIdentifier(), moduleOfA.getName() );
3785 
3786                                 }
3787                             }
3788                         }
3789                     }
3790                 }
3791 
3792                 if ( dependency.getMessages() != null )
3793                 {
3794                     for ( int j = 0, s1 = dependency.getMessages().getMessage().size(); j < s1; j++ )
3795                     {
3796                         final Message override = dependency.getMessages().getMessage().get( j );
3797 
3798                         final Set<InheritanceModel.Node<Message>> overriddenMessages =
3799                             modifiableSet( imodel.getMessageNodes( a.getIdentifier(), override.getName() ) );
3800 
3801                         if ( override.isOverride() && overriddenMessages.isEmpty() )
3802                         {
3803                             addDetail( validationContext.getReport(),
3804                                        "IMPLEMENTATION_DEPENDENCY_OVERRIDE_MESSAGE_CONSTRAINT", Level.SEVERE,
3805                                        new ObjectFactory().createImplementation( implementation ),
3806                                        "implementationDependencyOverrideMessageConstraint",
3807                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3808                                        override.getName(), a.getIdentifier(), moduleOfA.getName() );
3809 
3810                         }
3811 
3812                         if ( !( override.isOverride() || overriddenMessages.isEmpty() ) )
3813                         {
3814                             for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
3815                             {
3816                                 addDetail( validationContext.getReport(),
3817                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_MESSAGE_WARNING", Level.WARNING,
3818                                            new ObjectFactory().createImplementation( implementation ),
3819                                            "implementationDependencyOverrideMessageWarning",
3820                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3821                                            override.getName(), a.getIdentifier(), moduleOfA.getName(),
3822                                            getNodePathString( overriddenMessage ) );
3823 
3824                             }
3825                         }
3826 
3827                         retainFinalNodes( overriddenMessages );
3828 
3829                         for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
3830                         {
3831                             addDetail( validationContext.getReport(),
3832                                        "IMPLEMENTATION_DEPENDENCY_FINAL_MESSAGE_CONSTRAINT", Level.SEVERE,
3833                                        new ObjectFactory().createImplementation( implementation ),
3834                                        "implementationDependencyFinalMessageConstraint",
3835                                        implementation.getIdentifier(), moduleOfImpl.getName(),
3836                                        dependency.getName(), override.getName(), a.getIdentifier(),
3837                                        moduleOfA.getName(), getNodePathString( overriddenMessage ) );
3838 
3839                         }
3840                     }
3841                 }
3842 
3843                 if ( dependency.getProperties() != null )
3844                 {
3845                     for ( int j = 0, s1 = dependency.getProperties().getProperty().size(); j < s1; j++ )
3846                     {
3847                         final Property override = dependency.getProperties().getProperty().get( j );
3848 
3849                         final Set<InheritanceModel.Node<Property>> overriddenProperties =
3850                             modifiableSet( imodel.getPropertyNodes( a.getIdentifier(), override.getName() ) );
3851 
3852                         if ( override.isOverride() && overriddenProperties.isEmpty() )
3853                         {
3854                             addDetail( validationContext.getReport(),
3855                                        "IMPLEMENTATION_DEPENDENCY_OVERRIDE_PROPERTY_CONSTRAINT", Level.SEVERE,
3856                                        new ObjectFactory().createImplementation( implementation ),
3857                                        "implementationDependencyOverridePropertyConstraint",
3858                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3859                                        override.getName(), a.getIdentifier(), moduleOfA.getName() );
3860 
3861                         }
3862 
3863                         if ( !( override.isOverride() || overriddenProperties.isEmpty() ) )
3864                         {
3865                             for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
3866                             {
3867                                 addDetail( validationContext.getReport(),
3868                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_PROPERTY_WARNING", Level.WARNING,
3869                                            new ObjectFactory().createImplementation( implementation ),
3870                                            "implementationDependencyOverridePropertyWarning",
3871                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3872                                            override.getName(), a.getIdentifier(), moduleOfA.getName(),
3873                                            getNodePathString( overriddenProperty ) );
3874 
3875                             }
3876                         }
3877 
3878                         retainFinalNodes( overriddenProperties );
3879 
3880                         for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
3881                         {
3882                             addDetail( validationContext.getReport(),
3883                                        "IMPLEMENTATION_DEPENDENCY_FINAL_PROPERTY_CONSTRAINT", Level.SEVERE,
3884                                        new ObjectFactory().createImplementation( implementation ),
3885                                        "implementationDependencyFinalPropertyConstraint",
3886                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3887                                        override.getName(), a.getIdentifier(), moduleOfA.getName(),
3888                                        getNodePathString( overriddenProperty ) );
3889 
3890                         }
3891                     }
3892                 }
3893             }
3894         }
3895 
3896         if ( dependency.getDependencies() != null )
3897         {
3898             for ( int i = 0, s0 = dependency.getDependencies().getDependency().size(); i < s0; i++ )
3899             {
3900                 final Dependency d = dependency.getDependencies().getDependency().get( i );
3901 
3902                 if ( validationContext.isValidateJava() )
3903                 {
3904                     try
3905                     {
3906                         d.getJavaConstantName();
3907                     }
3908                     catch ( final ModelObjectException e )
3909                     {
3910                         final String message = getMessage( e );
3911 
3912                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3913                         {
3914                             validationContext.getModelContext().log( Level.FINE, message, e );
3915                         }
3916 
3917                         addDetail( validationContext.getReport(),
3918                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
3919                                    new ObjectFactory().createImplementation( implementation ),
3920                                    "implementationDependencyDependencyJavaConstantNameConstraint",
3921                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3922                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3923 
3924                     }
3925 
3926                     try
3927                     {
3928                         d.getJavaGetterMethodName();
3929                     }
3930                     catch ( final ModelObjectException e )
3931                     {
3932                         final String message = getMessage( e );
3933 
3934                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3935                         {
3936                             validationContext.getModelContext().log( Level.FINE, message, e );
3937                         }
3938 
3939                         addDetail( validationContext.getReport(),
3940                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
3941                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3942                                    "implementationDependencyDependencyJavaGetterMethodNameConstraint",
3943                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3944                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3945 
3946                     }
3947 
3948                     try
3949                     {
3950                         d.getJavaSetterMethodName();
3951                     }
3952                     catch ( final ModelObjectException e )
3953                     {
3954                         final String message = getMessage( e );
3955 
3956                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3957                         {
3958                             validationContext.getModelContext().log( Level.FINE, message, e );
3959                         }
3960 
3961                         addDetail( validationContext.getReport(),
3962                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
3963                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3964                                    "implementationDependencyDependencyJavaSetterMethodNameConstraint",
3965                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3966                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3967 
3968                     }
3969 
3970                     try
3971                     {
3972                         d.getJavaVariableName();
3973                     }
3974                     catch ( final ModelObjectException e )
3975                     {
3976                         final String message = getMessage( e );
3977 
3978                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3979                         {
3980                             validationContext.getModelContext().log( Level.FINE, message, e );
3981                         }
3982 
3983                         addDetail( validationContext.getReport(),
3984                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_VARIABLE_NAME_CONSTRAINT",
3985                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3986                                    "implementationDependencyDependencyJavaVariableNameConstraint",
3987                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3988                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3989 
3990                     }
3991                 }
3992 
3993                 assertDependencyValid( validationContext, implementation, d );
3994             }
3995         }
3996     }
3997 
3998     private static void assertImplementationSpecificationCompatibility(
3999         final ValidationContext validationContext, final Implementation implementation )
4000     {
4001         final Specifications specs = validationContext.getSpecifications( implementation.getIdentifier() );
4002         final Module moduleOfImpl =
4003             validationContext.getModuleOfImplementation( implementation.getIdentifier() );
4004 
4005         if ( specs != null )
4006         {
4007             for ( int i = 0, s0 = specs.getReference().size(); i < s0; i++ )
4008             {
4009                 final SpecificationReference r = specs.getReference().get( i );
4010                 final Specification s = specs.getSpecification( r.getIdentifier() );
4011 
4012                 if ( s != null && r.getVersion() != null )
4013                 {
4014                     final Module moduleOfS =
4015                         validationContext.getModuleOfSpecification( s.getIdentifier() );
4016 
4017                     if ( s.getVersion() == null )
4018                     {
4019                         addDetail( validationContext.getReport(),
4020                                    "IMPLEMENTATION_SPECIFICATION_VERSIONING_CONSTRAINT", Level.SEVERE,
4021                                    new ObjectFactory().createImplementation( implementation ),
4022                                    "implementationSpecificationVersioningConstraint", implementation.getIdentifier(),
4023                                    moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName() );
4024 
4025                     }
4026                     else
4027                     {
4028                         try
4029                         {
4030                             if ( VersionParser.compare( r.getVersion(), s.getVersion() ) != 0 )
4031                             {
4032                                 addDetail( validationContext.getReport(),
4033                                            "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_CONSTRAINT", Level.SEVERE,
4034                                            new ObjectFactory().createImplementation( implementation ),
4035                                            "implementationSpecificationCompatibilityConstraint",
4036                                            implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
4037                                            moduleOfS.getName(), r.getVersion(), s.getVersion() );
4038 
4039                             }
4040                         }
4041                         catch ( final ParseException e )
4042                         {
4043                             final String message = getMessage( e );
4044 
4045                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
4046                             {
4047                                 validationContext.getModelContext().log( Level.FINE, message, e );
4048                             }
4049 
4050                             addDetail( validationContext.getReport(),
4051                                        "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
4052                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
4053                                        "implementationSpecificationCompatibilityVersioningParseException",
4054                                        implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
4055                                        moduleOfS.getName(), r.getVersion(),
4056                                        message != null && message.length() > 0 ? " " + message : "" );
4057 
4058                         }
4059                         catch ( final TokenMgrError e )
4060                         {
4061                             final String message = getMessage( e );
4062 
4063                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
4064                             {
4065                                 validationContext.getModelContext().log( Level.FINE, message, e );
4066                             }
4067 
4068                             addDetail( validationContext.getReport(),
4069                                        "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
4070                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
4071                                        "implementationSpecificationCompatibilityVersioningTokenManagerError",
4072                                        implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
4073                                        moduleOfS.getName(), r.getVersion(),
4074                                        message != null && message.length() > 0 ? " " + message : "" );
4075 
4076                         }
4077                     }
4078                 }
4079             }
4080         }
4081     }
4082 
4083     private static <T> String getNodePathString( final InheritanceModel.Node<T> node )
4084     {
4085         final StringBuilder b = new StringBuilder( node.getPath().size() * 50 );
4086 
4087         for ( int i = 0, s0 = node.getPath().size(); i < s0; i++ )
4088         {
4089             final InheritanceModel.Node<Implementation> pathNode = node.getPath().get( i );
4090 
4091             if ( pathNode.getClassDeclaration() != null )
4092             {
4093                 b.append( " -> [" ).append( pathNode.getClassDeclaration().getClazz() ).append( "] @ '" ).
4094                     append( pathNode.getImplementation().getIdentifier() ).append( "'" );
4095 
4096             }
4097             if ( pathNode.getSpecification() != null )
4098             {
4099                 b.append( " -> <" ).append( pathNode.getSpecification().getIdentifier() ).append( "> @ '" ).
4100                     append( pathNode.getImplementation().getIdentifier() ).append( "'" );
4101 
4102             }
4103             else
4104             {
4105                 b.append( " -> '" ).append( pathNode.getImplementation().getIdentifier() ).append( "'" );
4106             }
4107         }
4108 
4109         if ( node.getClassDeclaration() != null )
4110         {
4111             b.append( " -> [" ).append( node.getClassDeclaration().getClazz() ).append( "] @ '" ).
4112                 append( node.getImplementation().getIdentifier() ).append( "'" );
4113 
4114         }
4115         if ( node.getSpecification() != null )
4116         {
4117             b.append( " -> <" ).append( node.getSpecification().getIdentifier() ).append( "> @ '" ).
4118                 append( node.getImplementation().getIdentifier() ).append( "'" );
4119 
4120         }
4121 
4122         return b.length() > 0 ? b.substring( " -> ".length() ) : b.toString();
4123     }
4124 
4125     private static <T> String getNodeListPathString( final Collection<? extends InheritanceModel.Node<T>> nodes )
4126     {
4127         final StringBuilder path = new StringBuilder( nodes.size() * 255 );
4128 
4129         for ( final InheritanceModel.Node<T> node : nodes )
4130         {
4131             path.append( ", " ).append( getNodePathString( node ) );
4132         }
4133 
4134         return path.length() > 1 ? path.substring( 2 ) : path.toString();
4135     }
4136 
4137     private static <T> Set<InheritanceModel.Node<T>> retainFinalNodes( final Set<InheritanceModel.Node<T>> set )
4138     {
4139         if ( set != null )
4140         {
4141             for ( final Iterator<InheritanceModel.Node<T>> it = set.iterator(); it.hasNext(); )
4142             {
4143                 if ( !it.next().isFinal() )
4144                 {
4145                     it.remove();
4146                 }
4147             }
4148         }
4149 
4150         return set;
4151     }
4152 
4153     private static void addDetail(
4154         final ModelValidationReport report, final String identifier, final Level level,
4155         final JAXBElement<? extends ModelObject> element, final String messageKey, final Object... messageArguments )
4156     {
4157         report.getDetails().add( new ModelValidationReport.Detail(
4158             identifier, level, getMessage( messageKey, messageArguments ), element ) );
4159 
4160     }
4161 
4162     private static <T> Set<T> modifiableSet( final Collection<? extends T> col )
4163     {
4164         Set<T> set = Collections.emptySet();
4165 
4166         if ( col != null )
4167         {
4168             set = new HashSet<T>( col );
4169         }
4170 
4171         return set;
4172     }
4173 
4174     private static String getMessage( final String key, final Object... messageArguments )
4175     {
4176         return MessageFormat.format( ResourceBundle.getBundle(
4177             DefaultModelValidator.class.getName().replace( '.', '/' ),
4178             Locale.getDefault() ).getString( key ), messageArguments );
4179 
4180     }
4181 
4182     private static String getMessage( final Throwable t )
4183     {
4184         return t != null
4185                ? t.getMessage() != null && t.getMessage().trim().length() > 0
4186                  ? t.getMessage()
4187                  : getMessage( t.getCause() )
4188                : null;
4189 
4190     }
4191 
4192     /** @since 1.2 */
4193     private static final class ValidationContext
4194     {
4195 
4196         private final ModelContext modelContext;
4197 
4198         private final Modules modules;
4199 
4200         private final ModelValidationReport report;
4201 
4202         private final InheritanceModel inheritanceModel;
4203 
4204         private final boolean validateJava;
4205 
4206         private final Specifications allSpecifications;
4207 
4208         private final Implementations allImplementations;
4209 
4210         private final Map<String, Specification> specifications = new HashMap<String, Specification>();
4211 
4212         private final Map<String, Specifications> specificationsByImplementation =
4213             new HashMap<String, Specifications>();
4214 
4215         private final Map<String, Module> modulesOfSpecifications = new HashMap<String, Module>();
4216 
4217         private final Map<String, Implementation> implementations = new HashMap<String, Implementation>();
4218 
4219         private final Map<String, Implementations> implementationsBySpecification =
4220             new HashMap<String, Implementations>();
4221 
4222         private final Map<String, Module> modulesOfImplementations = new HashMap<String, Module>();
4223 
4224         private ValidationContext( final ModelContext modelContext, final Modules modules,
4225                                    final ModelValidationReport report, final boolean validateJava )
4226         {
4227             super();
4228             this.modelContext = modelContext;
4229             this.modules = modules;
4230             this.report = report;
4231             this.inheritanceModel = new InheritanceModel( modules );
4232             this.validateJava = validateJava;
4233             this.allImplementations = modules.getImplementations();
4234             this.allSpecifications = modules.getSpecifications();
4235 
4236             if ( this.allSpecifications != null )
4237             {
4238                 for ( final Specification s : this.allSpecifications.getSpecification() )
4239                 {
4240                     this.specifications.put( s.getIdentifier(), s );
4241                     this.implementationsBySpecification.put(
4242                         s.getIdentifier(), modules.getImplementations( s.getIdentifier() ) );
4243 
4244                     this.modulesOfSpecifications.put(
4245                         s.getIdentifier(), modules.getModuleOfSpecification( s.getIdentifier() ) );
4246 
4247                 }
4248             }
4249 
4250             if ( this.allImplementations != null )
4251             {
4252                 for ( final Implementation i : this.allImplementations.getImplementation() )
4253                 {
4254                     this.implementations.put( i.getIdentifier(), i );
4255                     this.specificationsByImplementation.put(
4256                         i.getIdentifier(), modules.getSpecifications( i.getIdentifier() ) );
4257 
4258                     this.modulesOfImplementations.put(
4259                         i.getIdentifier(), modules.getModuleOfImplementation( i.getIdentifier() ) );
4260                 }
4261             }
4262         }
4263 
4264         private ModelContext getModelContext()
4265         {
4266             return modelContext;
4267         }
4268 
4269         private Modules getModules()
4270         {
4271             return modules;
4272         }
4273 
4274         private ModelValidationReport getReport()
4275         {
4276             return report;
4277         }
4278 
4279         private InheritanceModel getInheritanceModel()
4280         {
4281             return this.inheritanceModel;
4282         }
4283 
4284         private boolean isValidateJava()
4285         {
4286             return this.validateJava;
4287         }
4288 
4289         private Specifications getAllSpecifications()
4290         {
4291             return this.allSpecifications;
4292         }
4293 
4294         private Implementations getAllImplementations()
4295         {
4296             return this.allImplementations;
4297         }
4298 
4299         private Specification getSpecification( final String identifier )
4300         {
4301             return this.specifications.get( identifier );
4302         }
4303 
4304         private Specifications getSpecifications( final String implementation )
4305         {
4306             return this.specificationsByImplementation.get( implementation );
4307         }
4308 
4309         private Implementation getImplementation( final String identifier )
4310         {
4311             return this.implementations.get( identifier );
4312         }
4313 
4314         private Implementations getImplementations( final String specification )
4315         {
4316             return this.implementationsBySpecification.get( specification );
4317         }
4318 
4319         private Module getModuleOfSpecification( final String identifier )
4320         {
4321             return this.modulesOfSpecifications.get( identifier );
4322         }
4323 
4324         private Module getModuleOfImplementation( final String identifier )
4325         {
4326             return this.modulesOfImplementations.get( identifier );
4327         }
4328 
4329     }
4330 
4331 }