Java tutorial
/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.util; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Set; import net.rim.ejde.internal.core.ContextManager; import net.rim.ejde.internal.core.IConstants; import net.rim.ejde.internal.model.BasicBlackBerryProperties; import net.rim.ejde.internal.model.BlackBerryProject; import net.rim.ejde.internal.model.BlackBerryProjectCoreNature; import net.rim.ejde.internal.model.BlackBerryProperties; import net.rim.ejde.internal.model.BlackBerryPropertiesFactory; import net.rim.ejde.internal.model.BlackBerrySDKInstall; import net.rim.ejde.internal.model.BlackBerryVMInstallType; import net.rim.ejde.internal.validation.BBPropertiesValidator; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; /** * A util class to deal with the tasks needed for steps in the packaging process. * * @author jheifetz */ public class PackagingUtils { static Logger _log = Logger.getLogger(PackagingUtils.class); static char _replaceChar; /** * The index of standard deployment folder name */ static final public int STANDARD_DEPLOYMENT = 0; /** * The index of web deployment folder name */ static final public int WEB_DEPLOYMENT = 1; /** * Gets the default project output folder. * * @return the default project output folder */ public static String getDefaultProjectOutputPrefix() { return ContextManager.getDefault().getPreferenceStore() .getString(IConstants.PROJECT_OUTPUT_FOLDER_PREFIX_KEY); } /** * Gets the default generate alx file value. * * @return the default generate alx file value */ public static boolean getDefaultGenerateAlxFile() { return ContextManager.getDefault().getPreferenceStore().getBoolean(IConstants.GENERATE_ALX_FILE_KEY); } /** * Gets the default BlackBerry model version. * * @return the default BlackBerry model version */ public static String getDefaultModelVersion() { // ContextManager.getDefault().getPreferenceStore().getString( IConstants.BB_MODEL_VERSION ); return BasicBlackBerryProperties.DEFAULT_MODEL_VERSION; } /** * If the exported jars in a BlackBerry project should be packaged into the project's cod file. * * @return */ public static boolean getPackagExportedJar() { return ContextManager.getDefault().getPreferenceStore().getBoolean(IConstants.PACKAGE_EXPORTED_JAR); } /** * Cleans the contents of the project output folder. * * @param javaProj * the java project * * @throws CoreException * Exceptions in the process */ public static void cleanProjectOutputFolder(final IJavaProject javaProj) throws CoreException { if (javaProj != null) { boolean isBBProject = javaProj.getProject().hasNature(BlackBerryProjectCoreNature.NATURE_ID); final String projName = javaProj.getProject().getName(); BlackBerryProperties bbProperties = null; if (isBBProject) { bbProperties = ContextManager.PLUGIN.getBBProperties(projName, false); } else { bbProperties = BlackBerryPropertiesFactory.createBlackBerryProperties(javaProj); } if (bbProperties != null) { // clean the deployment files of the current project String[] outputFolderPaths = PackagingUtils .getPackagingOutputFolders(new BlackBerryProject(javaProj, bbProperties)); for (int i = 0; i < outputFolderPaths.length; i++) { String outputFolder = outputFolderPaths[i]; String outputFileN = bbProperties._packaging.getOutputFileName(); if ((null != outputFolder) && (null != outputFileN) && (outputFileN.length() > 0)) { final IResource outputFolderRes = javaProj.getProject().findMember(outputFolder); removeFiles((IContainer) outputFolderRes, null); } } // clean the deployment files of the dependency projects List<IJavaProject> dependentProjects = ProjectUtils.getAllReferencedJavaProjects(javaProj); String outputFileName; for (IJavaProject dependentProject : dependentProjects) { bbProperties = ContextManager.PLUGIN.getBBProperties(dependentProject.getProject().getName(), false); outputFileName = bbProperties._packaging.getOutputFileName(); outputFolderPaths = PackagingUtils .getPackagingOutputFolders(new BlackBerryProject(dependentProject, bbProperties)); for (int i = 0; i < outputFolderPaths.length; i++) { String outputFolder = outputFolderPaths[i]; if ((null != outputFolder) && (null != outputFileName) && (outputFileName.length() > 0)) { final IResource outputFolderRes = javaProj.getProject().findMember(outputFolder); removeFiles((IContainer) outputFolderRes, outputFileName); } } } } else { if (isBBProject) { throw new CoreException(new Status(IStatus.ERROR, ContextManager.PLUGIN_ID, "Cannot retrieve metadata from project " + projName)); } } } else { throw new CoreException(new Status(IStatus.ERROR, ContextManager.PLUGIN_ID, "Cannot change output folder for null IJavaProject")); } } private static void removeFiles(IContainer container, String fileName) throws CoreException { if ((container != null) && container.exists()) { IResource[] resources = (container).members(); for (final IResource child : resources) { if (StringUtils.isBlank(fileName) || child.getName().startsWith(fileName)) { child.delete(true, new NullProgressMonitor()); } } } } /** * Gets the bbsdk install for the given JavaProject * * @param javaProj * the java proj * * @return The BlackBerrySDKInstall for JavaProject or <code>null</code> */ public static BlackBerrySDKInstall getBBSDKInstall(IJavaProject javaProj) { if (javaProj == null) { return null; } try { IVMInstall vm = null; if (javaProj.getProject().hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { if (javaProj.getProject().isOpen()) { vm = JavaRuntime.getVMInstall(javaProj); if (vm != null && vm instanceof BlackBerrySDKInstall) { return (BlackBerrySDKInstall) vm; } } } else { if (javaProj.getProject().isOpen()) { // for java proejct, we use the default BB jre return (BlackBerrySDKInstall) VMUtils.getDefaultBBVM(); } } } catch (CoreException e) { _log.error(e); } return null; } /** * Get the output folder name of the BlackBerry JRE of the given <code>bbProject</code>. * * @param bbProject * @return */ public static String getVMOutputFolderName(BlackBerryProject bbProject) { BlackBerrySDKInstall bbVM = PackagingUtils.getBBSDKInstall(bbProject.getJavaProject()); if (bbVM == null) { return IConstants.DEFAULT_VM_OUTPUT_FOLDER_NAME; } String name = bbVM.getAttribute(BlackBerryVMInstallType.ATTR_RAPC_OUTPUT_FOLDER); if (name == null) { return IConstants.DEFAULT_VM_OUTPUT_FOLDER_NAME; } return name; } /** * Gets the array of output folders of packaging. * * @param javaProj * the java proj * * @return The output folders of packaging. If there is not output folder found, an empty string array is returned not * <code>null</code>. * * @see PackagingUtils#STANDARD_DEPLOYMENT * @see PackagingUtils#WEB_DEPLOYMENT */ public static String[] getPackagingOutputFolders(BlackBerryProject bbProject) { String outputRootFolder = bbProject.getProperties()._packaging.getOutputFolder(); final BlackBerrySDKInstall bbVM = PackagingUtils.getBBSDKInstall(bbProject.getJavaProject()); String[] outputFolders; String outputFolderPrefix = StringUtils.isBlank(outputRootFolder) ? IConstants.EMPTY_STRING : outputRootFolder + IPath.SEPARATOR; if (bbVM != null) { outputFolders = new String[2]; final String outputFolderSuffix = bbVM.getAttribute(BlackBerryVMInstallType.ATTR_RAPC_OUTPUT_FOLDER); if ((outputFolderSuffix != null) && !StringUtils.isBlank(outputFolderSuffix)) { outputFolders[STANDARD_DEPLOYMENT] = outputFolderPrefix + getStandardDeploymentFolderName() + IPath.SEPARATOR + outputFolderSuffix; outputFolders[WEB_DEPLOYMENT] = outputFolderPrefix + getWebDeploymentFolderName() + IPath.SEPARATOR + outputFolderSuffix; } else { outputFolders[STANDARD_DEPLOYMENT] = outputFolderPrefix + getStandardDeploymentFolderName(); outputFolders[WEB_DEPLOYMENT] = outputFolderPrefix + getWebDeploymentFolderName(); } } else { outputFolders = new String[2]; outputFolders[STANDARD_DEPLOYMENT] = outputFolderPrefix + getStandardDeploymentFolderName(); outputFolders[WEB_DEPLOYMENT] = outputFolderPrefix + getWebDeploymentFolderName(); } return outputFolders; } /** * Gets the relative web output folder. * * @param bbProject * @return */ public static String getRelativeWebOutputFolder(BlackBerryProject bbProject) { String[] outputFolders = getPackagingOutputFolders(bbProject); if (outputFolders.length > WEB_DEPLOYMENT) { return outputFolders[WEB_DEPLOYMENT]; } else { return IConstants.EMPTY_STRING; } } /** * Gets the relative standard output folder. * * @param bbProject * @return */ public static String getRelativeStandardOutputFolder(BlackBerryProject bbProject) { String[] outputFolders = getPackagingOutputFolders(bbProject); if (outputFolders.length > STANDARD_DEPLOYMENT) { return outputFolders[STANDARD_DEPLOYMENT]; } else { return IConstants.EMPTY_STRING; } } /** * Gets the relative standard output folder for the given <code>vm</code>. * * @param bbProject * @return */ public static String getRelativeStandardOutputFolder(BlackBerryProject bbProject, BlackBerrySDKInstall vm) { String bbVersion = vm.getAttribute(BlackBerryVMInstallType.ATTR_RAPC_OUTPUT_FOLDER); String outputFolder = bbProject.getProperties()._packaging.getOutputFolder(); if (!StringUtils.isBlank(outputFolder)) { outputFolder += IPath.SEPARATOR + getStandardDeploymentFolderName() + IPath.SEPARATOR + bbVersion; } else { outputFolder = getStandardDeploymentFolderName(); } return outputFolder; } /** * Gets the output folder of alx file. * * @param bbProject * @return */ public static String getRelativeAlxFileOutputFolder(BlackBerryProject bbProject) { String outputFolder = bbProject.getProperties()._packaging.getOutputFolder(); if (!StringUtils.isBlank(outputFolder)) { outputFolder += IPath.SEPARATOR + getStandardDeploymentFolderName(); } else { outputFolder = getStandardDeploymentFolderName(); } return outputFolder; } /** * Gets the absolute path of the output file for standard deployment, e.g. * c:/workspace/project1/deliverable/Standard/5.0.0/Helloworld * * @param project * @return */ static public IPath getAbsoluteStandardOutputFilePath(BlackBerryProject bbProject) { IPath standardOutputPath = bbProject.getProject().getLocation(); standardOutputPath = standardOutputPath.append(getRelativeStandardOutputFilePath(bbProject)); return standardOutputPath; } /** * Gets the relative path of the output file for standard deployment, e.g. /deliverable/Standard/5.0.0/Helloworld. * * @param project * @return */ static public IPath getRelativeStandardOutputFilePath(BlackBerryProject bbProject) { String[] outputPaths = getPackagingOutputFolders(bbProject); IPath standardOutputPath = new Path(outputPaths[STANDARD_DEPLOYMENT]); standardOutputPath = standardOutputPath.append(bbProject.getProperties()._packaging.getOutputFileName()); return standardOutputPath; } /** * Gets the web deployment folder name. * * @return */ public static String getWebDeploymentFolderName() { return ImportUtils.getImportPref("web_deployment_folder_name"); } /** * Gets the standard deployment folder name. * * @return */ public static String getStandardDeploymentFolderName() { return ImportUtils.getImportPref("standard_deployment_folder_name"); } /** * Replaces special characters in the given string to conform to Java standard. * * @param val * @return */ public static String replaceSpecialChars(String val) { // replace special characters final char replaceChr = getProjectOutputReplaceChar(); for (char chr : BBPropertiesValidator.CHARS_WARN) { if (val.indexOf(chr) >= 0 && replaceChr != 0) { val = val.replace(chr, replaceChr); } } // append "_" in front if the first character is digit if (!val.isEmpty() && Character.isDigit(val.charAt(0))) { val = IConstants.UNDERSCORE_STRING + val; } return val; } /** * Returns the preferences.ini project_output_file_replace_space or 0 * * @return */ public static char getProjectOutputReplaceChar() { if (_replaceChar <= 0) { String replaceVal; if ((replaceVal = ContextManager.getDefault().getPreferenceStore() .getString(IConstants.PROJECT_OUTPUT_FILE_REPLACE_CHAR)) != null && replaceVal.length() > 0) { _replaceChar = replaceVal.charAt(0); } } return _replaceChar; } public static String[] getDependantProjectOutputFolders(BlackBerryProject parentProject, BlackBerryProject dependantProject) { String outputRootFolder = parentProject.getProperties()._packaging.getOutputFolder(); final BlackBerrySDKInstall bbVM = PackagingUtils.getBBSDKInstall(dependantProject.getJavaProject()); String[] outputFolders = null; if (bbVM != null) { outputFolders = new String[2]; final String outputFolderSuffix = bbVM.getAttribute(BlackBerryVMInstallType.ATTR_RAPC_OUTPUT_FOLDER); String outputFolderPrefix = StringUtils.isBlank(outputRootFolder) ? IConstants.EMPTY_STRING : outputRootFolder + IPath.SEPARATOR; if ((outputFolderSuffix != null) && !StringUtils.isBlank(outputFolderSuffix)) { outputFolders[STANDARD_DEPLOYMENT] = outputFolderPrefix + getStandardDeploymentFolderName() + IPath.SEPARATOR + outputFolderSuffix; outputFolders[WEB_DEPLOYMENT] = outputFolderPrefix + getWebDeploymentFolderName() + IPath.SEPARATOR + outputFolderSuffix; } else { outputFolders[STANDARD_DEPLOYMENT] = outputFolderPrefix + getStandardDeploymentFolderName(); outputFolders[WEB_DEPLOYMENT] = outputFolderPrefix + getWebDeploymentFolderName(); } } return outputFolders; } public static List<String> getCodFilePathsFromProjects(Set<BlackBerryProject> projects) { List<String> codFiles = new ArrayList<String>(); // Add the output files. These are the *.cod's of all active projects in // the RIM workspace for (BlackBerryProject project : projects) { String outputFolderPath = project.getProject().getLocation().toOSString() + File.separator + getRelativeStandardOutputFolder(project); String outputFileName = project.getProperties()._packaging.getOutputFileName(); File codFile = new File( outputFolderPath + File.separator + outputFileName + IConstants.COD_FILE_EXTENSION_WITH_DOT); File cslFile; codFiles.add(codFile.getPath()); try { List<BlackBerryProject> dependantProjects = ProjectUtils.getAllReferencedProjects(project); for (BlackBerryProject dependantProject : dependantProjects) { outputFolderPath = project.getProject().getLocation().toOSString() + File.separator + getRelativeStandardOutputFolder(dependantProject); outputFileName = dependantProject.getProperties()._packaging.getOutputFileName(); codFile = new File(outputFolderPath + File.separator + outputFileName + IConstants.COD_FILE_EXTENSION_WITH_DOT); cslFile = new File(outputFolderPath + File.separator + outputFileName + IConstants.CSL_FILE_EXTENSION_WITH_DOT); // The signature tool brakes if we add a file that doesn't exist to // the list of files to import. This might happen if a project has // build errors, for instance. if (codFile.exists() && cslFile.exists()) { codFiles.add(codFile.getPath()); } } } catch (CoreException ce) { _log.error("launchSignatureTool: Cannot find dependant projects ", ce); } } return codFiles; } /** * Returns if the given <code>BlackBerryProject</code> needs to be signed. This method only checks the * <code>BlackBerryProject</code> itself. * * @param project * The project to be tested * @return <code>true</code> if the project needs to be signed; otherwise returns <code>false</code> */ public static boolean isSigningNeeded(BlackBerryProject project) { boolean signingNeeded = false; String outputFolderPath = project.getProject().getLocation().toOSString() + File.separator + getRelativeStandardOutputFolder(project); String outputFileName = project.getProperties()._packaging.getOutputFileName(); File codFile = new File( outputFolderPath + File.separator + outputFileName + IConstants.COD_FILE_EXTENSION_WITH_DOT); File cslFile = new File( outputFolderPath + File.separator + outputFileName + IConstants.CSL_FILE_EXTENSION_WITH_DOT); if (codFile.exists() && cslFile.exists()) { signingNeeded = true; } return signingNeeded; } /** * Returns if the given <code>BlackBerryProject</code> or any of its dependent projects needs to be signed * * @param bbProject * @return <code>true</code> if the project or any of its dependent project needs to be signed; otherwise returns * <code>false</code> */ public static boolean isSigningNeededForDependency(BlackBerryProject bbProject) { try { if (isSigningNeeded(bbProject)) { return true; } List<BlackBerryProject> dependencies = ProjectUtils.getAllReferencedProjects(bbProject); for (BlackBerryProject project : dependencies) { if (isSigningNeeded(project)) { return true; } } return false; } catch (CoreException e) { _log.error(e); return false; } } /** * Gets the custom jad file form the root of the given <code>project</code>. * * @param bbproj * @return */ public static String getCustomJadFile(BlackBerryProject bbproj) { return getProjectCustomFile(bbproj, IConstants.JAD_FILE_EXTENSION); } /** * Gets the custom rapc file from the root of the given <code>project</code>. * * @param bbproj * @return */ public static String getCustomRapcFile(BlackBerryProject bbproj) { return getProjectCustomFile(bbproj, IConstants.RAPC_FILE_EXTENSION); } /** * Gets the custom file with given <project-name>.<code>fileExtension</code> form the root of the <code>project</code>. * * @param bbproj * @return */ public static String getProjectCustomFile(BlackBerryProject bbproj, String fileExtension) { if (bbproj != null && !StringUtils.isEmpty(fileExtension)) { try { IProject project = bbproj.getProject(); IResource[] resources = project.members(); for (IResource res : resources) { if ((res instanceof IFile) && fileExtension.equalsIgnoreCase(res.getFileExtension())) { String resn = res.getName().substring(0, res.getName().length() - fileExtension.length() - 1); if (resn.equals(bbproj.getProperties()._packaging.getOutputFileName()) || resn.equals(project.getName())) { return res.getLocation().toOSString(); } } } } catch (CoreException e) { _log.error(e); } } return null; } }