--- /dev/null
+/*
+ * Web IDE - Command Line Interface
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Taeyoung Son <taeyoung2.son@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.cli.exec.web.build;
+
+import static org.tizen.cli.exec.LaunchOptionConstants.DESC_OVERWRITE;
+import static org.tizen.cli.exec.LaunchOptionConstants.OPT_OVERWRITE;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.tizen.cli.exec.AbstractLauncher;
+import org.tizen.cli.exec.Help;
+import org.tizen.common.builder.BuildProcess;
+import org.tizen.common.builder.Resource;
+import org.tizen.common.builder.ResourceLayer;
+import org.tizen.common.builder.core.FSBuilder;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.core.command.zip.ZipCommand;
+import org.tizen.common.file.FileHandler;
+import org.tizen.common.file.FileHandler.Attribute;
+import org.tizen.common.file.VirtualFileHandler;
+import org.tizen.common.util.FileUtil;
+import org.tizen.common.util.FilenameUtil;
+import org.tizen.web.builder.JavaScriptMinifier;
+
+/**
+ * Command Line Interface for optimization of web resources
+ *
+ * @author Taeyoung Son{@literal <taeyoung2.son@samsung.com>} (S-Core)
+ */
+public class
+Main
+extends AbstractLauncher
+{
+ private String dest="opt";
+
+ private static final String OPT_NAME_DEST = "minify";
+ private static final String OPT_DESC_DEST = "Minify resources(js | css)";
+
+ //for build framework(org.tizen.common.builder)
+ protected static final String RESOURCE_LAYER_MINIFY = "minify";
+ protected static final String RESOURCE_LAYER_MINIFY_JS = RESOURCE_LAYER_MINIFY+".js";
+ protected static final String RESOURCE_LAYER_START = "start";
+ protected static final String RESOURCE_LAYER_OPTIMIZE = "optimize";
+ protected static final String RESOURCE_LAYER_END = "end";
+
+ private static final String RESOURCE_LAYER_EXTRACT_TO_FS = null;
+
+
+ /**
+ * Entry point for cli main
+ *
+ * @param args user input parameter
+ *
+ * @throws Exception If unhandled exception occur
+ */
+ public static
+ void
+ main(
+ final String[] args
+ )
+ throws Exception
+ {
+ final Main instance = new Main();
+ instance.run( args );
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.cli.exec.AbstractLauncher#getOptions()
+ */
+ @Override
+ @SuppressWarnings("static-access")
+ protected
+ Options
+ getOptions()
+ {
+ final Options opts = super.getOptions();
+ opts.addOption( OptionBuilder.withLongOpt( OPT_OVERWRITE ).withDescription( DESC_OVERWRITE ).create( OPT_OVERWRITE.substring( 0, 1 ) ) );
+ opts.addOption( OptionBuilder.hasArg().withLongOpt( OPT_NAME_DEST ).withDescription( OPT_DESC_DEST ).create( OPT_NAME_DEST.substring( 0, 1 ) ) );
+ return opts;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.cli.exec.AbstractLauncher#execute(org.apache.commons.cli.CommandLine)
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ protected
+ void
+ execute(
+ final CommandLine cmdLine
+ )
+ throws Exception
+ {
+ final List<String> args = cmdLine.getArgList();
+ logger.trace( "arguments :{}", args );
+
+ int nArgs = args.size();
+
+ String baseDir = convertPath( "." );
+ if ( 1 < nArgs )
+ {
+ baseDir = convertPath( args.get( 1 ) );
+ }
+ logger.debug( "Base directory :{}", baseDir );
+
+ if (cmdLine.hasOption(OPT_NAME_DEST)) {
+ dest = cmdLine.getOptionValue( OPT_NAME_DEST );
+ }
+
+ logger.debug( "Output directory :{}", dest );
+
+ if ( cmdLine.hasOption( OPT_OVERWRITE ) )
+ {
+ if (exists(dest)) {
+ FileUtil.recursiveDelete(new File(dest));
+ logger.info( dest + "directory was deleted." );
+ } else {
+ logger.info( dest + "directory does not exist" );
+ }
+ } else if (exists(dest)) {
+ getPrompter().notify(dest + "directory already exist.");
+ return;
+ }
+
+ BuildProcess buildProcess = new BuildProcess();
+ ResourceLayer startLayer = new ResourceLayer("start", new VirtualFileHandler());
+
+ addOptimizingBuilders(buildProcess, startLayer);
+ addLastbuilder(buildProcess
+ , buildProcess.getLastBuilder().getResourceLayer());
+
+ Resource[] resources = getResources(baseDir, startLayer);
+
+ if (buildProcess.getLastBuilder() != null) {
+ logger.debug("start build process");
+ buildProcess.build(resources);
+ }
+ }
+
+ private void addLastbuilder(BuildProcess buildProcess, ResourceLayer resourceLayer) {
+ // add file output builder
+ ResourceLayer toFSLayer = new ResourceLayer(RESOURCE_LAYER_EXTRACT_TO_FS
+ , resourceLayer
+ , getFileHandler());
+ FSBuilder toFSBuilder = new FSBuilder(toFSLayer);
+ buildProcess.addBuilder(toFSBuilder);
+ }
+
+ private Resource[] getResources(String baseDir, ResourceLayer resourceLayer) throws IOException {
+ List<File> files = FileUtil.findFiles(new File(baseDir), ".*", true);
+ List<Resource> resources = new ArrayList<Resource>();
+ FileHandler fh = resourceLayer.getFileHandler();
+
+ for (File file : files) {
+ String filePath = file.getPath();
+ Resource resource = new Resource(resourceLayer, filePath);
+
+ String dir = null;
+ if (file.isFile()) {
+ dir = file.getParent();
+ } else {
+ dir = filePath;
+ }
+
+ if (fh instanceof VirtualFileHandler) {
+ ((VirtualFileHandler) fh).makeDirectory(dir, true);
+ }
+
+ resource.setContents(new FileInputStream(file));
+ resources.add(resource);
+ }
+ return resources.toArray(new Resource[resources.size()]);
+ }
+
+ /**
+ * Archive <code>baseDir</code> to <code>wgtPath</code> including
+ * <code>includes</code> and excluding <code>excludes</code>
+ *
+ * @param wgtPath wgt file path
+ * @param baseDir directory to root
+ * @param includes includes file pattern
+ * @param excludes excludes file pattern
+ */
+ private void zipFiles(final String wgtPath, final String baseDir, final Resource[] resources) {
+ final ZipCommand command = new ZipCommand(baseDir, resources, wgtPath);
+
+ final Executor executor = getExecutor();
+ executor.execute(command);
+ }
+
+ private void addOptimizingBuilders(BuildProcess buildProcess, ResourceLayer parentLayer ) {
+ if (buildProcess == null) {
+ return;
+ }
+ /*
+ * 1. optimization builder
+ */
+ ResourceLayer optimizeLayer = new ResourceLayer(RESOURCE_LAYER_OPTIMIZE, parentLayer, parentLayer.getFileHandler());
+ ResourceLayer minifyLayer = new ResourceLayer(RESOURCE_LAYER_MINIFY, optimizeLayer, parentLayer.getFileHandler());
+
+ // add js minify builder
+ ResourceLayer jsMinLayer = new ResourceLayer(RESOURCE_LAYER_MINIFY_JS, minifyLayer, parentLayer.getFileHandler());
+ JavaScriptMinifier jsMin = new JavaScriptMinifier(jsMinLayer);
+ buildProcess.addBuilder(jsMin);
+ }
+
+ /**
+ * Check if <code>path</code> exists
+ *
+ * @param path file path
+ *
+ * @return <code>true</code> if <code>path</code> exists
+ *
+ * @throws IOException If <code>path</code> can't be accessed
+ */
+ protected
+ boolean
+ exists(
+ final String path
+ )
+ throws IOException
+ {
+ return getFileHandler().is( path, Attribute.EXISTS );
+ }
+
+ /**
+ * Check if <code>path</code> is Tizen web project root
+ *
+ * @param path directory path to check
+ *
+ * @return <code>true</code> if <code>path</code> is Tize web project root
+ * @throws IOException If <code>path</code>'s sub files can't be accessed
+ */
+ protected
+ boolean
+ isValidRoot(
+ final String path
+ )
+ throws IOException
+ {
+ final FileHandler fileHandler = getFileHandler();
+ final String projectFilePath = FilenameUtil.addTailingPath( path, ".project" );
+ return fileHandler.is( projectFilePath, Attribute.EXISTS );
+ }
+
+ /**
+ * Return default excludes file patterns
+ *
+ * @return default excludes file patterns
+ */
+ protected
+ String[] getDefaultExcludes()
+ {
+ return new String[] { ".*", "*.wgt" };
+ }
+
+ /**
+ * Archive <code>baseDir</code> to <code>wgtPath</code>
+ *
+ * including <code>includes</code> and excluding <code>excludes</code>
+ *
+ * @param wgtPath wgt file path
+ * @param baseDir directory to root
+ * @param includes includes file pattern
+ * @param excludes excludes file pattern
+ */
+ protected
+ void
+ zipFiles(
+ final String wgtPath,
+ final String baseDir
+ )
+ {
+ zipFiles(wgtPath, baseDir, null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.cli.exec.AbstractLauncher#createHelp()
+ */
+ @Override
+ protected Help createHelp() {
+ Help help = super.createHelp();
+
+ help.setSyntax( help.getSyntax() + getSyntax() );
+ return help;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.cli.exec.AbstractLauncher#getSyntax()
+ */
+ @Override
+ protected
+ String
+ getSyntax()
+ {
+ return " [options]";
+ }
+}