EMMA Coverage Report (generated Wed Mar 26 15:19:37 CET 2014)
[all classes][org.jomc.model.modlet]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultModelValidator.java]

nameclass, %method, %block, %line, %
DefaultModelValidator.java100% (2/2)96%  (49/51)95%  (11375/11976)95%  (1192.8/1254)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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