Package net.rim.tumbler

Source Code of net.rim.tumbler.WidgetPackager

/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.rim.tumbler;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import net.rim.tumbler.config.WidgetConfig;
import net.rim.tumbler.exception.CommandLineException;
import net.rim.tumbler.exception.PackageException;
import net.rim.tumbler.exception.ValidationException;
import net.rim.tumbler.file.FileManager;
import net.rim.tumbler.log.LogType;
import net.rim.tumbler.log.Logger;
import net.rim.tumbler.rapc.Rapc;
import net.rim.tumbler.serialize.WidgetConfigSerializer;
import net.rim.tumbler.serialize.WidgetConfig_v1Serializer;
import net.rim.tumbler.session.BBWPProperties;
import net.rim.tumbler.session.SessionManager;
import net.rim.tumbler.xml.ConfigXMLParser;
import net.rim.tumbler.xml.XMLParser;

public class WidgetPackager {

    public static final String[] STANDARD_OUTPUTS = new String[] { ".cod", ".alx", ".cso", ".csl" };
    public static final String[] OTA_OUTPUTS = new String[] { ".cod", ".jad" };

    // TODO: retrieve from logger
    public static final String BLACKBERRY_WIDGET_PORTAL_URL = "http://www.blackberry.com/developers/webworkssdk/";
    public static final String PROPERTIES_FILE = "bbwp.properties";
    public static final String SIGNATURE_KEY_FILE = "sigtool.csk";

    private static final String AUTOGEN_FILE = "blackberry/web/widget/autogen/WidgetConfigAutoGen.java";

    private static final int NO_ERROR_RETURN_CODE = 0;
    private static final int PACKAGE_ERROR_RCODE = 1;
    private static final int VALIDATION_ERROR_RCODE = 2;
    private static final int RUNTIME_ERROR_RCODE = 3;
    private static final int UNEXPECTED_ERROR_RCODE = 4;
    private static final int COMMAND_LINE_EXCEPTION = 5;

    public static void main( String[] args ) {
        WidgetPackager wp = new WidgetPackager();
        int returnCode = wp.go( args );
        System.exit( returnCode );
    }

    public int go( String[] args ) {
        Logger.logMessage( LogType.INFO, "PROGRESS_CMDLINE_OPTIONS" );
        int returnCode = NO_ERROR_RETURN_CODE;

        try {
            CmdLineHandler cmd = new CmdLineHandler();
            if( !cmd.parse( args ) ) {
                // nothing to package
                return NO_ERROR_RETURN_CODE;
            }

            // create SessionManager
            SessionManager sessionManager = cmd.createSession();

            // create bbwp.properties
            Logger.logMessage( LogType.INFO, "PROGRESS_SESSION_BBWP_PROPERTIES" );
            String propertiesFile = sessionManager.getBBWPJarFolder() + WidgetPackager.PROPERTIES_FILE;
            BBWPProperties bbwpProperties = new BBWPProperties( propertiesFile, sessionManager.getSessionHome() );

            // validate BlackBerry WebWorks application archive
            Logger.logMessage( LogType.INFO, "PROGRESS_VALIDATING_WIDGET_ARCHIVE" );
            WidgetArchive wa = new WidgetArchive( sessionManager.getWidgetArchive() );
            wa.validate();

            // parse/validate config.xml
            Logger.logMessage( LogType.INFO, "PROGRESS_SESSION_CONFIGXML" );
            XMLParser xmlparser = new ConfigXMLParser();
            WidgetConfig config = xmlparser.parseXML( wa ); // raw data, without \

            // create/clean outputs/source
            // Logger.printInfoMessage("BlackBerry WebWorks application packaging starts...");
            FileManager fileManager = new FileManager( bbwpProperties, config.getAccessTable() );
            Logger.logMessage( LogType.INFO, "PROGRESS_FILE_POPULATING_SOURCE" );
            fileManager.prepare();

            // Set 3rd party extension classes
            config.setExtensionClasses( fileManager.getExtensionClasses() );
            config.setExtensionJSFiles( fileManager.getExtensionJSFiles() );
            config.setSharedGlobalJSFiles( fileManager.getSharedGlobalJSFiles() );

            // create autogen file
            WidgetConfigSerializer wcs = new WidgetConfig_v1Serializer( config );
            byte[] autogenFile = wcs.serialize();
            fileManager.writeToSource( autogenFile, AUTOGEN_FILE );

            // create jdw/jdp files
            fileManager.generateProjectFiles( sessionManager.getSourceFolder(), sessionManager.getArchiveName(),
                    config.getName(), config.getVersion(), config.getAuthor(), config.getContent(), config.getBackgroundSource(),
                    config.isStartupEnabled(), config.getIconSrc(), config.getHoverIconSrc(), fileManager.getFiles(),
                    bbwpProperties.getImports() );

            // run rapc
            Logger.logMessage( LogType.INFO, "PROGRESS_COMPILING" );
            Rapc rapc = new Rapc( bbwpProperties, config, fileManager.getCompiledJARDependencies() );
            if( !rapc.run( fileManager.getFiles() ) ) {
                throw new PackageException( "EXCEPTION_RAPC" );
            }

            // generate ALX
            generateAlxFile( config );

            // Sign the cod if required
            if( sessionManager.requireSigning() ) {
                Logger.logMessage( LogType.INFO, "PROGRESS_SIGNING" );
                signCod( sessionManager );
                Logger.logMessage( LogType.INFO, "PROGRESS_SIGNING_COMPLETE" );
            }

            // If requires source and a safe source folder is used, copy source to where the user expects it to be
            if( sessionManager.requireSource()
                    && !sessionManager.getOriginalSourceFolder().equals( sessionManager.getSourceFolder() ) ) {
                File f = new File( SessionManager.getInstance().getOriginalSourceFolder() );
                if( !f.exists() ) {
                    if( f.mkdirs() == false ) {
                        Logger.logMessage( LogType.WARNING, "EXCEPTION_MAKING_DIRECTORY" );
                    }
                }

                ExecUtil.exec(
                        null,
                        new String[] { "cp", "-R", sessionManager.getSourceFolder() + "/",
                                sessionManager.getOriginalSourceFolder() }, null );
            }

            // clean/prep output folders
            fileManager.cleanOutput();

            // copy output files
            Logger.logMessage( LogType.INFO, "PROGRESS_GEN_OUTPUT" );
            fileManager.copyOutputsFromSource();

            // clean source (if necessary)
            if( !sessionManager.requireSource() ) {
                fileManager.cleanSource();
            }

            Logger.logMessage( LogType.INFO, "PROGRESS_COMPLETE" );
        } catch( CommandLineException cle ) {
            Logger.logMessage( LogType.ERROR, cle.getMessage(), cle.getInfo() );
            Logger.logMessage( LogType.NONE, "BBWP_USAGE", getVersion() );
            returnCode = COMMAND_LINE_EXCEPTION;
        } catch( PackageException pe ) {
            Logger.logMessage( LogType.ERROR, pe.getMessage(), pe.getInfo() );
            returnCode = PACKAGE_ERROR_RCODE;
        } catch( ValidationException ve ) {
            Logger.logMessage( LogType.ERROR, ve.getMessage(), ve.getInfo() );
            returnCode = VALIDATION_ERROR_RCODE;
        } catch( RuntimeException re ) {
            Logger.logMessage( LogType.FATAL, re );
            returnCode = RUNTIME_ERROR_RCODE;
        } catch( Exception e ) {
            Logger.logMessage( LogType.ERROR, e );
            returnCode = UNEXPECTED_ERROR_RCODE;
        }

        return returnCode;
    }

    public static Object[] getVersion() {
        return new Object[] { new WidgetPackager().getClass().getPackage().getImplementationVersion() };
    }

    private static void signCod( SessionManager sessionManager ) throws Exception {
        Process signingProcess;
        long lastModified = 0;
        String codFullname = sessionManager.getSourceFolder() + System.getProperty( "file.separator" )
                + sessionManager.getArchiveName() + ".cod";

        try {
            lastModified = ( new File( codFullname ) ).lastModified();
            String password = sessionManager.getPassword();
            File cwd = new File( sessionManager.getBBWPJarFolder() );
            String cmdline = "java -jar SignatureTool.jar -a -c " + ( password.length() == 0 ? "" : "-p " + password + " " );
            String codName = sessionManager.getSourceFolder() + System.getProperty( "file.separator" )
                    + sessionManager.getArchiveName() + ".cod";
            if( OSUtils.isWindows() ) {
                codName = "\"" + codName + "\"";
            }
            cmdline += codName;
            signingProcess = Runtime.getRuntime().exec( cmdline, null, cwd );
        } catch( IOException ex ) {
            throw ex;
        }

        try {
            int signingResult = signingProcess.waitFor();

            // Check whether signing is successful
            if( signingResult != 0 ) {
                throw new PackageException( "EXCEPTION_SIGNING_FAILED" );
            }

            long newModified = ( new File( codFullname ) ).lastModified();
            if( newModified == lastModified ) {
                throw new PackageException( "EXCEPTION_SIGNING_FAILED" );
            }
        } catch( InterruptedException e ) {
            throw e;
        }
    }

    // Generate a .alx file
    private static void generateAlxFile( WidgetConfig widgetConfig ) throws IOException {
        String EOL = System.getProperty( "line.separator" );
        String fileName = SessionManager.getInstance().getSourceFolder() + System.getProperty( "file.separator" )
                + SessionManager.getInstance().getArchiveName() + ".alx";
        BufferedWriter writer = new BufferedWriter( new FileWriter( fileName ) );
        writer.write( "<loader version=\"1.0\" >" + EOL );
        writer.write( "<application id=\"" + SessionManager.getInstance().getArchiveName() + "\">" + EOL );
        writer.write( "<name>" + widgetConfig.getName() + "</name>" + EOL );
        if( widgetConfig.getDescription() != null ) {
            writer.write( "<description>" + widgetConfig.getDescription() + "</description>" + EOL );
        }
        writer.write( "<version>" + widgetConfig.getVersion() + "</version>" + EOL );
        if( widgetConfig.getAuthor() != null ) {
            writer.write( "<vendor>" + widgetConfig.getAuthor() + "</vendor>" + EOL );
        }
        if( widgetConfig.getCopyright() != null ) {
            writer.write( "<copyright>" + widgetConfig.getCopyright() + "</copyright>" + EOL );
        }
        writer.write( "<fileset Java=\"1.45\">" + EOL );
        writer.write( "<directory>" );
        writer.write( "</directory>" + EOL );
        writer.write( "<files>" );
        writer.write( SessionManager.getInstance().getArchiveName() + ".cod" );
        writer.write( "</files>" + EOL );
        writer.write( "</fileset>" + EOL );
        writer.write( "</application>" + EOL );
        writer.write( "</loader>" + EOL );
        writer.close();
    }

}
TOP

Related Classes of net.rim.tumbler.WidgetPackager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.