001 /* 002 * Copyright (C) Christian Schulte, 2005-206 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions 007 * are met: 008 * 009 * o Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 012 * o Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in 014 * the documentation and/or other materials provided with the 015 * distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 027 * 028 * $JOMC: DefaultModelValidator.java 4426 2012-03-14 09:11:54Z schulte2005 $ 029 * 030 */ 031 package org.jomc.model.modlet; 032 033 import java.text.MessageFormat; 034 import java.util.Collection; 035 import java.util.Collections; 036 import java.util.HashMap; 037 import java.util.HashSet; 038 import java.util.Iterator; 039 import java.util.LinkedList; 040 import java.util.List; 041 import java.util.Locale; 042 import java.util.Map; 043 import java.util.ResourceBundle; 044 import java.util.Set; 045 import java.util.logging.Level; 046 import javax.xml.bind.JAXBElement; 047 import javax.xml.bind.JAXBException; 048 import javax.xml.bind.util.JAXBSource; 049 import javax.xml.namespace.QName; 050 import javax.xml.transform.Source; 051 import org.jomc.model.Dependency; 052 import org.jomc.model.Implementation; 053 import org.jomc.model.ImplementationReference; 054 import org.jomc.model.Implementations; 055 import org.jomc.model.Inheritable; 056 import org.jomc.model.InheritanceModel; 057 import org.jomc.model.Message; 058 import org.jomc.model.MessageReference; 059 import org.jomc.model.ModelObject; 060 import org.jomc.model.Module; 061 import org.jomc.model.Modules; 062 import org.jomc.model.Multiplicity; 063 import org.jomc.model.ObjectFactory; 064 import org.jomc.model.Property; 065 import org.jomc.model.PropertyException; 066 import org.jomc.model.PropertyReference; 067 import org.jomc.model.Specification; 068 import org.jomc.model.SpecificationReference; 069 import org.jomc.model.Specifications; 070 import org.jomc.model.Text; 071 import org.jomc.modlet.Model; 072 import org.jomc.modlet.ModelContext; 073 import org.jomc.modlet.ModelException; 074 import org.jomc.modlet.ModelValidationReport; 075 import org.jomc.modlet.ModelValidator; 076 import org.jomc.util.ParseException; 077 import org.jomc.util.TokenMgrError; 078 import org.jomc.util.VersionParser; 079 import org.w3c.dom.Element; 080 081 /** 082 * Default object management and configuration {@code ModelValidator} implementation. 083 * 084 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 085 * @version $JOMC: DefaultModelValidator.java 4426 2012-03-14 09:11:54Z schulte2005 $ 086 * @see ModelContext#validateModel(org.jomc.modlet.Model) 087 */ 088 public class DefaultModelValidator implements ModelValidator 089 { 090 091 /** Creates a new {@code DefaultModelValidator} instance. */ 092 public DefaultModelValidator() 093 { 094 super(); 095 } 096 097 public ModelValidationReport validateModel( final ModelContext context, final Model model ) throws ModelException 098 { 099 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 }