AbstractXCodeMojo.java
/*
* #%L
* xcode-maven-plugin
* %%
* Copyright (C) 2012 SAP AG
* %%
* 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.
* #L%
*/
package com.sap.prd.mobile.ios.mios;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.LogManager;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
/**
* Base class for Xcode specific mojos
*
*/
public abstract class AbstractXCodeMojo extends AbstractMojo
{
//
// This variable here ensures that a reference to the logger is kept.
// According to the API doc of the java.util.logging framework it is required
// to keep a reference. Otherwise it might happen that the logger is garbage
// collected. This in turn must not happen since the logger keeps a
// reference to the maven logger that could not be restored. This variable
// should not be accessed. Instead use the LogManager to get the instance.
//
private static XCodePluginLogger logger = null;
static {
if(null == LogManager.getLogManager().getLogger(XCodePluginLogger.getLoggerName())) {
logger = new XCodePluginLogger();
LogManager.getLogManager().addLogger(logger);
logger.finest(String.format("XCode plugin logger has been created: %s", logger.getName()));
}
}
/**
* The original Xcode sources located in the <code>src/xcode</code> directory stay untouched
* during the whole Maven build. However, as we might have to modify the info.plist or the project
* itself we copy the whole Xcode source directory during the build into another "checkout"
* directory that by default named <code>checkout</code> and located below the Maven build (
* <code>target</code>) directory.
*
* @parameter expression="${xcode.checkoutDirectory}";
*/
private File checkoutDirectory;
/**
* The xcode directory of the copied sources below the checkout directory.
*
* @parameter expression="${xcode.compileDirectory}"
*/
private File xcodeCompileDirectory;
/**
* @parameter expression="${project}"
* @readonly
* @required
*/
protected MavenProject project;
/**
* The Xcode configurations that shall be built (e.g. Debug and Release).
*
* If no configuration is provided in the plugin's <code>configuration</code> section of the
* <code>pom.xml</code> it defaults to the values provided in the
* <code>defaultAppConfigurations</code> or <code>defaultLibConfigurations</code> parameters
*
* @parameter
*/
private Set<String> configurations;
/**
* @parameter expression="${project.packaging}"
* @readonly
* @required
*/
protected String packaging;
/**
* Explicit lists of sdks (iphoneos,iphonesimulator) the Xcode project shall be built for.
*
* If no configuration is provided in the plugin's <code>configuration</code> section of the
* <code>pom.xml</code> it defaults to the values provided in the <code>defaultAppSdks</code> or
* <code>defaultLibSdks</code> parameters
*
* @parameter
*/
private Set<String> sdks;
/**
* Comma separated list of the default Xcode build configurations that should be built for apps
* (in contrast to libraries). These values only apply if no "configurations" are explicitly
* provided in the POM.
*
* @parameter expression="${xcode.app.defaultConfigurations}" default-value="Release,Debug"
* @since 1.2.0
*
*/
private String defaultAppConfigurations;
/**
* Comma separated list of the default Xcode build configurations that should be built for
* libraries (in contrast to apps). These values only apply if no "configurations" are explicitly
* provided in the POM.
*
* @parameter expression="${xcode.lib.defaultConfigurations}" default-value="Release,Debug"
* @since 1.2.0
*
*/
private String defaultLibConfigurations;
/**
* Comma separated list of the default Xcode SDKs that should be used for apps (in contrast to
* libs). These values only apply if no "sdks" are explicitly provided in the POM.
*
* @parameter expression="${xcode.app.defaultSdks}" default-value="iphoneos,iphonesimulator"
* @since 1.2.0
*
*/
private String defaultAppSdks;
/**
* Comma separated list of the default Xcode SDKs that should be used for libraries (in contrast
* to apps). These values only apply if no "sdks" are explicitly provided in the POM.
*
* @parameter expression="${xcode.lib.defaultSdks}" default-value="iphoneos,iphonesimulator"
* @since 1.2.0
*
*/
private String defaultLibSdks;
protected Set<String> getSDKs()
{
if (sdks == null || sdks.isEmpty()) {
try {
PackagingType packagingType = PackagingType.getByMavenType(packaging);
if (packagingType == PackagingType.APP) {
getLog().info(
"No SDKs in POM set. Using default configurations for applications: " + defaultAppSdks);
return commaSeparatedStringToSet(defaultAppSdks);
}
else if (packagingType == PackagingType.LIB || packagingType == PackagingType.FRAMEWORK) {
getLog().info(
"No SDKs in POM set. Using default configurations for libraries: " + defaultLibSdks);
return commaSeparatedStringToSet(defaultLibSdks);
}
}
catch (PackagingType.UnknownPackagingTypeException e) {
getLog().info("Unknown PackagingType found.", e);
return Collections.emptySet();
}
}
getLog().info("SDKs have been explicitly set in POM: " + sdks);
return sdks;
}
protected Set<String> getConfigurations()
{
if (configurations == null || configurations.isEmpty()) {
try {
PackagingType packagingType = PackagingType.getByMavenType(packaging);
if (packagingType == PackagingType.APP) {
getLog().info(
"No configurations in POM set. Using default configurations for applications: "
+ defaultAppConfigurations);
return commaSeparatedStringToSet(defaultAppConfigurations);
}
else if (packagingType == PackagingType.LIB || packagingType == PackagingType.FRAMEWORK) {
getLog()
.info(
"No configurations in POM set. Using default configurations for libraries: "
+ defaultLibConfigurations);
return commaSeparatedStringToSet(defaultLibConfigurations);
}
}
catch (PackagingType.UnknownPackagingTypeException e) {
getLog().info("Unknown PackagingType found.", e);
return Collections.emptySet();
}
}
getLog().info("Configurations have been explicitly set in POM: " + configurations);
return configurations;
}
private Set<String> commaSeparatedStringToSet(String commaSeparetedValues)
{
Set<String> values = new HashSet<String>();
String[] valueArray = commaSeparetedValues.split(",");
for (String value : valueArray) {
value = value.trim();
if (!value.isEmpty()) {
values.add(value);
}
}
return Collections.unmodifiableSet(values);
}
protected File getCheckoutDirectory()
{
return checkoutDirectory;
}
/**
* The xcode directory of the copied sources below the checkout directory.
*/
protected File getXCodeCompileDirectory()
{
return xcodeCompileDirectory;
}
/**
*
* @return the <code>src/xcode</code> directory
*/
protected File getXCodeSourceDirectory()
{
return new File(project.getBuild().getSourceDirectory());
}
protected String getFixedProductName(final String productName)
{
return productName.trim().replaceAll(" ", "");
}
protected File getXCodeProjectFile()
{
return new File(getXCodeCompileDirectory(), project.getArtifactId() + ".xcodeproj/project.pbxproj");
}
/**
* Calls a shell script in order to zip a folder. We have to call a shell script as Java cannot
* zip symbolic links.
*
* @param rootDir
* the directory where the zip command shall be executed
* @param zipSubFolder
* the subfolder to be zipped
* @param zipFileName
* the name of the zipFile (will be located in the rootDir)
* @param archiveFolder
* an optional folder name if the zipSubFolder folder shall be placed inside the zip into
* a parent folder
* @return the zip file
* @throws MojoExecutionException
*/
protected File zipSubfolder(File rootDir, String zipSubFolder, String zipFileName, String archiveFolder)
throws MojoExecutionException
{
int resultCode = 0;
try {
File scriptDirectory = new File(project.getBuild().getDirectory(), "scripts").getCanonicalFile();
scriptDirectory.deleteOnExit();
if (archiveFolder != null)
{
resultCode = ScriptRunner.copyAndExecuteScript(System.out, "/com/sap/prd/mobile/ios/mios/zip-subfolder.sh",
scriptDirectory, rootDir.getCanonicalPath(), zipSubFolder, zipFileName, archiveFolder);
}
else
{
resultCode = ScriptRunner.copyAndExecuteScript(System.out, "/com/sap/prd/mobile/ios/mios/zip-subfolder.sh",
scriptDirectory, rootDir.getCanonicalPath(), zipSubFolder, zipFileName);
}
}
catch (Exception ex) {
throw new MojoExecutionException("Cannot create zip file " + zipFileName + ". Check log for details.", ex);
}
if (resultCode != 0) {
throw new MojoExecutionException("Cannot create zip file " + zipFileName + ". Check log for details.");
}
getLog().info("Zip file '" + zipFileName + "' created.");
return new File(rootDir, zipFileName);
}
}