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 4704 2013-01-02 05:15:52Z 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.modlet.ToolsModelValidator;
059import org.junit.Test;
060import static org.junit.Assert.assertNotNull;
061import static org.junit.Assert.assertTrue;
062import static org.junit.Assert.fail;
063
064/**
065 * Test cases for class {@code org.jomc.tools.modlet.ToolsModelValidator}.
066 *
067 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 1.0
068 * @version $JOMC: ToolsModelValidatorTest.java 4704 2013-01-02 05:15:52Z schulte $
069 */
070public class ToolsModelValidatorTest
071{
072
073    /** The {@code ToolsModelValidator} instance tests are performed with. */
074    private ToolsModelValidator toolsModelValidator;
075
076    /** Creates a new {@code ToolsModelValidatorTest} instance. */
077    public ToolsModelValidatorTest()
078    {
079        super();
080    }
081
082    /**
083     * Gets the {@code ToolsModelValidator} instance tests are performed with.
084     *
085     * @return The {@code ToolsModelValidator} instance tests are performed with.
086     *
087     * @see #newModelValidator()
088     */
089    public ToolsModelValidator getModelValidator()
090    {
091        if ( this.toolsModelValidator == null )
092        {
093            this.toolsModelValidator = this.newModelValidator();
094        }
095
096        return this.toolsModelValidator;
097    }
098
099    /**
100     * Create a new {@code ToolsModelValidator} instance to test.
101     *
102     * @return A new {@code ToolsModelValidator} instance to test.
103     *
104     * @see #getModelValidator()
105     */
106    protected ToolsModelValidator newModelValidator()
107    {
108        return new ToolsModelValidator();
109    }
110
111    @Test
112    public final void testValidateModel() throws Exception
113    {
114        final ModelContext modelContext = ModelContextFactory.newInstance().newModelContext();
115
116        try
117        {
118            this.getModelValidator().validateModel( modelContext, null );
119            fail( "Expected NullPointerException not thrown." );
120        }
121        catch ( final NullPointerException e )
122        {
123            assertNotNull( e.getMessage() );
124            System.out.println( e.toString() );
125        }
126
127        try
128        {
129            this.getModelValidator().validateModel( null, new Model() );
130            fail( "Expected NullPointerException not thrown." );
131        }
132        catch ( final NullPointerException e )
133        {
134            assertNotNull( e.getMessage() );
135            System.out.println( e.toString() );
136        }
137
138        ModelValidationReport report = this.getModelValidator().validateModel( modelContext, new Model() );
139        assertNotNull( report );
140        assertTrue( report.isModelValid() );
141
142        final Model model = new Model();
143        model.setIdentifier( ModelObject.MODEL_PUBLIC_ID );
144
145        final SourceFileType sourceFile1 = new SourceFileType();
146        sourceFile1.setIdentifier( this.getClass().getSimpleName() + " 1" );
147
148        final SourceFileType sourceFile2 = new SourceFileType();
149        sourceFile2.setIdentifier( this.getClass().getSimpleName() + " 2" );
150
151        final SourceFilesType sourceFiles1 = new SourceFilesType();
152        sourceFiles1.getSourceFile().add( sourceFile1 );
153        sourceFiles1.getSourceFile().add( sourceFile2 );
154
155        final SourceFilesType sourceFiles2 = new SourceFilesType();
156        sourceFiles2.getSourceFile().add( sourceFile1 );
157        sourceFiles2.getSourceFile().add( sourceFile2 );
158
159        final SourceSectionType sourceSection1 = new SourceSectionType();
160        sourceSection1.setName( this.getClass().getSimpleName() + " 1" );
161
162        final SourceSectionType sourceSection2 = new SourceSectionType();
163        sourceSection2.setName( this.getClass().getSimpleName() + " 2" );
164
165        final SourceSectionsType sourceSections1 = new SourceSectionsType();
166        sourceSections1.getSourceSection().add( sourceSection1 );
167        sourceSections1.getSourceSection().add( sourceSection2 );
168
169        final SourceSectionsType sourceSections2 = new SourceSectionsType();
170        sourceSections2.getSourceSection().add( sourceSection1 );
171        sourceSections2.getSourceSection().add( sourceSection2 );
172
173        model.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
174        model.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
175        model.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
176        model.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
177        model.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
178        model.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
179        model.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
180        model.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
181        model.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
182        model.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
183
184        final Modules modules = new Modules();
185        ModelHelper.setModules( model, modules );
186
187        final Module module = new Module();
188        modules.getModule().add( module );
189        module.setSpecifications( new Specifications() );
190        module.setImplementations( new Implementations() );
191        module.setName( this.getClass().getSimpleName() );
192
193        module.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
194        module.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
195        module.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
196        module.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
197        module.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
198        module.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
199        module.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
200        module.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
201        module.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
202        module.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
203        module.setMessages( new Messages() );
204
205        final Specification specification = new Specification();
206        specification.setIdentifier( this.getClass().getSimpleName() );
207        specification.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
208        specification.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
209        specification.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
210        specification.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
211        specification.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
212        specification.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
213        specification.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
214        specification.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
215        specification.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
216        specification.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
217
218        final Implementation implementation = new Implementation();
219        implementation.setIdentifier( this.getClass().getSimpleName() );
220        implementation.setName( this.getClass().getSimpleName() );
221        implementation.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
222        implementation.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
223        implementation.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
224        implementation.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
225        implementation.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
226        implementation.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
227        implementation.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
228        implementation.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
229        implementation.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
230        implementation.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
231
232        implementation.setDependencies( new Dependencies() );
233        implementation.setMessages( new Messages() );
234
235        final Dependency dependency = new Dependency();
236        dependency.setName( this.getClass().getSimpleName() );
237        dependency.setIdentifier( this.getClass().getSimpleName() );
238        dependency.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
239        dependency.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
240        dependency.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
241        dependency.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
242        dependency.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
243        dependency.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
244        dependency.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
245        dependency.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
246        dependency.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
247        dependency.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
248
249        final Message message = new Message();
250        message.setName( this.getClass().getSimpleName() );
251        message.setTemplate( new Texts() );
252        message.getTemplate().setDefaultLanguage( "en" );
253
254        final Text text = new Text();
255        text.setLanguage( "en" );
256        message.getTemplate().getText().add( text );
257
258        message.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
259        message.getAny().add( new ObjectFactory().createSourceFile( sourceFile2 ) );
260        message.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles1 ) );
261        message.getAny().add( new ObjectFactory().createSourceFiles( sourceFiles2 ) );
262        message.getAny().add( new ObjectFactory().createSourceFiles( new SourceFilesType() ) );
263        message.getAny().add( new ObjectFactory().createSourceSection( sourceSection1 ) );
264        message.getAny().add( new ObjectFactory().createSourceSection( sourceSection2 ) );
265        message.getAny().add( new ObjectFactory().createSourceSections( sourceSections1 ) );
266        message.getAny().add( new ObjectFactory().createSourceSections( sourceSections2 ) );
267        message.getAny().add( new ObjectFactory().createSourceSections( new SourceSectionsType() ) );
268
269        implementation.getDependencies().getDependency().add( dependency );
270        implementation.getMessages().getMessage().add( message );
271
272        module.getImplementations().getImplementation().add( implementation );
273        module.getMessages().getMessage().add( message );
274        module.getSpecifications().getSpecification().add( specification );
275
276        final Specification deprecatedSpecification = new Specification();
277        deprecatedSpecification.setIdentifier( this.getClass().getSimpleName() + " 2" );
278        deprecatedSpecification.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
279
280        final Implementation deprecatedImplementation = new Implementation();
281        deprecatedImplementation.setIdentifier( this.getClass().getSimpleName() + " 2" );
282        deprecatedImplementation.setName( this.getClass().getSimpleName() );
283        deprecatedImplementation.getAny().add( new ObjectFactory().createSourceFile( sourceFile1 ) );
284
285        module.getSpecifications().getSpecification().add( deprecatedSpecification );
286        module.getImplementations().getImplementation().add( deprecatedImplementation );
287
288        final JAXBSource jaxbSource = new JAXBSource( modelContext.createMarshaller(
289            ModelObject.MODEL_PUBLIC_ID ), new org.jomc.modlet.ObjectFactory().createModel( model ) );
290
291        report = modelContext.validateModel( ModelObject.MODEL_PUBLIC_ID, jaxbSource );
292        assertValidModel( report );
293
294        report = this.getModelValidator().validateModel( modelContext, model );
295        assertInvalidModel( report );
296        assertModelValidationReportDetail( report, "MODEL_SOURCE_FILE_CONSTRAINT", 6 );
297        assertModelValidationReportDetail( report, "MODEL_SOURCE_FILES_CONSTRAINT", 1 );
298        assertModelValidationReportDetail( report, "MODEL_SOURCE_SECTION_CONSTRAINT", 6 );
299        assertModelValidationReportDetail( report, "MODEL_SOURCE_SECTIONS_CONSTRAINT", 1 );
300        assertModelValidationReportDetail( report, "MODULE_SOURCE_FILE_CONSTRAINT", 6 );
301        assertModelValidationReportDetail( report, "MODULE_SOURCE_FILES_CONSTRAINT", 1 );
302        assertModelValidationReportDetail( report, "MODULE_SOURCE_SECTION_CONSTRAINT", 6 );
303        assertModelValidationReportDetail( report, "MODULE_SOURCE_SECTIONS_CONSTRAINT", 1 );
304        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_FILE_MULTIPLICITY_CONSTRAINT", 1 );
305        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_FILES_MULTIPLICITY_CONSTRAINT", 1 );
306        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_SECTION_CONSTRAINT", 6 );
307        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_SECTIONS_CONSTRAINT", 1 );
308        assertModelValidationReportDetail( report, "IMPLEMENTATION_SOURCE_FILE_INFORMATION", 1 );
309        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_FILE_CONSTRAINT", 6 );
310        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_FILES_CONSTRAINT", 1 );
311        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_SECTION_CONSTRAINT", 6 );
312        assertModelValidationReportDetail( report, "IMPLEMENTATION_DEPENDENCY_SOURCE_SECTIONS_CONSTRAINT", 1 );
313        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_FILE_CONSTRAINT", 6 );
314        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_FILES_CONSTRAINT", 1 );
315        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_SECTION_CONSTRAINT", 6 );
316        assertModelValidationReportDetail( report, "IMPLEMENTATION_MESSAGE_SOURCE_SECTIONS_CONSTRAINT", 1 );
317        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_FILE_MULTIPLICITY_CONSTRAINT", 1 );
318        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_FILES_MULTIPLICITY_CONSTRAINT", 1 );
319        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_SECTION_CONSTRAINT", 6 );
320        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_SECTIONS_CONSTRAINT", 1 );
321        assertModelValidationReportDetail( report, "SPECIFICATION_SOURCE_FILE_INFORMATION", 1 );
322    }
323
324    private static void assertValidModel( final ModelValidationReport report )
325    {
326        assertNotNull( report );
327
328        if ( !report.isModelValid() )
329        {
330            System.out.println( ">>>Unexpected invalid model:" );
331            logModelValidationReport( report );
332            fail( report.toString() );
333        }
334        else
335        {
336            System.out.println( ">>>Valid model:" );
337            logModelValidationReport( report );
338        }
339    }
340
341    private static void assertInvalidModel( final ModelValidationReport report )
342    {
343        assertNotNull( report );
344
345        if ( report.isModelValid() )
346        {
347            System.out.println( ">>>Unexpected valid model:" );
348            logModelValidationReport( report );
349            fail( report.toString() );
350        }
351        else
352        {
353            System.out.println( ">>>Invalid model:" );
354            logModelValidationReport( report );
355        }
356    }
357
358    private static void assertModelValidationReportDetail( final ModelValidationReport report, final String identifier,
359                                                           final Number count )
360    {
361        final List<ModelValidationReport.Detail> details = report.getDetails( identifier );
362
363        if ( details.size() != count )
364        {
365            System.out.println( ">>>Unexpected number of '" + identifier + "' details. Expected " + count + " - found "
366                                + details.size() + "." );
367
368            logModelValidationReport( report );
369            fail( report.toString() );
370        }
371    }
372
373    private static void logModelValidationReport( final ModelValidationReport report )
374    {
375        for ( ModelValidationReport.Detail d : report.getDetails() )
376        {
377            System.out.println( "\t" + d );
378        }
379    }
380
381}