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