Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2009 Jayway AB
* Copyright (C) 2007-2008 JVending Masa
*
* 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 com.jayway.maven.plugins.android.phase01generatesources;
import static com.jayway.maven.plugins.android.common.AndroidExtension.APK;
import static com.jayway.maven.plugins.android.common.AndroidExtension.APKLIB;
import static com.jayway.maven.plugins.android.common.AndroidExtension.APKSOURCES;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.jayway.maven.plugins.android.common.AetherHelper;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.util.AbstractScanner;
import com.jayway.maven.plugins.android.AbstractAndroidMojo;
import com.jayway.maven.plugins.android.CommandExecutor;
import com.jayway.maven.plugins.android.ExecutionException;
/**
* Generates R.java based on resources specified by the resources configuration parameter.
* Generates java files based on aidl files.
*
*
* @author [email protected]
* @goal generate-sources
* @phase generate-sources
* @requiresProject true
* @requiresDependencyResolution compile
*/
public class GenerateSourcesMojo extends AbstractAndroidMojo {
/**
* Override default generated folder
*
* @parameter expression="${android.genDirectory}" default-value="${project.build.directory}/generated-sources/r"
*
*/
protected File genDirectory;
public void execute() throws MojoExecutionException, MojoFailureException {
// If the current POM isn't an Android-related POM, then don't do
// anything. This helps work with multi-module projects.
if (!isCurrentProjectAndroid()) {
return;
}
try {
extractSourceDependencies();
extractApkLibDependencies();
final String[] relativeAidlFileNames1 = findRelativeAidlFileNames(sourceDirectory);
final String[] relativeAidlFileNames2 = findRelativeAidlFileNames(extractedDependenciesJavaSources);
final Map relativeApklibAidlFileNames = new HashMap();
String[] apklibAidlFiles;
for (Artifact artifact: getAllRelevantDependencyArtifacts()) {
if (artifact.getType().equals(APKLIB)) {
apklibAidlFiles = findRelativeAidlFileNames(new File(getLibraryUnpackDirectory(artifact)+"/src"));
relativeApklibAidlFileNames.put(artifact.getArtifactId(), apklibAidlFiles);
}
}
generateR();
generateApklibR();
// When compiling AIDL for this project,
// make sure we compile AIDL for dependencies as well.
// This is so project A, which depends on project B, can
// use AIDL info from project B in its own AIDL
Map files = new HashMap();
files.put(sourceDirectory, relativeAidlFileNames1);
files.put(extractedDependenciesJavaSources, relativeAidlFileNames2);
for (Artifact artifact: getAllRelevantDependencyArtifacts()) {
if (artifact.getType().equals(APKLIB)) {
files.put(new File(getLibraryUnpackDirectory(artifact)+"/src"),
relativeApklibAidlFileNames.get(artifact.getArtifactId()));
}
}
generateAidlFiles(files);
} catch (MojoExecutionException e) {
getLog().error("Error when generating sources.", e);
throw e;
}
}
protected void extractSourceDependencies() throws MojoExecutionException {
for (Artifact artifact :getRelevantDependencyArtifacts()) {
String type = artifact.getType();
if (type.equals(APKSOURCES)) {
getLog().debug("Detected apksources dependency " + artifact + " with file " + artifact.getFile() + ". Will resolve and extract...");
Artifact resolvedArtifact = AetherHelper.resolveArtifact(artifact,repoSystem,repoSession,projectRepos);
File apksourcesFile = resolvedArtifact.getFile();
// When the artifact is not installed in local repository, but rather part of the current reactor,
// resolve from within the reactor. (i.e. ../someothermodule/target/*)
if (!apksourcesFile.exists()) {
apksourcesFile = resolveArtifactToFile(artifact);
}
//When using maven under eclipse the artifact will by default point to a directory, which isn't correct.
//To work around this we'll first try to get the archive from the local repo, and only if it isn't found there we'll do a normal resolve.
if (apksourcesFile.isDirectory()) {
apksourcesFile = resolveArtifactToFile(artifact);
}
getLog().debug("Extracting " + apksourcesFile + "...");
extractApksources(apksourcesFile);
}
}
projectHelper.addResource(project, extractedDependenciesJavaResources.getAbsolutePath(), null, null);
project.addCompileSourceRoot(extractedDependenciesJavaSources.getAbsolutePath());
}
private void extractApksources(File apksourcesFile) throws MojoExecutionException {
if (apksourcesFile.isDirectory()) {
getLog().warn("The apksources artifact points to '" + apksourcesFile + "' which is a directory; skipping unpacking it.");
return;
}
final UnArchiver unArchiver = new ZipUnArchiver(apksourcesFile) {
@Override
protected Logger getLogger() {
return new ConsoleLogger(Logger.LEVEL_DEBUG, "dependencies-unarchiver");
}
};
extractedDependenciesDirectory.mkdirs();
unArchiver.setDestDirectory(extractedDependenciesDirectory);
try {
unArchiver.extract();
} catch (ArchiverException e) {
throw new MojoExecutionException("ArchiverException while extracting " + apksourcesFile.getAbsolutePath() + ". Message: " + e.getLocalizedMessage(), e);
}
}
private void extractApkLibDependencies() throws MojoExecutionException {
for (Artifact artifact :getAllRelevantDependencyArtifacts()) {
String type = artifact.getType();
if (type.equals(APKLIB)) {
getLog().debug("Extracting apklib " + artifact.getArtifactId() + "...");
extractApklib(artifact);
}
}
}
private void extractApklib(Artifact apklibArtifact) throws MojoExecutionException {
final Artifact resolvedArtifact = AetherHelper.resolveArtifact(apklibArtifact,repoSystem,repoSession,projectRepos);
File apkLibFile = resolvedArtifact.getFile();
// When the artifact is not installed in local repository, but rather part of the current reactor,
// resolve from within the reactor. (i.e. ../someothermodule/target/*)
if (!apkLibFile.exists()) {
apkLibFile = resolveArtifactToFile(apklibArtifact);
}
//When using maven under eclipse the artifact will by default point to a directory, which isn't correct.
//To work around this we'll first try to get the archive from the local repo, and only if it isn't found there we'll do a normal resolve.
if (apkLibFile.isDirectory()) {
apkLibFile = resolveArtifactToFile(apklibArtifact);
}
if (apkLibFile.isDirectory()) {
getLog().warn("The apklib artifact points to '" + apkLibFile + "' which is a directory; skipping unpacking it.");
return;
}
final UnArchiver unArchiver = new ZipUnArchiver(apkLibFile) {
@Override
protected Logger getLogger() {
return new ConsoleLogger(Logger.LEVEL_DEBUG, "dependencies-unarchiver");
}
};
File apklibDirectory = new File(getLibraryUnpackDirectory(apklibArtifact));
apklibDirectory.mkdirs();
unArchiver.setDestDirectory(apklibDirectory);
try {
unArchiver.extract();
} catch (ArchiverException e) {
throw new MojoExecutionException("ArchiverException while extracting " + apklibDirectory.getAbsolutePath()
+ ". Message: " + e.getLocalizedMessage(), e);
}
projectHelper.addResource(project, apklibDirectory.getAbsolutePath() + "/src", null, Arrays.asList("**/*.java", "**/*.aidl"));
project.addCompileSourceRoot(apklibDirectory.getAbsolutePath() + "/src");
}
private void generateR() throws MojoExecutionException {
getLog().debug("Generating R file for "+project.getPackaging());
genDirectory.mkdirs();
File[] overlayDirectories;
if (resourceOverlayDirectories == null || resourceOverlayDirectories.length == 0) {
overlayDirectories = new File[]{resourceOverlayDirectory};
} else {
overlayDirectories = resourceOverlayDirectories;
}
if (extractedDependenciesRes.exists()) {
try {
getLog().info("Copying dependency resource files to combined resource directory.");
if (!combinedRes.exists()) {
if (!combinedRes.mkdirs()) {
throw new MojoExecutionException("Could not create directory for combined resources at " + combinedRes.getAbsolutePath());
}
}
org.apache.commons.io.FileUtils.copyDirectory(extractedDependenciesRes, combinedRes);
} catch (IOException e) {
throw new MojoExecutionException("", e);
}
}
if (resourceDirectory.exists() && combinedRes.exists()) {
try {
getLog().info("Copying local resource files to combined resource directory.");
org.apache.commons.io.FileUtils.copyDirectory(resourceDirectory, combinedRes, new FileFilter() {
/**
* Excludes files matching one of the common file to exclude.
* The default excludes pattern are the ones from
* {org.codehaus.plexus.util.AbstractScanner#DEFAULTEXCLUDES}
* @see java.io.FileFilter#accept(java.io.File)
*/
public boolean accept(File file) {
for (String pattern : AbstractScanner.DEFAULTEXCLUDES) {
if (AbstractScanner.match(pattern, file.getAbsolutePath())) {
getLog().debug("Excluding " + file.getName() + " from resource copy : matching " + pattern);
return false;
}
}
return true;
}
});
} catch (IOException e) {
throw new MojoExecutionException("", e);
}
}
CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor();
executor.setLogger(this.getLog());
List commands = new ArrayList();
commands.add("package");
commands.add("-m");
commands.add("-J");
commands.add(genDirectory.getAbsolutePath());
commands.add("-M");
commands.add(androidManifestFile.getAbsolutePath());
if (StringUtils.isNotBlank(customPackage)) {
commands.add("--custom-package");
commands.add(customPackage);
}
for (File resOverlayDir : overlayDirectories) {
if (resOverlayDir != null && resOverlayDir.exists()) {
commands.add("-S");
commands.add(resOverlayDir.getAbsolutePath());
}
}
if (combinedRes.exists()) {
commands.add("-S");
commands.add(combinedRes.getAbsolutePath());
} else {
if (resourceDirectory.exists()) {
commands.add("-S");
commands.add(resourceDirectory.getAbsolutePath());
}
}
for (Artifact artifact: getAllRelevantDependencyArtifacts()) {
if (artifact.getType().equals(APKLIB)) {
commands.add("-S");
commands.add(getLibraryUnpackDirectory(artifact)+"/res");
}
}
commands.add("--auto-add-overlay");
if (assetsDirectory.exists()) {
commands.add("-A");
commands.add(assetsDirectory.getAbsolutePath());
}
if (extractedDependenciesAssets.exists()) {
commands.add("-A");
commands.add(extractedDependenciesAssets.getAbsolutePath());
}
commands.add("-I");
commands.add(getAndroidSdk().getAndroidJar().getAbsolutePath());
if (StringUtils.isNotBlank(configurations)) {
commands.add("-c");
commands.add(configurations);
}
getLog().info(getAndroidSdk().getPathForTool("aapt") + " " + commands.toString());
try {
executor.executeCommand(getAndroidSdk().getPathForTool("aapt"), commands, project.getBasedir(), false);
} catch (ExecutionException e) {
throw new MojoExecutionException("", e);
}
project.addCompileSourceRoot(genDirectory.getAbsolutePath());
}
private void generateApklibR() throws MojoExecutionException {
getLog().debug("Generating R file for projects dependent on apklibs");
genDirectory.mkdirs();
for (Artifact artifact : getAllRelevantDependencyArtifacts()) {
if (artifact.getType().equals(APKLIB)) {
generateRForApkLibDependency(artifact);
}
}
project.addCompileSourceRoot(genDirectory.getAbsolutePath());
}
private void generateRForApkLibDependency(Artifact apklibArtifact) throws MojoExecutionException {
final String unpackDir = getLibraryUnpackDirectory(apklibArtifact);
getLog().debug("Generating R file for apklibrary: " + apklibArtifact.getGroupId());
CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor();
executor.setLogger(this.getLog());
List commands = new ArrayList();
commands.add("package");
commands.add("-m");
commands.add("-J");
commands.add(genDirectory.getAbsolutePath());
commands.add("--custom-package");
commands.add(extractPackageNameFromAndroidManifest(new File(unpackDir + "/" + "AndroidManifest.xml")));
commands.add("-M");
commands.add(androidManifestFile.getAbsolutePath());
if (resourceDirectory.exists()){
commands.add("-S");
commands.add(resourceDirectory.getAbsolutePath());
}
for (Artifact artifact: getAllRelevantDependencyArtifacts()) {
if (artifact.getType().equals(APKLIB)) {
final String apkLibResDir = getLibraryUnpackDirectory(artifact) + "/res";
if (new File(apkLibResDir).exists()){
commands.add("-S");
commands.add(apkLibResDir);
}
}
}
commands.add("--auto-add-overlay");
if (assetsDirectory.exists()) {
commands.add("-A");
commands.add(assetsDirectory.getAbsolutePath());
}
for (Artifact artifact : getAllRelevantDependencyArtifacts()) {
if (artifact.getType().equals(APKLIB)) {
final String apkLibAssetsDir = getLibraryUnpackDirectory(artifact) + "/assets";
if (new File(apkLibAssetsDir).exists()){
commands.add("-A");
commands.add(apkLibAssetsDir);
}
}
}
commands.add("-I");
commands.add(getAndroidSdk().getAndroidJar().getAbsolutePath());
if (StringUtils.isNotBlank(configurations)) {
commands.add("-c");
commands.add(configurations);
}
getLog().info(getAndroidSdk().getPathForTool("aapt") + " " + commands.toString());
try {
executor.executeCommand(getAndroidSdk().getPathForTool("aapt"), commands, project.getBasedir(), false);
} catch (ExecutionException e) {
throw new MojoExecutionException("", e);
}
}
/**
* Given a map of source directories to list of AIDL (relative) filenames within each,
* runs the AIDL compiler for each, such that all source directories are available to
* the AIDL compiler.
*
* @param files Map of source directory File instances to the relative paths to all AIDL files within
* @throws MojoExecutionException If the AIDL compiler fails
*/
private void generateAidlFiles(Map files) throws MojoExecutionException {
List protoCommands = new ArrayList();
protoCommands.add("-p" + getAndroidSdk().getPathForFrameworkAidl());
File generatedSourcesAidlDirectory = new File(project.getBuild().getDirectory() + File.separator + "generated-sources" + File.separator + "aidl");
generatedSourcesAidlDirectory.mkdirs();
project.addCompileSourceRoot(generatedSourcesAidlDirectory.getPath());
Set sourceDirs = files.keySet();
for (File sourceDir : sourceDirs) {
protoCommands.add("-I" + sourceDir);
}
for (File sourceDir : sourceDirs) {
for (String relativeAidlFileName : files.get(sourceDir)) {
File targetDirectory = new File(generatedSourcesAidlDirectory, new File(relativeAidlFileName).getParent());
targetDirectory.mkdirs();
final String shortAidlFileName = new File(relativeAidlFileName).getName();
final String shortJavaFileName = shortAidlFileName.substring(0, shortAidlFileName.lastIndexOf(".")) + ".java";
final File aidlFileInSourceDirectory = new File(sourceDir, relativeAidlFileName);
List commands = new ArrayList(protoCommands);
commands.add(aidlFileInSourceDirectory.getAbsolutePath());
commands.add(new File(targetDirectory, shortJavaFileName).getAbsolutePath());
try {
CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor();
executor.setLogger(this.getLog());
executor.executeCommand(getAndroidSdk().getPathForTool("aidl"), commands, project.getBasedir(), false);
} catch (ExecutionException e) {
throw new MojoExecutionException("", e);
}
}
}
}
private String[] findRelativeAidlFileNames(File sourceDirectory) {
String[] relativeAidlFileNames = findFilesInDirectory(sourceDirectory, "**/*.aidl");
getLog().info("ANDROID-904-002: Found aidl files: Count = " + relativeAidlFileNames.length);
return relativeAidlFileNames;
}
/**
* @return true if the pom type is APK, APKLIB, or APKSOURCES
*/
private boolean isCurrentProjectAndroid() {
Set androidArtifacts = new HashSet() {{
addAll(Arrays.asList(APK, APKLIB, APKSOURCES));
}};
return androidArtifacts.contains(project.getArtifact().getType());
}
}