EMMA Coverage Report (generated Thu Jan 03 04:54:40 CET 2013)
[all classes][org.jomc.model.modlet]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultModelValidator.java]

nameclass, %method, %block, %line, %
DefaultModelValidator.java100% (2/2)94%  (30/32)95%  (11206/11799)95%  (1161.7/1222)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultModelValidator100% (1/1)90%  (18/20)95%  (11148/11741)95%  (1148.7/1209)
setDefaultValidateJava (Boolean): void 0%   (0/1)0%   (0/3)0%   (0/2)
setValidateJava (Boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
getMessage (Throwable): String 100% (1/1)64%  (9/14)64%  (0.6/1)
validateModel (ModelContext, Model): ModelValidationReport 100% (1/1)66%  (67/101)65%  (15/23)
getNodePathString (InheritanceModel$Node): String 100% (1/1)72%  (89/124)83%  (10.8/13)
assertImplementationSpecificationCompatibility (DefaultModelValidator$Validat... 100% (1/1)74%  (206/278)79%  (19/24)
assertModulesValid (DefaultModelValidator$ValidationContext): void 100% (1/1)95%  (1310/1385)96%  (141.6/147)
getNodeListPathString (Collection): String 100% (1/1)95%  (35/37)96%  (4.8/5)
assertDependencyValid (DefaultModelValidator$ValidationContext, Implementatio... 100% (1/1)95%  (3060/3224)96%  (258.6/269)
assertImplementationsValid (DefaultModelValidator$ValidationContext): void 100% (1/1)96%  (5233/5425)96%  (556.5/580)
assertSpecificationsValid (DefaultModelValidator$ValidationContext): void 100% (1/1)99%  (992/999)99%  (107.8/109)
<static initializer> 100% (1/1)100% (3/3)100% (1/1)
DefaultModelValidator (): void 100% (1/1)100% (3/3)100% (2/2)
addDetail (ModelValidationReport, String, Level, JAXBElement, String, Object ... 100% (1/1)100% (14/14)100% (2/2)
getMessage (String, Object []): String 100% (1/1)100% (12/12)100% (1/1)
isDefaultValidateJava (): boolean 100% (1/1)100% (12/12)100% (3/3)
isInheritanceCycle (DefaultModelValidator$ValidationContext, Implementation, ... 100% (1/1)100% (63/63)100% (13/13)
isValidateJava (): boolean 100% (1/1)100% (11/11)100% (3/3)
modifiableSet (Collection): Set 100% (1/1)100% (11/11)100% (4/4)
retainFinalNodes (Set): Set 100% (1/1)100% (18/18)100% (5/5)
     
class DefaultModelValidator$ValidationContext100% (1/1)100% (12/12)100% (58/58)100% (13/13)
DefaultModelValidator$ValidationContext (ModelContext, Modules, ModelValidati... 100% (1/1)100% (21/21)100% (7/7)
DefaultModelValidator$ValidationContext (ModelContext, Modules, ModelValidati... 100% (1/1)100% (7/7)100% (1/1)
access$100 (DefaultModelValidator$ValidationContext): Modules 100% (1/1)100% (3/3)100% (1/1)
access$200 (DefaultModelValidator$ValidationContext): ModelValidationReport 100% (1/1)100% (3/3)100% (1/1)
access$300 (DefaultModelValidator$ValidationContext): boolean 100% (1/1)100% (3/3)100% (1/1)
access$400 (DefaultModelValidator$ValidationContext): ModelContext 100% (1/1)100% (3/3)100% (1/1)
access$500 (DefaultModelValidator$ValidationContext): InheritanceModel 100% (1/1)100% (3/3)100% (1/1)
getInheritanceModel (): InheritanceModel 100% (1/1)100% (3/3)100% (1/1)
getModelContext (): ModelContext 100% (1/1)100% (3/3)100% (1/1)
getModules (): Modules 100% (1/1)100% (3/3)100% (1/1)
getReport (): ModelValidationReport 100% (1/1)100% (3/3)100% (1/1)
isValidateJava (): boolean 100% (1/1)100% (3/3)100% (1/1)

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

[all classes][org.jomc.model.modlet]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov