001/*
002 * Copyright (C) 2009 Christian Schulte <cs@schulte.it>
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: ValidateClassesCommand.java 5251 2016-04-25 19:46:04Z schulte $
029 *
030 */
031package org.jomc.cli.commands;
032
033import java.io.IOException;
034import java.util.Locale;
035import java.util.logging.Level;
036import javax.xml.bind.JAXBContext;
037import javax.xml.bind.JAXBException;
038import javax.xml.bind.Marshaller;
039import javax.xml.bind.util.JAXBSource;
040import javax.xml.transform.Source;
041import org.apache.commons.cli.CommandLine;
042import org.jomc.model.Implementation;
043import org.jomc.model.Module;
044import org.jomc.model.Specification;
045import org.jomc.modlet.Model;
046import org.jomc.modlet.ModelContext;
047import org.jomc.modlet.ModelException;
048import org.jomc.modlet.ModelValidationReport;
049import org.jomc.modlet.ObjectFactory;
050import org.jomc.tools.ClassFileProcessor;
051
052/**
053 * {@code validate-classes} command implementation.
054 *
055 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
056 */
057public final class ValidateClassesCommand extends AbstractClassFileProcessorCommand
058{
059
060    /**
061     * Creates a new {@code ValidateClassesCommand} instance.
062     */
063    public ValidateClassesCommand()
064    {
065        super();
066    }
067
068    public String getName()
069    {
070        return "validate-classes";
071    }
072
073    public String getAbbreviatedName()
074    {
075        return "vc";
076    }
077
078    public String getShortDescription( final Locale locale )
079    {
080        return Messages.getMessage( "validateClassesShortDescription" );
081    }
082
083    public String getLongDescription( final Locale locale )
084    {
085        return null;
086    }
087
088    protected void processClassFiles( final CommandLine commandLine ) throws CommandExecutionException
089    {
090        if ( commandLine == null )
091        {
092            throw new NullPointerException( "commandLine" );
093        }
094
095        CommandLineClassLoader classLoader = null;
096
097        try
098        {
099            classLoader = new CommandLineClassLoader( commandLine );
100            final ModelContext context = this.createModelContext( commandLine, classLoader );
101            final Model model = this.getModel( context, commandLine );
102            final JAXBContext jaxbContext = context.createContext( model.getIdentifier() );
103            final Marshaller marshaller = context.createMarshaller( model.getIdentifier() );
104            final Source source = new JAXBSource( jaxbContext, new ObjectFactory().createModel( model ) );
105            ModelValidationReport validationReport = context.validateModel( model.getIdentifier(), source );
106            this.log( validationReport, marshaller );
107
108            if ( !validationReport.isModelValid() )
109            {
110                throw new CommandExecutionException( Messages.getMessage( "invalidModel",
111                                                                          this.getModel( commandLine ) ) );
112
113            }
114
115            final ClassFileProcessor tool = this.createClassFileProcessor( commandLine );
116            tool.setModel( model );
117
118            final Specification specification = this.getSpecification( commandLine, model );
119            final Implementation implementation = this.getImplementation( commandLine, model );
120            final Module module = this.getModule( commandLine, model );
121
122            if ( specification != null )
123            {
124                validationReport = tool.validateModelObjects( specification, context );
125
126                if ( validationReport != null )
127                {
128                    this.log( validationReport, marshaller );
129
130                    if ( !validationReport.isModelValid() )
131                    {
132                        throw new CommandExecutionException( Messages.getMessage( "invalidClasses" ) );
133                    }
134                }
135            }
136
137            if ( implementation != null )
138            {
139                validationReport = tool.validateModelObjects( implementation, context );
140
141                if ( validationReport != null )
142                {
143                    this.log( validationReport, marshaller );
144
145                    if ( !validationReport.isModelValid() )
146                    {
147                        throw new CommandExecutionException( Messages.getMessage( "invalidClasses" ) );
148                    }
149                }
150            }
151
152            if ( module != null )
153            {
154                validationReport = tool.validateModelObjects( module, context );
155
156                if ( validationReport != null )
157                {
158                    this.log( validationReport, marshaller );
159
160                    if ( !validationReport.isModelValid() )
161                    {
162                        throw new CommandExecutionException( Messages.getMessage( "invalidClasses" ) );
163                    }
164                }
165            }
166
167            if ( this.isModulesProcessingRequested( commandLine ) )
168            {
169                validationReport = tool.validateModelObjects( context );
170
171                if ( validationReport != null )
172                {
173                    this.log( validationReport, marshaller );
174
175                    if ( !validationReport.isModelValid() )
176                    {
177                        throw new CommandExecutionException( Messages.getMessage( "invalidClasses" ) );
178                    }
179                }
180            }
181
182            classLoader.close();
183            classLoader = null;
184        }
185        catch ( final JAXBException e )
186        {
187            String message = Messages.getMessage( e );
188            if ( message == null )
189            {
190                message = Messages.getMessage( e.getLinkedException() );
191            }
192
193            throw new CommandExecutionException( message, e );
194        }
195        catch ( final ModelException e )
196        {
197            throw new CommandExecutionException( Messages.getMessage( e ), e );
198        }
199        catch ( final IOException e )
200        {
201            throw new CommandExecutionException( Messages.getMessage( e ), e );
202        }
203        finally
204        {
205            try
206            {
207                if ( classLoader != null )
208                {
209                    classLoader.close();
210                }
211            }
212            catch ( final IOException e )
213            {
214                this.log( Level.SEVERE, Messages.getMessage( e ), e );
215            }
216        }
217    }
218
219}