EMMA Coverage Report (generated Sun Apr 01 02:45:34 CEST 2012)
[all classes][org.jomc.model.modlet]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultModelValidator.java]

nameclass, %method, %block, %line, %
DefaultModelValidator.java100% (2/2)100% (25/25)95%  (6511/6841)94%  (629/666)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultModelValidator100% (1/1)100% (15/15)95%  (6463/6793)94%  (618/655)
getMessage (Throwable): String 100% (1/1)64%  (9/14)64%  (0.6/1)
validateModel (ModelContext, Model): ModelValidationReport 100% (1/1)66%  (54/82)65%  (13/20)
getNodePathString (InheritanceModel$Node): String 100% (1/1)72%  (89/124)83%  (10.8/13)
assertImplementationSpecificationCompatibility (DefaultModelValidator$Validat... 100% (1/1)74%  (206/278)79%  (19/24)
getNodeListPathString (Collection): String 100% (1/1)95%  (35/37)95%  (3.8/4)
assertDependencyValid (DefaultModelValidator$ValidationContext, Implementatio... 100% (1/1)96%  (1782/1859)96%  (121.9/127)
assertImplementationsValid (DefaultModelValidator$ValidationContext): void 100% (1/1)97%  (3098/3208)95%  (315.9/333)
assertSpecificationsValid (DefaultModelValidator$ValidationContext): void 100% (1/1)100% (539/540)100% (54/54)
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)
assertModulesValid (DefaultModelValidator$ValidationContext): void 100% (1/1)100% (530/530)100% (52/52)
getMessage (String, Object []): String 100% (1/1)100% (12/12)100% (1/1)
isInheritanceCycle (DefaultModelValidator$ValidationContext, Implementation, ... 100% (1/1)100% (63/63)100% (13/13)
modifiableSet (Collection): Set 100% (1/1)100% (11/11)100% (4/4)
retainFinalNodes (Set): Set 100% (1/1)100% (18/18)100% (5/5)
     
class DefaultModelValidator$ValidationContext100% (1/1)100% (10/10)100% (48/48)100% (11/11)
DefaultModelValidator$ValidationContext (ModelContext, Modules, ModelValidati... 100% (1/1)100% (18/18)100% (6/6)
DefaultModelValidator$ValidationContext (ModelContext, Modules, ModelValidati... 100% (1/1)100% (6/6)100% (1/1)
access$100 (DefaultModelValidator$ValidationContext): Modules 100% (1/1)100% (3/3)100% (1/1)
access$200 (DefaultModelValidator$ValidationContext): ModelValidationReport 100% (1/1)100% (3/3)100% (1/1)
access$300 (DefaultModelValidator$ValidationContext): ModelContext 100% (1/1)100% (3/3)100% (1/1)
access$400 (DefaultModelValidator$ValidationContext): InheritanceModel 100% (1/1)100% (3/3)100% (1/1)
getInheritanceModel (): InheritanceModel 100% (1/1)100% (3/3)100% (1/1)
getModelContext (): ModelContext 100% (1/1)100% (3/3)100% (1/1)
getModules (): Modules 100% (1/1)100% (3/3)100% (1/1)
getReport (): ModelValidationReport 100% (1/1)100% (3/3)100% (1/1)

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

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