http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/README.txt ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/README.txt b/flex-maven-tools/flex-sdk-converter/README.txt new file mode 100644 index 0000000..7f84e76 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/README.txt @@ -0,0 +1,222 @@ +Apache Flex SDK Converter +========================= + The Mavenizer tool is used to convert the Apache and Adobe Flex SDKs and Air + SDKs into Maven artifacts. Automatically creating the Directories, pom-files, + copying and moving the resources to the correct destinations. + + These artifacts can be used in Maven builds using the Flexmojos plugin + (Starting with version 6.x). + + The Apache Flex SDK Converter comes with all the means to download, convert + and deploy a mavenized form of an Apache Flex SDK. + + The Converter does not simply copy all java libraries to the destination; it checks + if the given artifact has already been deployed to maven central or by deploying an + other FDK previously. For this check you do need an internet connection to do the + conversion, otherwise it will probably take forever. + + Internally it consists of 3 components: + - One Retriever + - DownloadRetriever: For downloading binary artifacts + - Four Converters + - One for producing the Apache Flex SDK artifacts + - One for producing the Adobe Flash artifacts + - One for producing the Adobe Air artifacts + - One for producing the Adobe Fontkit artifacts + - Two Deployers + - One using Aether with no requirement to Maven (Faster, but less configurable) + - One using a local Maven installation (A lot slower, but fully configurable) + + + +Getting the latest sources via git +================================== + + Getting the source code is the recommended way to get the Apache Flex SDK + Converter. + + You can always checkout the latest source via git using the following + command: + + git clone https://git-wip-us.apache.org/repos/asf/flex-utilities.git flex-utilities + cd flex-utilities/mavenizer + git checkout develop + +Building the Apache Flex SDK Converter +====================================== + + The Apache Flex SDK Converter is a relatively simple project. It requires some + build tools which must be installed prior to building the compiler and it depends + on some external software which are downloaded as part of the build process. + Some of these have different licenses. See the Software Dependencies section + for more information on the external software dependencies. + +Install Prerequisites +--------------------- + + Before building the Apache Flex Compiler you must install the following software + and set the corresponding environment variables using absolute file paths. + Relative file paths will result in build errors. + + ================================================================================== + SOFTWARE ENVIRONMENT VARIABLE (absolute paths) + ================================================================================== + + Java SDK 1.6 or greater (*1) JAVA_HOME + + Maven 3.1.0 or greater (*1) MAVEN_HOME + + ================================================================================== + + *1) The bin directories for MAVEN_HOME and JAVA_HOME should be added to your + PATH. + + On Windows, set PATH to + + PATH=%PATH%;%MAVEN_HOME%\bin;%JAVA_HOME%\bin + + On the Mac (bash), set PATH to + + export PATH="$PATH:$MAVEN_HOME/bin:$JAVA_HOME/bin" + + On Linux make sure you path include MAVEN_HOME and JAVA_HOME. + +Software Dependencies +--------------------- + + The Apache Flex SDK Converter uses third-party code that will be downloaded as + part of the build. + + The Apache Version 2.0 license is in the LICENSE file. + + The following dependencies have licenses which are, or are compatible with, + the Apache Version 2.0 license. You will not be prompted to acknowledge the + download. Most of the jars are installed in your maven local repository and + are included in the assembly jars. + +TODO: Add them all here ... + +Building the Source in the Source Distribution +---------------------------------------------- + + The project is built with Apache Maven so for a reference to Maven commands + please have a look at the Maven documentation. + + When you have all the prerequisites in place and the environment variables + set (see Install Prerequisites above) use + + cd <mavenizer.dir> + mvn install + + to download the thirdparty dependencies and build the binary from the source. + + To clean the build, of everything other than the downloaded third-party + dependencies use + + mvn clean + + The packages can be found in the "target" subdirectories. + + The particularly interesting one is the Standalone Command Line Interface: + - cli/target/apache-flex-sdk-converter-1.0.0-SNAPSHOT.jar + + + +Using the Apache Flex SDK Converter +=================================== + + The CLI (Command Line Interface) allows the Apache Flex SDK Converter + to be executed from the command-line. Assuming the Java executable is + available on the current systems path, it can be called using: + + cd <mavenizer.dir>/cli/target + java -jar apache-flex-sdk-converter-1.0.0-SNAPSHOT.jar + + If executed without any command, it will output a list of commands and + available properties. + + In general it is able to perform 4 different commands: + + - help Prints a list of all commands and options available. + - list Lists all versions and platforms available for download + - download Downloads selected versions and assembles an FDK + - convert Converts a previously installed (using the installer) or + assembled (using download command) FDK into a mavenized form. + - deploy Uploads previously created maven artifacts to a remote repository. + +Some typical usage scenarios +---------------------------- + + - Create a mavenized version of a previously installed FDK (Using the installer): + "... -fdkDir <FDK install dir> -mavenDir <maven local repo> convert" + + - Download and create an FDK (Flex 4.14.1 with playerglobal 17.0 and 16.0 + AIR SDK 17.0 for Windows and Mac and the fontkit libs): + "... -fdkDir <FDK target dir> -flexVersion 4.14.1 -flashVersions 17.0,16.0 \ + -airVersion 17.0 -platform WINDOWS,MAC -fontkit download" + + - Download and convert an FDK (FDK assembled in temp directory using Air for + current systems platform only): + "... -flexVersion 4.14.1 -flashVersions 17.0 -airVersion 17.0 -fontkit \ + -mavenDir <maven local repo> download convert" + + - Deploy a bunch of maven artifacts to a remote maven repository: + "... -mavenDir <dir with maven artifacts> -repoUrl <url> \ + -repoUsername <username> -repoPassword <pasword> deploy" + + - "The works": Download, Convert and Deploy using only temp directories: + "... -flexVersion 4.14.1 -flashVersions 17.0 -airVersion 17.0 -fontkit \ + -repoUrl <url> -repoUsername <username> -repoPassword <pasword> \ + download convert deploy" + + +Thanks for using Apache Flex. Enjoy! + + The Apache Flex Project + <http://flex.apache.org> + + + + + +///////////////////////////////////////////////////////////////////////////////////////// +Some information (HOWTO) to go with the deployer artifacts +///////////////////////////////////////////////////////////////////////////////////////// + +The deployers are separate modules. Currently two implementations exist. +1. The Maven deployer (located in deployers/maven/target/maven-deployer-1.0.0-full.jar) +2. The Aether deployer (located in deployers/aether/target/aether-deployer-1.0.0-full.jar) + +The Maven-Deployer expects Maven to be installed on your system and issues a set of +commandline commands in order to deploy the artifacts. This is the safest approach if you +haven any special settings that need to be handled in order to deploy the artifacts. + +The Aether-Deplyoer uses the Maven-Internal aether libraries to deploy the artifacts from +within the running JVM. This makes this approach a lot faster than the Maven-Deployer. + +///////////////////////////////////////// +Usage for the Maven Deployer: +///////////////////////////////////////// + +java -cp {home}/deployers/maven/target/maven-deployer-1.0.0-full.jar "directory" "repositoryId" "url" "mvn" + +The Maven-Deployer needs 4 ordered parameters separated by spaces: + 1- directory: The path to the directory to deploy. + 2- repositoryId: Server Id to map on the <id> under <server> section of settings.xml. + 3- url: URL where the artifacts will be deployed. + 4- mvn: The path to the mvn.bat / mvn.sh. + +///////////////////////////////////////// +Usage for the Maven Deployer: +///////////////////////////////////////// + +java -cp {home}/deployers/aether/target/maven-aether-1.0.0-full.jar "directory" "url" ["username" "password] + +The Aether-Deployer needs 2 ordered parameters separated by spaces: + 1- directory: The path to the directory to deploy. + 2- url: URL where the artifacts will be deployed. +Optionally you can provide the username and password that is used for deploying artifacts. + 3- username: The username needed to log-in to the remote repository. + 4- password: The password needed to log-in to the remote repository. + +
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/RELEASE_NOTES ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/RELEASE_NOTES b/flex-maven-tools/flex-sdk-converter/RELEASE_NOTES new file mode 100644 index 0000000..d51fd96 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/RELEASE_NOTES @@ -0,0 +1,19 @@ +Apache Flex Mavenizer 1.0.0 +=========================== + +Apache Flex Mavenizer 1.0.0 is the first release of a tool allowing, automating +the conversion of Apache Flex FDKs into Maven artifacts that can be used by +FlexMojos to build Apache Flex application using Maven. + +Known Issues +_____________ + +Currently None. + + +Please report new issues to our bug tracker at: + + https://issues.apache.org/jira/browse/FLEX + + The Apache Flex Project + <http://flex.apache.org/> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/cli/pom.xml ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/cli/pom.xml b/flex-maven-tools/flex-sdk-converter/cli/pom.xml new file mode 100644 index 0000000..511ac31 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/cli/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>apache-flex-sdk-converter</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <artifactId>cli</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.4</version> + <configuration> + <archive> + <manifest> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + <addClasspath>true</addClasspath> + <mainClass>org.apache.flex.utilities.converter.core.SdkConverterCLI</mainClass> + </manifest> + <manifestEntries> + <Implementation-Build>${project.version}</Implementation-Build> + </manifestEntries> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + <finalName>apache-flex-sdk-converter-${project.version}</finalName> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>download-retriever</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>flex-converter</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>aether-deployer</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact</artifactId> + <version>3.2.3</version> + </dependency> + + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.2</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <version>1.7.7</version> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/cli/src/main/java/org/apache/flex/utilities/converter/core/SdkConverterCLI.java ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/cli/src/main/java/org/apache/flex/utilities/converter/core/SdkConverterCLI.java b/flex-maven-tools/flex-sdk-converter/cli/src/main/java/org/apache/flex/utilities/converter/core/SdkConverterCLI.java new file mode 100644 index 0000000..918dd70 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/cli/src/main/java/org/apache/flex/utilities/converter/core/SdkConverterCLI.java @@ -0,0 +1,394 @@ +package org.apache.flex.utilities.converter.core; + +import org.apache.commons.cli.*; +import org.apache.commons.io.FileUtils; +import org.apache.flex.utilities.converter.air.AirConverter; +import org.apache.flex.utilities.converter.deployer.aether.AetherDeployer; +import org.apache.flex.utilities.converter.flash.FlashConverter; +import org.apache.flex.utilities.converter.flex.FlexConverter; +import org.apache.flex.utilities.converter.fontkit.FontkitConverter; +import org.apache.flex.utilities.converter.retrievers.download.DownloadRetriever; +import org.apache.flex.utilities.converter.retrievers.types.PlatformType; +import org.apache.flex.utilities.converter.retrievers.types.SdkType; +import org.apache.flex.utilities.converter.wrapper.WrapperConverter; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * Created by christoferdutz on 07.04.15. + */ +public class SdkConverterCLI { + + public static final String COMMAND_HELP = "help"; + public static final String COMMAND_LIST = "list"; + public static final String COMMAND_DOWNLOAD = "download"; + public static final String COMMAND_CONVERT = "convert"; + public static final String COMMAND_DEPLOY = "deploy"; + + public static final String OPTION_FLEX_VERSION = "flexVersion"; + public static final String OPTION_FLASH_VERSIONS = "flashVersions"; + public static final String OPTION_AIT_VERSION = "airVersion"; + public static final String OPTION_FONTKIT = "fontkit"; + public static final String OPTION_PLATFORMS = "platforms"; + + public static final String OPTION_FDK_DIR = "fdkDir"; + public static final String OPTION_MAVEN_DIR = "mavenDir"; + + public static final String OPTION_REPO_URL = "repoUrl"; + public static final String OPTION_REPO_USERNAME = "repoUsername"; + public static final String OPTION_REPO_PASSWORD = "repoPassword"; + + + @SuppressWarnings("unchecked") + public static void main(String[] args) throws Exception { + Options options = new Options(); + options.addOption(OptionBuilder.withArgName("version").hasArg(). + withDescription("(Optional and Only valid for download) Version of the " + + "FDK which should be downloaded."). + isRequired(false). + create(OPTION_FLEX_VERSION)); + options.addOption(OptionBuilder.withArgName("version(s)").hasArg(). + withValueSeparator(','). + withDescription("(Optional and Only valid for download) Version(s) of the " + + "Adobe Flash SDK which should be downloaded. Multiple versions can " + + "be separated by \",\"."). + isRequired(false). + create(OPTION_FLASH_VERSIONS)); + options.addOption(OptionBuilder.withArgName("version").hasArg(). + withDescription("(Optional and Only valid for download) Version of the " + + "Adobe Air SDK which should be downloaded."). + isRequired(false). + create(OPTION_AIT_VERSION)); + options.addOption(OptionBuilder. + withDescription("(Optional and Only valid for download) If provided, the " + + "Converter will also download the Fontkit libraries needed for font " + + "encoding."). + isRequired(false). + create(OPTION_FONTKIT)); + options.addOption(OptionBuilder.withArgName("platform(s)").hasArg(). + withValueSeparator(','). + withDescription("(Optional and Only valid for download) Platform the artifacts " + + "should be downloaded for. If omitted the platform this process is run " + + "on will be used. Valid options are: \"WINDOWS\", \"MAC\" and \"LNX\". " + + "Multiple versions can be separated by \",\"."). + isRequired(false). + create(OPTION_PLATFORMS)); + options.addOption(OptionBuilder.withArgName("dir").hasArg(). + withDescription("(Optional) Directory that the FDK will be located in. " + + "If omitted, a temporary directory will be used."). + isRequired(false). + create(OPTION_FDK_DIR)); + options.addOption(OptionBuilder.withArgName("dir").hasArg(). + withDescription("(Optional) Directory that the mavenized artifacts will be located in. " + + "If omitted, a temporary directory will be used."). + isRequired(false). + create(OPTION_MAVEN_DIR)); + options.addOption(OptionBuilder.withArgName("url").hasArg(). + withDescription("(Optional and only valid for deploy) Url of the remote Maven " + + "repository that the generated Maven artifacts should be deployed to."). + isRequired(false). + create(OPTION_REPO_URL)); + options.addOption(OptionBuilder.withArgName("username").hasArg(). + withDescription("(Optional and only valid for deploy) Username used to authenticate " + + "on the remote Maven repository that the generated Maven artifacts should be " + + "deployed to."). + isRequired(false). + create(OPTION_REPO_USERNAME)); + options.addOption(OptionBuilder.withArgName("password").hasArg(). + withDescription("(Optional and only valid for deploy) Password used to authenticate " + + "on the remote Maven repository that the generated Maven artifacts should be " + + "deployed to."). + isRequired(false). + create(OPTION_REPO_PASSWORD)); + + CommandLineParser parser = new BasicParser(); + try { + CommandLine cmd = parser.parse(options, args); + if(cmd.getArgList().isEmpty() || cmd.getArgList().contains(COMMAND_HELP)) { + printHelp(options); + System.exit(0); + } + + // Find out the desired platform(s). + List<PlatformType> platforms = new ArrayList<PlatformType>(); + String platformParam = cmd.getOptionValue(OPTION_PLATFORMS); + if((platformParam != null) && !platformParam.isEmpty()) { + String[] platformNames = platformParam.split(","); + for(String platformName : platformNames) { + platforms.add(PlatformType.valueOf(platformName)); + } + } + + if(platforms.isEmpty()) { + try { + platforms.add(PlatformType.getCurrent()); + } catch (Exception e) { + System.err.println("Unsupported OS type. Provide manually using 'platform' parameter."); + System.exit(1); + } + } + + ///////////////////////////////////////////////////////// + // Validate sensible combinations of commands. + ///////////////////////////////////////////////////////// + + // Check that all commands are valid. + for(String command : (List<String>) cmd.getArgList()) { + if(!COMMAND_LIST.equals(command) && !COMMAND_DOWNLOAD.equals(command) && + !COMMAND_CONVERT.equals(command) && !COMMAND_DEPLOY.equals(command)) { + System.err.println("Unsupported command '" + command + "'."); + System.exit(1); + } + } + + // Downloading and deploying without converting doesn't make sense. + if(cmd.getArgList().contains(COMMAND_DOWNLOAD) && !cmd.getArgList().contains(COMMAND_CONVERT) && + cmd.getArgList().contains(COMMAND_DEPLOY)) { + System.err.println("Downloading and deploying without conversion doesn't make much sense."); + System.exit(1); + } + + // If Downloading and not converting, the fdkDir parameter has to be provided as + // otherwise the download result would reside in some strange temp directory. + if(cmd.getArgList().contains(COMMAND_DOWNLOAD) && !cmd.getArgList().contains(COMMAND_CONVERT) + && !cmd.hasOption(OPTION_FDK_DIR)) { + System.err.println("Parameter 'fdkDir' required for task 'download' without conversion."); + System.exit(1); + } + + // If Converting and not deploying, the mavenDir parameter has to be provided as + // otherwise the converted FDK would reside in some strange temp directory. + if(cmd.getArgList().contains(COMMAND_CONVERT) && !cmd.getArgList().contains(COMMAND_DEPLOY) + && !cmd.hasOption(OPTION_MAVEN_DIR)) { + System.err.println("Parameter 'mavenDir' required for task 'convert' without deployment."); + System.exit(1); + } + + // Downloading nothing doesn't really make sense. On the bad side it even causes + // problems with the converter without any fdkDir parameter, therefore we abort here. + if(cmd.getArgList().contains(COMMAND_DOWNLOAD) && !cmd.hasOption(OPTION_FLEX_VERSION) && + !cmd.hasOption(OPTION_FLASH_VERSIONS) && !cmd.hasOption(OPTION_AIT_VERSION) && + !cmd.hasOption(OPTION_FONTKIT)) { + System.err.println("At least one of the parameters 'flexVersion', 'flashVersions', 'airVersion' or " + + "'fontkit' required for task 'download'."); + System.exit(1); + } + + // Find out where to download or convert from. + File fdkDir = cmd.hasOption(OPTION_FDK_DIR) ? + new File(cmd.getOptionValue(OPTION_FDK_DIR)) : getTempDir("FLEX-DOWNLOAD-"); + + // Find out where to convert to or deploy from. + File mavenDir = cmd.hasOption(OPTION_MAVEN_DIR) ? + new File(cmd.getOptionValue(OPTION_MAVEN_DIR)) : getTempDir("FLEX-MAVEN-"); + + //////////////////////////////////////////////////////////////////////////// + // Exectute operations + //////////////////////////////////////////////////////////////////////////// + + // Output a list of all available downloads. + if(cmd.getArgList().contains(COMMAND_LIST)) { + System.out.println("-----------------------------------------------"); + System.out.println("- Available downloads"); + System.out.println("-----------------------------------------------"); + + DownloadRetriever retriever = new DownloadRetriever(); + System.out.println("Apache Flex:"); + List<DefaultArtifactVersion> versions = new ArrayList<DefaultArtifactVersion>( + retriever.getAvailableVersions(SdkType.FLEX).keySet()); + Collections.sort(versions); + for(DefaultArtifactVersion version : versions) { + System.out.println(" - " + version.toString()); + } + System.out.println(); + + System.out.println("Adobe Flash:"); + versions = new ArrayList<DefaultArtifactVersion>( + retriever.getAvailableVersions(SdkType.FLASH).keySet()); + Collections.sort(versions); + for(DefaultArtifactVersion version : versions) { + System.out.println(" - " + version.toString()); + } + System.out.println(); + + System.out.println("Adobe AIR:"); + Map<DefaultArtifactVersion, Collection<PlatformType>> versionData = + retriever.getAvailableVersions(SdkType.AIR); + versions = new ArrayList<DefaultArtifactVersion>(versionData.keySet()); + Collections.sort(versions); + for(DefaultArtifactVersion version : versions) { + StringBuilder sb = new StringBuilder(); + sb.append(" - ").append(version.toString()).append(" ("); + boolean firstOption = true; + for(PlatformType platformType : versionData.get(version)) { + if(!firstOption) { + sb.append(", "); + } + sb.append(platformType.name()); + firstOption = false; + } + sb.append(")"); + System.out.println(sb.toString()); + } + } + + // Handle the downloading of atifacts. + if(cmd.getArgList().contains(COMMAND_DOWNLOAD)) { + System.out.println("-----------------------------------------------"); + System.out.println("- Downloading"); + System.out.println("-----------------------------------------------"); + + DownloadRetriever retriever = new DownloadRetriever(); + + String flexVersion = cmd.getOptionValue(OPTION_FLEX_VERSION, null); + if(flexVersion != null) { + System.out.println("- Downloading Flex SDK version: " + flexVersion + + " to directory: " + fdkDir.getAbsolutePath()); + File fdkDownloadDirectory = retriever.retrieve(SdkType.FLEX, flexVersion); + // Unpack the archive to the FDK directory. + mergeDirectories(fdkDownloadDirectory, fdkDir); + + // Add the swfobject files. + File swfObjectDirectory = retriever.retrieve(SdkType.SWFOBJECT); + mergeDirectories(swfObjectDirectory, fdkDir); + } + + String flashVersions = cmd.getOptionValue(OPTION_FLASH_VERSIONS, ""); + if(!flashVersions.isEmpty()) { + for(String flashVersion : flashVersions.split(",")) { + System.out.println("- Downloading Flash SDK version: " + flashVersion + + " to directory: " + fdkDir.getAbsolutePath()); + File flashDownloadDiretory = retriever.retrieve(SdkType.FLASH, flashVersion); + // Integrate the download into the FDK directory. + mergeDirectories(flashDownloadDiretory, fdkDir); + } + } + + String airVersion = cmd.getOptionValue(OPTION_AIT_VERSION, ""); + if(!airVersion.isEmpty()) { + for(PlatformType platformType : platforms) { + System.out.println("- Downloading Air SDK version: " + airVersion + + " and platform " + platformType.name() + + " to directory: " + fdkDir.getAbsolutePath()); + File airDownloadDirectory = retriever.retrieve(SdkType.AIR, airVersion, platformType); + // Integrate the download into the FDK directory. + mergeDirectories(airDownloadDirectory, fdkDir); + } + } + + if(cmd.hasOption(OPTION_FONTKIT)) { + System.out.println("- Downloading Flex Fontkit libraries" + + " to directory: " + fdkDir.getAbsolutePath()); + File fontkitDownloadDirectory = retriever.retrieve(SdkType.FONTKIT); + // Integrate the download into the FDK directory. + mergeDirectories(fontkitDownloadDirectory, fdkDir); + } + + System.out.println("Finished downloads."); + } + + // Handle the conversion. + if(cmd.getArgList().contains(COMMAND_CONVERT)) { + System.out.println("-----------------------------------------------"); + System.out.println("- Conversion"); + System.out.println("-----------------------------------------------"); + + System.out.println("- Converting Flex SDK from " + fdkDir.getAbsolutePath() + + " to " + mavenDir.getAbsolutePath()); + FlexConverter flexConverter = new FlexConverter(fdkDir, mavenDir); + flexConverter.convert(); + + System.out.println("- Converting Flash SDKs from " + fdkDir.getAbsolutePath() + + " to " + mavenDir.getAbsolutePath()); + FlashConverter flashConverter = new FlashConverter(fdkDir, mavenDir); + flashConverter.convert(); + + System.out.println("- Converting Air SDK from " + fdkDir.getAbsolutePath() + + " to " + mavenDir.getAbsolutePath()); + AirConverter airConverter = new AirConverter(fdkDir, mavenDir); + airConverter.convert(); + + System.out.println("- Converting Fontkit libraries from " + fdkDir.getAbsolutePath() + + " to " + mavenDir.getAbsolutePath()); + FontkitConverter fontkitConverter = new FontkitConverter(fdkDir, mavenDir); + fontkitConverter.convert(); + + System.out.println("- Converting Wrappers from " + fdkDir.getAbsolutePath() + + " to " + mavenDir.getAbsolutePath()); + WrapperConverter wrapperConverter = new WrapperConverter(fdkDir, mavenDir); + wrapperConverter.convert(); + + System.out.println("Finished conversion."); + } + + // Handle the deployment. + if(cmd.getArgList().contains(COMMAND_DEPLOY)) { + System.out.println("-----------------------------------------------"); + System.out.println("- Deployment"); + System.out.println("-----------------------------------------------"); + + if(!cmd.hasOption(OPTION_REPO_URL)) { + System.err.println("Parameter 'repoUrl' required for task 'deploy'."); + System.exit(1); + } + + String repoUrl = cmd.getOptionValue(OPTION_REPO_URL); + String repoUsername = cmd.getOptionValue(OPTION_REPO_USERNAME, null); + String repoPassword = cmd.getOptionValue(OPTION_REPO_PASSWORD, null); + + System.out.println("- Deploying libraries to " + repoUrl + " from " + mavenDir.getAbsolutePath()); + + AetherDeployer deployer = new AetherDeployer(mavenDir, repoUrl, repoUsername, repoPassword); + deployer.deploy(); + + System.out.println("Finished deploying."); + } + System.out.println("-----------------------------------------------"); + } catch (ParseException e) { + System.err.println("Parsing failed. Reason: " + e.getMessage()); + printHelp(options); + } + } + + protected static void printHelp(Options options) { + String headerText = "Commands: \n" + + "If the parameters 'fdkDir' and 'mavenDir' are not specified, the Converter creates two temporary " + + "directories in your systems temp directory and uses these for the follwoing commands.\n" + + " - list:\nList all available versions and platforms (for download)\n" + + " - download:\nDownload the selected versions of FDK parts specified by 'flexVersion', " + + "'flashVersions', 'airVersion' and 'fontkit' and creates an FDK in the directory specified by " + + "'fdkDir'. If 'airVersion' is specified, the 'platforms' parameter specifies the platforms for which " + + "the given AIR SDK should be downloaded, if not specified the current systems platform is used. \n" + + " - convert:\nConvert the FDK located in 'fdkDir' into a mavenized form at 'mavenDir'.\n" + + " - deploy:\nDeploy the maven artifacts located in 'mavenDir', to the remote maven repository " + + "specified with 'repoUrl'. If the 'repoUsername' and 'repoPassword' parameters are specified, use " + + "these credentials for authenticating at the remote system.\n" + + "Options:"; + + HelpFormatter helpFormatter = new HelpFormatter(); + helpFormatter.printHelp("java -jar apache-flex-sdk-converter.jar [list] [-fdkDir <fdkDir>] " + + "[-mavenDir <mavenDir>] [[-flexVersion <version>] [-flashVersions <version(s)>] " + + "[-airVersion <version> [-platforms <platform(s)>]] [-fontkit] download] [convert] " + + "[-repoUrl <url> [-repoUsername <username> -repoPassword <password>] deploy]", + headerText, options, ""); + } + + protected static File getTempDir(String prefix) throws IOException { + File tempFile = File.createTempFile(prefix, ".TMP"); + tempFile.delete(); + File tempDir = new File(tempFile.getParentFile(), + tempFile.getName().substring(0, tempFile.getName().length() - 4)); + if(!tempDir.exists()) { + tempDir.mkdirs(); + } + return tempDir; + } + + protected static void mergeDirectories(File sourceDir, File targetDir) throws IOException { + FileUtils.copyDirectory(sourceDir, targetDir); + } + +} http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/converters/air/pom.xml ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/converters/air/pom.xml b/flex-maven-tools/flex-sdk-converter/converters/air/pom.xml new file mode 100644 index 0000000..88d61aa --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/converters/air/pom.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>converters</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <artifactId>air-converter</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>base-converter</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/converters/air/src/main/java/org/apache/flex/utilities/converter/air/AirConverter.java ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/converters/air/src/main/java/org/apache/flex/utilities/converter/air/AirConverter.java b/flex-maven-tools/flex-sdk-converter/converters/air/src/main/java/org/apache/flex/utilities/converter/air/AirConverter.java new file mode 100644 index 0000000..1c32f05 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/converters/air/src/main/java/org/apache/flex/utilities/converter/air/AirConverter.java @@ -0,0 +1,431 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.flex.utilities.converter.air; + +import org.apache.flex.utilities.converter.BaseConverter; +import org.apache.flex.utilities.converter.Converter; +import org.apache.flex.utilities.converter.exceptions.ConverterException; +import org.apache.flex.utilities.converter.model.MavenArtifact; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.zip.ZipOutputStream; + +/** + * Created by cdutz on 22.04.2014. + */ +public class AirConverter extends BaseConverter implements Converter { + + protected String airSdkVersion; + + /** + * @param rootSourceDirectory Path to the root of the original AIR SDK. + * @param rootTargetDirectory Path to the root of the directory where the Maven artifacts should be generated to. + * @throws ConverterException + */ + public AirConverter(File rootSourceDirectory, File rootTargetDirectory) throws ConverterException { + super(rootSourceDirectory, rootTargetDirectory); + + // Get the version of the current air sdk. + this.airSdkVersion = getAirVersion(rootSourceDirectory); + } + + /** + * Entry point for generating the Maven artifacts for an AIR SDK. + * + * @throws ConverterException + */ + @Override + protected void processDirectory() throws ConverterException { + if ((airSdkVersion == null) || !rootSourceDirectory.exists() || !rootSourceDirectory.isDirectory()) { + System.out.println("Skipping AIR SDK generation."); + return; + } + + generateCompilerArtifacts(); + generateRuntimeArtifacts(); + generateFrameworkArtifacts(); + } + + /** + * This method generates those artifacts that resemble the compiler part of the AIR SDK. + * + * @throws ConverterException + */ + protected void generateCompilerArtifacts() throws ConverterException { + // Create the root artifact. + final MavenArtifact compiler = new MavenArtifact(); + compiler.setGroupId("com.adobe.air"); + compiler.setArtifactId("compiler"); + compiler.setVersion(airSdkVersion); + compiler.setPackaging("pom"); + + // Create a list of all libs that should belong to the AIR SDK compiler. + final File directory = new File(rootSourceDirectory, "lib"); + if (!directory.exists() || !directory.isDirectory()) { + throw new ConverterException("Compiler directory does not exist."); + } + final List<File> files = new ArrayList<File>(); + files.addAll(Arrays.asList(directory.listFiles(new AirCompilerFilter()))); + + // Add the smali.jar and baksmali.jar from the android/lib directory + // as this is needed for Android packaging. + File androidDir = new File(directory, "android"); + if (androidDir.exists() && androidDir.isDirectory()) { + File androidLibDir = new File(androidDir, "lib"); + if (androidLibDir.exists() && androidLibDir.isDirectory()) { + files.addAll(Arrays.asList(androidLibDir.listFiles(new AirCompilerFilter()))); + } + } + + // Generate artifacts for every jar in the input directories. + for (final File sourceFile : files) { + final MavenArtifact artifact = resolveArtifact(sourceFile, "com.adobe.air.compiler", airSdkVersion); + compiler.addDependency(artifact); + } + + // Generate the android package (android directory) + if (androidDir.exists() && androidDir.isDirectory()) { + final File androidZip = new File(rootTargetDirectory, + "com.adobe.air.compiler.adt.".replace(".", File.separator) + airSdkVersion + + File.separator + "adt-" + airSdkVersion + "-android.zip"); + try { + // Add all the content to a zip-file. + final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(androidZip)); + // Package all the compiler parts. + File[] zipfiles = androidDir.listFiles(); + if(zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + // Package all the runtime parts. + File runtimesDir = new File(rootSourceDirectory, "runtimes/air/android"); + if(runtimesDir.exists() && runtimesDir.isDirectory()) { + zipfiles = runtimesDir.listFiles(); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + File binDir = new File(rootSourceDirectory, "bin"); + if(binDir.exists() && binDir.isDirectory()) { + zipfiles = binDir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.equals("adt") || name.equals("adt.bat") || + name.equals("adl") || name.equals("adl.exe"); + } + }); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + zipOutputStream.close(); + } catch(IOException e) { + throw new ConverterException("Error generating android package zip.", e); + } + } + + // Generate the ios package (aot directory) + File iosDir = new File(directory, "aot"); + if (iosDir.exists() && iosDir.isDirectory()) { + final File iosZip = new File(rootTargetDirectory, + "com.adobe.air.compiler.adt.".replace(".", File.separator) + airSdkVersion + + File.separator + "adt-" + airSdkVersion + "-ios.zip"); + try { + // Add all the content to a zip-file. + final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(iosZip)); + // Package all the compiler parts. + File[] zipfiles = iosDir.listFiles(); + if(zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + File binDir = new File(rootSourceDirectory, "bin"); + if(binDir.exists() && binDir.isDirectory()) { + zipfiles = binDir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.equals("adt") || name.equals("adt.bat") || + name.equals("adl") || name.equals("adl.exe"); + } + }); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + zipOutputStream.close(); + } catch(IOException e) { + throw new ConverterException("Error generating android package zip.", e); + } + } + + // Generate the exe, dmg, deb, rpm packages (nai directory) + File desktopDir = new File(directory, "nai"); + if (desktopDir.exists() && desktopDir.isDirectory()) { + final File desktopZip = new File(rootTargetDirectory, + "com.adobe.air.compiler.adt.".replace(".", File.separator) + airSdkVersion + + File.separator + "adt-" + airSdkVersion + "-desktop.zip"); + try { + // Add all the content to a zip-file. + final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(desktopZip)); + // Package all the compiler parts. + File[] zipfiles = desktopDir.listFiles(); + if(zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + // Package all the runtime parts. + File runtimesDir = new File(rootSourceDirectory, "runtimes/air/win"); + if(runtimesDir.exists() && runtimesDir.isDirectory()) { + zipfiles = runtimesDir.listFiles(); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + runtimesDir = new File(rootSourceDirectory, "runtimes/air/mac/Adobe AIR.framework/Versions/1.0"); + if(runtimesDir.exists() && runtimesDir.isDirectory()) { + zipfiles = runtimesDir.listFiles(); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + runtimesDir = new File(rootSourceDirectory, "runtimes/air-captive/win"); + if(runtimesDir.exists() && runtimesDir.isDirectory()) { + zipfiles = runtimesDir.listFiles(); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + runtimesDir = new File(rootSourceDirectory, "runtimes/air-captive/mac/Adobe AIR.framework/Versions/1.0"); + if(runtimesDir.exists() && runtimesDir.isDirectory()) { + zipfiles = runtimesDir.listFiles(); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + File binDir = new File(rootSourceDirectory, "bin"); + if(binDir.exists() && binDir.isDirectory()) { + zipfiles = binDir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.equals("adt") || name.equals("adt.bat") || + name.equals("adl") || name.equals("adl.exe"); + } + }); + if (zipfiles != null) { + for (final File file : zipfiles) { + addFileToZip(zipOutputStream, file, rootSourceDirectory); + } + } + } + zipOutputStream.close(); + } catch(IOException e) { + throw new ConverterException("Error generating android package zip.", e); + } + } + + // Write this artifact to file. + writeArtifact(compiler); + } + + /** + * This method generates those artifacts that resemble the runtime part of the AIR SDK. + * + * @throws ConverterException + */ + protected void generateRuntimeArtifacts() throws ConverterException { + // Create the root artifact. + final MavenArtifact runtime = new MavenArtifact(); + runtime.setGroupId("com.adobe.air"); + runtime.setArtifactId("runtime"); + runtime.setVersion(airSdkVersion); + runtime.setPackaging("pom"); + + // Create a list of all libs that should belong to the AIR SDK runtime. + final File directory = new File(rootSourceDirectory, "bin"); + if (!directory.exists() || !directory.isDirectory()) { + throw new ConverterException("Runtime directory does not exist."); + } + final List<File> files = new ArrayList<File>(); + files.addAll(Arrays.asList(directory.listFiles(new AirRuntimeFilter()))); + + // Generate artifacts for every jar in the input directories (Actually this is only one file). + for (final File sourceFile : files) { + final MavenArtifact artifact = resolveArtifact(sourceFile, "com.adobe.air.runtime", airSdkVersion); + runtime.addDependency(artifact); + } + + // Zip up the AIR runtime directory. + final MavenArtifact airRuntimeArtifact = generateAirRuntimeArtifact(rootSourceDirectory); + if (airRuntimeArtifact != null) { + runtime.addDependency(airRuntimeArtifact); + } + + // Write this artifact to file. + writeArtifact(runtime); + } + + /** + * This method generates those artifacts that resemble the framework part of the AIR SDK. + * + * @throws ConverterException + */ + protected void generateFrameworkArtifacts() throws ConverterException { + // Create the root artifact. + final MavenArtifact framework = new MavenArtifact(); + framework.setGroupId("com.adobe.air"); + framework.setArtifactId("framework"); + framework.setVersion(airSdkVersion); + framework.setPackaging("pom"); + + // Create a list of all libs that should belong to the AIR SDK framework. + final File directory = + new File(rootSourceDirectory, "frameworks" + File.separator + "libs" + File.separator + "air"); + if (!directory.exists() || !directory.isDirectory()) { + throw new ConverterException("Framework directory does not exist."); + } + final List<File> files = new ArrayList<File>(); + files.addAll(Arrays.asList(directory.listFiles(new AirFrameworkFilter()))); + + // Generate artifacts for every jar in the input directories. + for (final File sourceFile : files) { + final MavenArtifact artifact = resolveArtifact(sourceFile, "com.adobe.air.framework", airSdkVersion); + framework.addDependency(artifact); + } + + // Write this artifact to file. + writeArtifact(framework); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Utility methods + // + /////////////////////////////////////////////////////////////////////////////////////////////////// + + protected MavenArtifact generateAirRuntimeArtifact(File rootDirectory) throws ConverterException { + final MavenArtifact airRuntimeArtifact = new MavenArtifact(); + airRuntimeArtifact.setGroupId("com.adobe.air.runtime"); + airRuntimeArtifact.setArtifactId("air-runtime"); + airRuntimeArtifact.setVersion(airSdkVersion); + airRuntimeArtifact.setPackaging("zip"); + + final File runtimeRoot = new File(rootDirectory, "runtimes.air".replace(".", File.separator)); + final File[] platforms = runtimeRoot.listFiles(); + if (platforms != null) { + for (final File platform : platforms) { + if (!platform.isDirectory()) { + continue; + } + final String platformName = platform.getName(); + try { + final File zip = File.createTempFile("AirRuntime-" + platformName + "-" + airSdkVersion, "zip"); + generateZip(platform.listFiles(), zip); + airRuntimeArtifact.addBinaryArtifact(platformName, zip); + } catch (IOException e) { + throw new ConverterException("Error creating runtime zip.", e); + } + } + } else { + return null; + } + + writeArtifact(airRuntimeArtifact); + return airRuntimeArtifact; + } + + /** + * Get the version of an AIR SDK from the content of the SDK directory. + * + * @return version string for the current AIR SDK + */ + protected String getAirVersion(File rootDirectory) throws ConverterException { + // All AIR SDKs contain a text file "AIR SDK Readme.txt" which contains a + // Version string in the first line. Newer SDKs contain an additional "airsdk.xml" + // which would be easier to parse, but as all SDKs contain the text-file, we'll + // stick to that for now. + + final File sdkDescriptor = new File(rootDirectory, "AIR SDK Readme.txt"); + + // If the descriptor is not present, return null as this FDK directory doesn't + // seem to contain a AIR SDK. + if (!sdkDescriptor.exists() || !sdkDescriptor.isFile()) { + return null; + } + + DataInputStream in = null; + try { + final FileInputStream descriptorInputStream = new FileInputStream(sdkDescriptor); + in = new DataInputStream(descriptorInputStream); + final BufferedReader br = new BufferedReader(new InputStreamReader(in)); + final String strLine = br.readLine(); + return strLine.substring("Adobe AIR ".length(), strLine.indexOf(" ", "Adobe AIR ".length())); + } catch (Exception e) { + throw new ConverterException("Error getting AIR version.", e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ioe) { + // Ignore. + } + } + } + } + + public static class AirCompilerFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return name.equals("adt.jar") || name.equals("smali.jar") || name.equals("baksmali.jar"); + } + } + + public static class AirRuntimeFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return name.equalsIgnoreCase("adl.exe"); + } + } + + public static class AirFrameworkFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return name.equals("aircore.swc") || name.equals("airglobal.swc") || + name.equals("applicationupdater.swc") || name.equals("applicationupdater_ui.swc") || + name.equals("servicemonitor.swc"); + } + } + + public static void main(String[] args) throws Exception { + AirConverter converter = new AirConverter(new File(args[0]), new File(args[1])); + converter.convert(); + } + +} http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/converters/base/pom.xml ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/converters/base/pom.xml b/flex-maven-tools/flex-sdk-converter/converters/base/pom.xml new file mode 100644 index 0000000..5a1b89c --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/converters/base/pom.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.flex.utilities.converter</groupId> + <artifactId>converters</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <artifactId>base-converter</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + <version>1.12</version> + </dependency> + <dependency> + <groupId>org.codehaus.jettison</groupId> + <artifactId>jettison</artifactId> + <version>1.3.1</version> + </dependency> + <dependency> + <groupId>org.freemarker</groupId> + <artifactId>freemarker</artifactId> + <version>2.3.22</version> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/BaseConverter.java ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/BaseConverter.java b/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/BaseConverter.java new file mode 100644 index 0000000..65e5bd7 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/BaseConverter.java @@ -0,0 +1,426 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.flex.utilities.converter; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateExceptionHandler; +import org.apache.flex.utilities.converter.exceptions.ConverterException; +import org.apache.flex.utilities.converter.model.MavenArtifact; +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.codehaus.jettison.json.JSONTokener; + +import java.io.*; +import java.math.BigInteger; +import java.net.URL; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * Created by cdutz on 11.05.2012. + */ +public abstract class BaseConverter { + + protected final Map<String, MavenArtifact> checksums = new HashMap<String, MavenArtifact>(); + + protected static final String MAVEN_CENTRAL_SHA_1_QUERY_URL = "http://search.maven.org/solrsearch/select?rows=20&wt=json&q=1:"; + // Artifactory: "http://server:port/artifactory/api/search/checksum?repos=libs-release-local&md5=04040c7c184620af0a0a8a3682a75eb7 + // Nexus: "http://repository.sonatype.org/service/local/data_index?a=04040c7c184620af0a0a8a3682a75eb7" + + protected File rootSourceDirectory; + protected File rootTargetDirectory; + + protected Configuration freemarkerConfig; + + protected BaseConverter(File rootSourceDirectory, File rootTargetDirectory) throws ConverterException { + if(rootSourceDirectory == null) { + throw new ConverterException("Air SDK directory is null."); + } + if(rootTargetDirectory == null) { + throw new ConverterException("Target directory is null."); + } + + this.rootSourceDirectory = rootSourceDirectory; + this.rootTargetDirectory = rootTargetDirectory; + + this.freemarkerConfig = new Configuration(Configuration.VERSION_2_3_22); + this.freemarkerConfig.setDefaultEncoding("UTF-8"); + this.freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); + this.freemarkerConfig.setClassForTemplateLoading(this.getClass(), "/"); + } + + public void convert() throws ConverterException { + if(rootSourceDirectory.isFile()) { + processArchive(); + } else { + processDirectory(); + } + } + + abstract protected void processDirectory() throws ConverterException; + + protected void processArchive() throws ConverterException { + + } + + protected String calculateChecksum(File jarFile) throws ConverterException { + // Implement the calculation of checksums for a given jar. + final MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA-1"); + + final InputStream is = new FileInputStream(jarFile); + final byte[] buffer = new byte[8192]; + int read; + try { + while( (read = is.read(buffer)) > 0) { + digest.update(buffer, 0, read); + } + final byte[] md5sum = digest.digest(); + final BigInteger bigInt = new BigInteger(1, md5sum); + return bigInt.toString(16); + } + catch(IOException e) { + throw new RuntimeException("Unable to process file for MD5", e); + } + finally { + try { + is.close(); + } + catch(IOException e) { + //noinspection ThrowFromFinallyBlock + throw new RuntimeException("Unable to close input stream for MD5 calculation", e); + } + } + } catch (NoSuchAlgorithmException e) { + throw new ConverterException("Error calculating checksum of file '" + jarFile.getPath() + "'", e); + } catch (FileNotFoundException e) { + throw new ConverterException("Error calculating checksum of file '" + jarFile.getPath() + "'", e); + } + } + + protected MavenArtifact lookupMetadataForChecksum(String checksum) throws ConverterException { + final String queryUrl = MAVEN_CENTRAL_SHA_1_QUERY_URL + checksum; + + final Client client = Client.create(); + final WebResource webResource = client.resource(queryUrl); + final ClientResponse response = webResource.accept("application/json").get(ClientResponse.class); + + if (response.getStatus() != 200) { + throw new RuntimeException("Failed : HTTP error code : " + response.getStatus()); + } + + final String output = response.getEntity(String.class); + + final BufferedReader reader = new BufferedReader(new StringReader(output)); + final StringBuilder builder = new StringBuilder(); + try { + for (String line; (line = reader.readLine()) != null; ) { + builder.append(line).append("\n"); + } + final JSONTokener tokener = new JSONTokener(builder.toString()); + final JSONObject rootObject = new JSONObject(tokener); + + final JSONObject responseObject = (JSONObject) rootObject.get("response"); + final int numFound = (Integer) responseObject.get("numFound"); + if(numFound == 0) { + return null; + } + else if(numFound == 1) { + final JSONArray docs = (JSONArray) responseObject.get("docs"); + final JSONObject firstHit = (JSONObject) docs.get(0); + + final MavenArtifact artifactMetadata = new MavenArtifact(); + artifactMetadata.setGroupId((String) firstHit.get("g")); + artifactMetadata.setArtifactId((String) firstHit.get("a")); + artifactMetadata.setVersion((String) firstHit.get("v")); + artifactMetadata.setPackaging((String) firstHit.get("p")); + + return artifactMetadata; + } else { + long newestTimestamp = 0; + JSONObject newestVersion = null; + + JSONArray options = (JSONArray) responseObject.get("docs"); + // if the "groupId" is "batik" then use the newer version. + for(int i = 0; i < numFound; i++) { + final JSONObject option = (JSONObject) options.get(0); + if("batik".equals(option.get("g")) && "batik-dom".equals(option.get("a")) && "jar".equals(option.get("p"))) { + final long timestamp = (Long) option.get("timestamp"); + if(timestamp > newestTimestamp) { + newestTimestamp = timestamp; + newestVersion = option; + } + } + } + + if(newestVersion != null) { + final MavenArtifact artifactMetadata = new MavenArtifact(); + artifactMetadata.setGroupId((String) newestVersion.get("g")); + artifactMetadata.setArtifactId((String) newestVersion.get("a")); + artifactMetadata.setVersion((String) newestVersion.get("v")); + artifactMetadata.setPackaging((String) newestVersion.get("p")); + + return artifactMetadata; + } else { + System.out.println("For jar-file with checksum: " + checksum + + " more than one result was returned by query: " + queryUrl); + } + } + return null; + } catch(IOException e) { + throw new ConverterException("Error processing Metadata for checksum: '" + checksum + "'", e); + } catch (JSONException e) { + throw new ConverterException("Error processing Metadata for checksum: '" + checksum + "'", e); + } + } + + protected void copyFile(File source, File target) throws ConverterException { + try { + final File outputDirectory = target.getParentFile(); + if(!outputDirectory.exists()) { + if(!outputDirectory.mkdirs()) { + throw new RuntimeException("Could not create directory: " + outputDirectory.getAbsolutePath()); + } + } + + final InputStream in = new FileInputStream(source); + final OutputStream out = new FileOutputStream(target); + + final byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0){ + out.write(buf, 0, len); + } + + in.close(); + out.close(); + } catch(IOException e) { + throw new ConverterException("Error copying file from '" + source.getPath() + + "' to '" + target.getPath() + "'", e); + } + } + + protected void writePomArtifact(MavenArtifact pomData) throws ConverterException { + final File outputFile = pomData.getPomTargetFile(rootTargetDirectory); + createPomDocument(pomData, outputFile); + } + + protected void createPomDocument(final MavenArtifact metadata, File outputFile) throws ConverterException { + try { + // Build a context to hold the model + Map freemarkerContext = new HashMap(); + freemarkerContext.put("artifact", metadata); + + // Try to get a template "templates/{type}.vm". + Template template; + URL check = this.getClass().getClassLoader().getResource("templates/" + metadata.getPackaging() + ".ftl"); + if(check != null) { + template = freemarkerConfig.getTemplate("templates/" + metadata.getPackaging() + ".ftl"); + } else { + template = freemarkerConfig.getTemplate("templates/default.ftl"); + } + + // Prepare an output stream to which the output can be generated. + FileWriter writer = null; + try { + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + throw new ConverterException("Could not create template output directory."); + } + } + + writer = new FileWriter(outputFile); + + // Have Freemarker generate the output for the template. + template.process(freemarkerContext, writer); + } finally { + if(writer != null) { + writer.close(); + } + } + } catch (Exception e) { + throw new ConverterException("Error generating template output.", e); + } + } + + protected void writeDummy(final File targetFile) throws ConverterException { + try { + final ZipOutputStream out = new ZipOutputStream(new FileOutputStream(targetFile)); + out.putNextEntry(new ZipEntry("dummy")); + out.closeEntry(); + out.close(); + } catch (IOException e) { + throw new ConverterException("Error generating dummy resouce bundle."); + } + } + + protected static File findDirectory(File directory, String directoryToFind) { + File[] entries = directory.listFiles(); + File founded = null; + + // Go over entries + if(entries != null) { + for (File entry : entries) { + if (entry.isDirectory() && directoryToFind.equalsIgnoreCase(entry.getName())) { + founded = entry; + break; + } + if (entry.isDirectory()) { + founded = findDirectory(entry, directoryToFind); + if (founded != null) + break; + } + } + } + return founded; + } + + protected MavenArtifact resolveArtifact(File sourceFile, String defaultGroupId, String defaultVersion) + throws ConverterException { + // Calculate a checksum for the current file. We will use this checksum to query maven central + // in order to find out if this lib has already been published. If it has, there is no need to + // publish it again under a new name. In case a matching artifact is found the generated FDK + // will use the already deployed version. Additionally the checksum will be saved and if a + // fdk generated after this one uses the same version of a lib, the version of the older fdk is + // used also reducing the amount of jars that have to be re-deployed. + final String checksum = calculateChecksum(sourceFile); + + // Try to get artifact metadata based upon the checksum by looking up the internal cache. + MavenArtifact artifact = checksums.get(checksum); + + // Reusing artifact from other sdk version. + if(artifact != null) { + System.out.println("Reusing artifact (" + checksum + ") : " + artifact.getGroupId() + ":" + + artifact.getArtifactId() + ":" + artifact.getVersion()); + return artifact; + } + // Id no artifact was found in the local cache, continue processing. + else { + // Do a lookup in maven central. + artifact = lookupMetadataForChecksum(checksum); + + // The file was available on maven central, so use that version instead of the one coming with the sdk. + if(artifact != null) { + System.out.println("Using artifact from Maven Central (" + checksum + ") : " + + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion()); + } + // The file was not available on maven central, so we have to add it manually. + else { + // The artifact name is the name of the jar. + final String artifactFileName = sourceFile.getName(); + final String dependencyArtifactId = artifactFileName.substring(0, artifactFileName.lastIndexOf(".")); + final String dependencyArtifactPackaging = + artifactFileName.substring(artifactFileName.lastIndexOf(".") + 1); + + // Generate a new metadata object + artifact = new MavenArtifact(); + artifact.setGroupId(defaultGroupId); + artifact.setArtifactId(dependencyArtifactId); + artifact.setVersion(defaultVersion); + artifact.setPackaging(dependencyArtifactPackaging); + artifact.addDefaultBinaryArtifact(sourceFile); + + // Create the pom document that will reside next to the artifact lib. + writeArtifact(artifact); + } + + // Remember the checksum for later re-usage. + checksums.put(checksum, artifact); + + return artifact; + } + } + + protected void writeArtifact(MavenArtifact artifact) throws ConverterException { + // Write the pom itself. + writePomArtifact(artifact); + final List<String> binaryClassifiers = artifact.getBinaryFilesClassifiers(); + for(final String classifier : binaryClassifiers) { + final File binarySourceFile = artifact.getBinarySourceFile(classifier); + final File binaryTargetFile = artifact.getBinaryTargetFile(rootTargetDirectory, classifier); + copyFile(binarySourceFile, binaryTargetFile); + } + } + + protected void generateZip(File[] sourceFiles, File targetFile) throws ConverterException { + if((sourceFiles == null) || (sourceFiles.length == 0)) { + return; + } + final File rootDir = sourceFiles[0].getParentFile(); + final File zipInputFiles[] = new File[sourceFiles.length]; + System.arraycopy(sourceFiles, 0, zipInputFiles, 0, sourceFiles.length); + + try { + // Add all the content to a zip-file. + final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(targetFile)); + for (final File file : zipInputFiles) { + addFileToZip(zipOutputStream, file, rootDir); + } + zipOutputStream.close(); + } catch(IOException e) { + throw new ConverterException("Error generating " + targetFile.getName() + " zip.", e); + } + } + + protected void addFileToZip(ZipOutputStream zipOutputStream, File inputFile, File rootDirectory) + throws ConverterException { + + if (inputFile == null) { + return; + } + + // If this is a directory, add all it's children. + if (inputFile.isDirectory()) { + final File directoryContent[] = inputFile.listFiles(); + if (directoryContent != null) { + for (final File file : directoryContent) { + addFileToZip(zipOutputStream, file, rootDirectory); + } + } + } + // If this is a file, add it to the zips output. + else { + byte[] buf = new byte[1024]; + try { + final FileInputStream in = new FileInputStream(inputFile); + final String zipPath = inputFile.getAbsolutePath().substring( + rootDirectory.getAbsolutePath().length() + 1).replace("\\", "/"); + zipOutputStream.putNextEntry(new ZipEntry(zipPath)); + int len; + while ((len = in.read(buf)) > 0) { + zipOutputStream.write(buf, 0, len); + } + zipOutputStream.closeEntry(); + in.close(); + } catch(IOException e) { + throw new ConverterException("Error adding files to zip.", e); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/Converter.java ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/Converter.java b/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/Converter.java new file mode 100644 index 0000000..54f4e18 --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/Converter.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.flex.utilities.converter; + +import org.apache.flex.utilities.converter.exceptions.ConverterException; + +/** + * Created by cdutz on 18.04.2014. + */ +public interface Converter { + + void convert() throws ConverterException; + +} http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/8bc0350d/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/exceptions/ConverterException.java ---------------------------------------------------------------------- diff --git a/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/exceptions/ConverterException.java b/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/exceptions/ConverterException.java new file mode 100644 index 0000000..384f2fe --- /dev/null +++ b/flex-maven-tools/flex-sdk-converter/converters/base/src/main/java/org/apache/flex/utilities/converter/exceptions/ConverterException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.flex.utilities.converter.exceptions; + +/** + * Created by cdutz on 07.05.2014. + */ +public class ConverterException extends Exception { + + public ConverterException(String message) { + super(message); + } + + public ConverterException(String message, Throwable cause) { + super(message, cause); + } + +}
