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