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: ToolsModelValidatorTest.java 4861 2014-02-13 23:23:29Z schulte $
029 *
030 */
031package org.jomc.tools.modlet.test;
032
033import java.util.List;
034import javax.xml.bind.util.JAXBSource;
035import org.jomc.model.Dependencies;
036import org.jomc.model.Dependency;
037import org.jomc.model.Implementation;
038import org.jomc.model.Implementations;
039import org.jomc.model.Message;
040import org.jomc.model.Messages;
041import org.jomc.model.ModelObject;
042import org.jomc.model.Module;
043import org.jomc.model.Modules;
044import org.jomc.model.Specification;
045import org.jomc.model.Specifications;
046import org.jomc.model.Text;
047import org.jomc.model.Texts;
048import org.jomc.model.modlet.ModelHelper;
049import org.jomc.modlet.Model;
050import org.jomc.modlet.ModelContext;
051import org.jomc.modlet.ModelContextFactory;
052import org.jomc.modlet.ModelValidationReport;
053import org.jomc.tools.model.ObjectFactory;
054import org.jomc.tools.model.SourceFileType;
055import org.jomc.tools.model.SourceFilesType;
056import org.jomc.tools.model.SourceSectionType;
057import org.jomc.tools.model.SourceSectionsType;
058import org.jomc.tools.model.TemplateParameterType;
059import org.jomc.tools.modlet.ToolsModelValidator;
060import org.junit.Test;
061import static org.junit.Assert.assertNotNull;
062import static org.junit.Assert.assertTrue;
063import static org.junit.Assert.fail;
064
065/**
066 * Test cases for class {@code org.jomc.tools.modlet.ToolsModelValidator}.
067 *
068 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 1.0
069 * @version $JOMC: ToolsModelValidatorTest.java 4861 2014-02-13 23:23:29Z schulte $
070 */
071public class ToolsModelValidatorTest
072{
073
074    /** The {@code ToolsModelValidator} instance tests are performed with. */
075    private ToolsModelValidator toolsModelValidator;
076
077    /** Creates a new {@code ToolsModelValidatorTest} instance. */
078    public ToolsModelValidatorTest()
079    {
080        super();
081    }
082
083    /**
084     * Gets the {@code ToolsModelValidator} instance tests are performed with.
085     *
086     * @return The {@code ToolsModelValidator} instance tests are performed with.
087     *
088     * @see #newModelValidator()
089     */
090    public ToolsModelValidator getModelValidator()
091    {
092        if ( this.toolsModelValidator == null )
093        {
094            this.toolsModelValidator = this.newModelValidator();
095        }
096
097        return this.toolsModelValidator;
098    }
099
100    /**
101     * Create a new {@code ToolsModelValidator} instance to test.
102     *
103     * @return A new {@code ToolsModelValidator} instance to test.
104     *
105     * @see #getModelValidator()
106     */
107    protected ToolsModelValidator newModelValidator()
108    {
109        return new ToolsModelValidator();
110    }
111
112    @Test
113    public final void testValidateModel() throws Exception
114    {
115        final ModelContext modelContext = ModelContextFactory.newInstance().newModelContext();
116
117        try
118        {
119            this.getModelValidator().validateModel( modelContext, null );
120            fail( "Expected NullPointerException not thrown." );
121        }
122        catch ( final NullPointerException e )
123        {
124            assertNotNull( e.getMessage() );
125            System.out.println( e.toString() );
126        }
127
128        try
129        {
130            this.getModelValidator().validateModel( null, new Model() );
131            fail( "Expected NullPointerException not thrown." );
132        }
133        catch ( final NullPointerException e )
134        {
135            assertNotNull( e.getMessage() );
136            System.out.println( e.toString() );
137        }
138
139        ModelValidationReport report = this.getModelValidator().validateModel( modelContext, new Model() );
140        assertNotNull( report );
141        assertTrue( report.isModelValid() );
142
143        final Model model = new Model();
144        model.setIdentifier( ModelObject.MODEL_PUBLIC_ID );
145
146        final SourceFileType sourceFile1 = new SourceFileType();
147        sourceFile1.setIdentifier( this.getClass().getSimpleName() + " 1" );
148        sourceFile1.getTemplateParameter().add( new TemplateParameterType() );
149        sourceFile1.getTemplateParameter().get( 0 ).setName( "SourceFile1" );
150        sourceFile1.getTemplateParameter().get( 0 ).setType( "DOES_NOT_EXIST" );
151        sourceFile1.getTemplateParameter().get( 0 ).setValue( "TEST" );
152
153        final SourceFileType sourceFile2 = new SourceFileType();
154        sourceFile2.setIdentifier( this.getClass().getSimpleName() + " 2" );
155        sourceFile2.getTemplateParameter().add( new TemplateParameterType() );
156        sourceFile2.getTemplateParameter().get( 0 ).setName( "SourceFile2" );
157        sourceFile2.getTemplateParameter().get( 0 ).setType( "DOES_NOT_EXIST" );
158        sourceFile2.getTemplateParameter().get( 0 ).setValue( "TEST" );
159
160        final SourceFilesType sourceFiles1 = new SourceFilesType();
161        sourceFiles1.getSourceFile().add( sourceFile1 );
162        sourceFiles1.getSourceFile().add( sourceFile2 );
163
164        final SourceFilesType sourceFiles2 = new SourceFilesType();
165        sourceFiles2.getSourceFile().add( sourceFile1 );
166        sourceFiles2.getSourceFile().add( sourceFile2 );
167
168        final SourceSectionType sourceSection1 = new SourceSectionType();
169        sourceSection1.setName( this.getClass().getSimpleName() + " 1" );
170        sourceSection1.getTemplateParameter().add( new TemplateParameterType() );
171        sourceSection1.getTemplateParameter().get( 0 ).setName( "SourceSection1" );
172        sourceSection1.getTemplateParameter().get( 0 ).setType( "DOES_NOT_EXIST" );
173        sourceSection1.getTemplateParameter().get( 0 ).setValue( "TEST" );
174        sourceSection1.setSourceSections( new SourceSectionsType() );
175        sourceSection1.getSourceSections().getSourceSection().add( sourceSection1.clone() );
176        sourceSection1.getSourceSections().getSourceSection().get( 0 ).setName( "SourceSection1 - nested" );
177
178        final SourceSectionType sourceSection2 = new SourceSectionType();
179        sourceSection2.setName( this.getClass().getSimpleName() + " 2" );
180        sourceSection2.getTemplateParameter().add( new TemplateParameterType() );
181        sourceSection2.getTemplateParameter().get( 0 ).setName( "SourceSection2" );
182        sourceSection2.getTemplateParameter().get( 0 ).setType( "DOES_NOT_EXIST" );
183        sourceSection2.getTemplateParameter().get( 0 ).setValue( "TEST" );
184        sourceSection2.setSourceSections( new SourceSectionsType() );
185        sourceSection2.getSourceSections().getSourceSection().add( sourceSection2.clone() );
186        sourceSection2.getSourceSections().getSourceSection().get( 0 ).setName( "SourceSection2 - nested" );
187
188        final SourceSectionsType sourceSections1 = new SourceSectionsType();
189        sourceSections1.getSourceSection().add( sourceSection1 );
190        sourceSections1.getSourceSection().add( sourceSection2 );
191
192        final SourceSectionsType sourceSections2 = new SourceSectionsType();
193        sourceSections2.getSourceSection().add( sourceSection1 );
194        sourceSections2.getSourceSection().add( sourceSection2 );
195
196        sourceFile1.setSourceSections( sourceSections1 );
197        sourceFile2.setSourceSections( sourceSections2 );
198
199        model.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
200        model.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
201        model.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
202        model.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
203        model.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
204        model.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
205        model.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
206        model.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
207        model.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
208        model.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
209
210        final Modules modules = new Modules();
211        ModelHelper.setModules( model, modules );
212
213        final Module module = new Module();
214        modules.getModule().add( module );
215        module.setSpecifications( new Specifications() );
216        module.setImplementations( new Implementations() );
217        module.setName( this.getClass().getSimpleName() );
218
219        module.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
220        module.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
221        module.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
222        module.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
223        module.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
224        module.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
225        module.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
226        module.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
227        module.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
228        module.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
229        module.setMessages( new Messages() );
230
231        final Specification specification = new Specification();
232        specification.setIdentifier( this.getClass().getSimpleName() );
233        specification.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
234        specification.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
235        specification.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
236        specification.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
237        specification.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
238        specification.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
239        specification.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
240        specification.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
241        specification.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
242        specification.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
243
244        final Implementation implementation = new Implementation();
245        implementation.setIdentifier( this.getClass().getSimpleName() );
246        implementation.setName( this.getClass().getSimpleName() );
247        implementation.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
248        implementation.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
249        implementation.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
250        implementation.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
251        implementation.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
252        implementation.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
253        implementation.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
254        implementation.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
255        implementation.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
256        implementation.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
257
258        implementation.setDependencies( new Dependencies() );
259        implementation.setMessages( new Messages() );
260
261        final Dependency dependency = new Dependency();
262        dependency.setName( this.getClass().getSimpleName() );
263        dependency.setIdentifier( this.getClass().getSimpleName() );
264        dependency.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
265        dependency.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
266        dependency.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
267        dependency.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
268        dependency.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
269        dependency.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
270        dependency.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
271        dependency.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
272        dependency.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
273        dependency.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
274
275        final Message message = new Message();
276        message.setName( this.getClass().getSimpleName() );
277        message.setTemplate( new Texts() );
278        message.getTemplate().setDefaultLanguage( "en" );
279
280        final Text text = new Text();
281        text.setLanguage( "en" );
282        message.getTemplate().getText().add( text );
283
284        message.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
285        message.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
286        message.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
287        message.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
288        message.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
289        message.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
290        message.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
291        message.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
292        message.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
293        message.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
294
295        implementation.getDependencies().getDependency().add( dependency );
296        implementation.getMessages().getMessage().add( message );
297
298        module.getImplementations().getImplementation().add( implementation );
299        module.getMessages().getMessage().add( message );
300        module.getSpecifications().getSpecification().add( specification );
301
302        final Specification deprecatedSpecification = new Specification();
303        deprecatedSpecification.setIdentifier( this.getClass().getSimpleName() + " 2" );
304        deprecatedSpecification.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
305
306        final Implementation deprecatedImplementation = new Implementation();
307        deprecatedImplementation.setIdentifier( this.getClass().getSimpleName() + " 2" );
308        deprecatedImplementation.setName( this.getClass().getSimpleName() );
309        deprecatedImplementation.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
310
311        module.getSpecifications().getSpecification().add( deprecatedSpecification );
312        module.getImplementations().getImplementation().add( deprecatedImplementation );
313
314        final JAXBSource jaxbSource = new JAXBSource( modelContext.createMarshaller(
315            ModelObject.MODEL_PUBLIC_ID ), new org.jomc.modlet.ObjectFactory().createModel( model ) );
316
317        report = modelContext.validateModel( ModelObject.MODEL_PUBLIC_ID, jaxbSource );
318        assertValidModel( report );
319
320        report = this.getModelValidator().validateModel( modelContext, model );
321        assertInvalidModel( report );
322        assertModelValidationReportDetail( report, "MODEL_SOURCE_FILE_CONSTRAINT", 6 );
323        assertModelValidationReportDetail( report, "MODEL_SOURCE_FILES_CONSTRAINT", 1 );
324        assertModelValidationReportDetail( report, "MODEL_SOURCE_SECTION_CONSTRAINT", 6 );
325        assertModelValidationReportDetail( report, "MODEL_SOURCE_SECTIONS_CONSTRAINT", 1 );
326        assertModelValidationReportDetail( report, "MODULE_SOURCE_FILE_CONSTRAINT", 6 );
327        assertModelValidationReportDetail( report, "MODULE_SOURCE_FILES_CONSTRAINT", 1 );
328        assertModelValidationReportDetail( report, "MODULE_SOURCE_SECTION_CONSTRAINT", 6 );
329        assertModelValidationReportDetail( report, "MODULE_SOURCE_SECTIONS_CONSTRAINT", 1 );
330        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_FILE_MULTIPLICITY_CONSTRAINT", 1 );
331        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_FILES_MULTIPLICITY_CONSTRAINT", 1 );
332        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_SECTION_CONSTRAINT", 6 );
333        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_SECTIONS_CONSTRAINT", 1 );
334        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_FILE_INFORMATION", 1 );
335        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_FILE_CONSTRAINT", 6 );
336        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_FILES_CONSTRAINT", 1 );
337        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_SECTION_CONSTRAINT", 6 );
338        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_SECTIONS_CONSTRAINT", 1 );
339        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_FILE_CONSTRAINT", 6 );
340        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_FILES_CONSTRAINT", 1 );
341        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_SECTION_CONSTRAINT", 6 );
342        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_SECTIONS_CONSTRAINT", 1 );
343        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_FILE_MULTIPLICITY_CONSTRAINT", 1 );
344        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_FILES_MULTIPLICITY_CONSTRAINT", 1 );
345        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_SECTION_CONSTRAINT", 6 );
346        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_SECTIONS_CONSTRAINT", 1 );
347        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_FILE_INFORMATION", 1 );
348        assertModelValidationReportDetail( report, "MODEL_SOURCE_FILE_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT", 6 );
349        assertModelValidationReportDetail( report, "MODEL_SOURCE_FILE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
350                                           24 );
351
352        assertModelValidationReportDetail( report, "MODEL_SOURCE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
353                                           12 );
354
355        assertModelValidationReportDetail( report, "MODULE_SOURCE_FILE_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT", 6 );
356
357        assertModelValidationReportDetail( report,
358                                           "MODULE_SOURCE_FILE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
359                                           24 );
360
361        assertModelValidationReportDetail( report, "MODULE_SOURCE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
362                                           12 );
363
364        assertModelValidationReportDetail( report,
365                                           "IMPLEMENTATION_SOURCE_FILE_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
366                                           7 );
367
368        assertModelValidationReportDetail( report,
369                                           "IMPLEMENTATION_SOURCE_FILE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
370                                           28 );
371
372        assertModelValidationReportDetail( report,
373                                           "IMPLEMENTATION_SOURCE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
374                                           12 );
375
376        assertModelValidationReportDetail( report,
377                                           "IMPLEMENTATION_DEPENDENCY_SOURCE_FILE_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
378                                           6 );
379
380        assertModelValidationReportDetail( report,
381                                           "IMPLEMENTATION_DEPENDENCY_SOURCE_FILE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
382                                           24 );
383
384        assertModelValidationReportDetail( report,
385                                           "IMPLEMENTATION_DEPENDENCY_SOURCE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
386                                           12 );
387
388        assertModelValidationReportDetail( report,
389                                           "IMPLEMENTATION_MESSAGE_SOURCE_FILE_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
390                                           6 );
391
392        assertModelValidationReportDetail( report,
393                                           "IMPLEMENTATION_MESSAGE_SOURCE_FILE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
394                                           24 );
395
396        assertModelValidationReportDetail( report,
397                                           "IMPLEMENTATION_MESSAGE_SOURCE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
398                                           12 );
399
400        assertModelValidationReportDetail( report,
401                                           "SPECIFICATION_SOURCE_FILE_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
402                                           7 );
403
404        assertModelValidationReportDetail( report,
405                                           "SPECIFICATION_SOURCE_FILE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
406                                           28 );
407
408        assertModelValidationReportDetail( report,
409                                           "SPECIFICATION_SOURCE_SECTION_TEMPLATE_PARAMETER_JAVA_VALUE_CONSTRAINT",
410                                           12 );
411    }
412
413    private static void assertValidModel( final ModelValidationReport report )
414    {
415        assertNotNull( report );
416
417        if ( !report.isModelValid() )
418        {
419            System.out.println( ">>>Unexpected invalid model:" );
420            logModelValidationReport( report );
421            fail( report.toString() );
422        }
423        else
424        {
425            System.out.println( ">>>Valid model:" );
426            logModelValidationReport( report );
427        }
428    }
429
430    private static void assertInvalidModel( final ModelValidationReport report )
431    {
432        assertNotNull( report );
433
434        if ( report.isModelValid() )
435        {
436            System.out.println( ">>>Unexpected valid model:" );
437            logModelValidationReport( report );
438            fail( report.toString() );
439        }
440        else
441        {
442            System.out.println( ">>>Invalid model:" );
443            logModelValidationReport( report );
444        }
445    }
446
447    private static void assertModelValidationReportDetail( final ModelValidationReport report, final String identifier,
448                                                           final int count )
449    {
450        final List<ModelValidationReport.Detail> details = report.getDetails( identifier );
451
452        if ( details.size() != count )
453        {
454            System.out.println( ">>>Unexpected number of '" + identifier + "' details. Expected " + count + " - found "
455                                    + details.size() + "." );
456
457            logModelValidationReport( report );
458            fail( report.toString() );
459        }
460    }
461
462    private static void logModelValidationReport( final ModelValidationReport report )
463    {
464        for ( ModelValidationReport.Detail d : report.getDetails() )
465        {
466            System.out.println( "\t" + d );
467        }
468    }
469
470}