package com.mobilesorcery.sdk.builder.blackberry; import java.io.File; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import com.mobilesorcery.sdk.builder.java.JavaPackager; import com.mobilesorcery.sdk.builder.java.KeystoreCertificateInfo; import com.mobilesorcery.sdk.core.CommandLineBuilder; import com.mobilesorcery.sdk.core.CoreMoSyncPlugin; import com.mobilesorcery.sdk.core.IBuildResult; import com.mobilesorcery.sdk.core.IBuildVariant; import com.mobilesorcery.sdk.core.MoSyncProject; import com.mobilesorcery.sdk.core.MoSyncTool; import com.mobilesorcery.sdk.core.ParameterResolverException; import com.mobilesorcery.sdk.core.PreferenceStorePropertyOwner; import com.mobilesorcery.sdk.core.PropertyUtil; import com.mobilesorcery.sdk.core.Util; import com.mobilesorcery.sdk.core.Version; import com.mobilesorcery.sdk.profiles.IProfile; public class BlackBerryPackager extends JavaPackager { public static final String ID = "com.mobilesorcery.sdk.builder.blackberry"; @Override protected void addPlatformSpecifics(MoSyncProject project, IBuildVariant variant, CommandLineBuilder commandLine) throws Exception { if (project.getProfileManagerType() != MoSyncTool.DEFAULT_PROFILE_TYPE) { throw new CoreException(new Status(IStatus.OK, BlackBerryPlugin.PLUGIN_ID, "Can only package BlackBerry with platform-based profiles")); } boolean packAsCOD = shouldPackAsCOD(project, variant); if (!packAsCOD) { // TODO: Warning; but we'll wait until we've re-enabled cod packaging } if (packAsCOD) { commandLine.flag("--blackberry-packcod"); JDE jde = matchingJDE(JDE.TYPE_DEV_TOOLS, project, variant.getProfile()); commandLine.flag("--blackberry-jde").with(jde.getLocation().toFile()); if (shouldSign(project)) { // We just reuse this java cert info, it's not quite blackberry-ish... KeystoreCertificateInfo certInfo = KeystoreCertificateInfo.loadOne( BlackBerryPlugin.BLACKBERRY_SIGNING_INFO, new PreferenceStorePropertyOwner(BlackBerryPlugin.getDefault().getPreferenceStore()), CoreMoSyncPlugin.getDefault().getSecureProperties()); String signFileKey = (certInfo == null ? null : certInfo.getKeyPassword()); if (Util.isEmpty(signFileKey)) { throw new CoreException(new Status(IStatus.OK, BlackBerryPlugin.PLUGIN_ID, "No key password for blackberry signing. Please note that for security reasons, passwords are locally stored. You may need to set the password in the BlackBerry preference page.")); } commandLine.flag("--blackberry-signkey").with(signFileKey); } } } private boolean shouldPackAsCOD(MoSyncProject project, IBuildVariant variant) { JDE jde = matchingJDE(JDE.TYPE_DEV_TOOLS, project, variant.getProfile()); return jde != null; } @Override public Map<String, List<File>> computeBuildResult(MoSyncProject project, IBuildVariant variant) throws ParameterResolverException { if (shouldPackAsCOD(project, variant)) { File jar = super.getProducedJar(project, variant); File cod = new File(Util.replaceExtension(jar.getAbsolutePath(), "cod")); Map<String, List<File>> result = new HashMap<String, List<File>>(); result.put(IBuildResult.MAIN, Arrays.asList(cod)); result.put(BlackBerryPlugin.JAD, Arrays.asList(cod)); return result; } else { return super.computeBuildResult(project, variant); } } /*@Override public void createPackage(MoSyncProject project, IBuildSession session, IBuildVariant variant, IFileTreeDiff diff, IBuildResult buildResult) throws CoreException { // Create a MIDlet super.createPackage(project, session, variant, diff, buildResult); File jar = buildResult.getBuildResult(); // We null the build result in case of error buildResult.setBuildResult(null); // Convert the MIDlet to a cod file //String platform = variant.getProfile().getRuntime(); JDE jde = matchingJDE(project, variant.getProfile()); if (jde == null) { throw new CoreException(new Status(IStatus.ERROR, BlackBerryPlugin.PLUGIN_ID, "Found no matching JDE for Blackberry platform " + variant.getProfile())); } // We'll just replace the original jar File preverifiedJar = jar; try { jde.preverifyJAR(jar, preverifiedJar); } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, BlackBerryPlugin.PLUGIN_ID, "Could not preverify", e)); } File finalOutput = new File(jar.getParentFile(), Util.getNameWithoutExtension(jar) + ".cod"); // TODO: Jad location should not be implicit... File jad = new File(jar.getParentFile(), Util.getNameWithoutExtension(jar) + ".jad"); try { jde.convertJARToCOD(preverifiedJar, jad, finalOutput); } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, BlackBerryPlugin.PLUGIN_ID, "Could not convert to COD format (BlackBerry)", e)); } if (shouldSign(project)) { // At this point we only support ONE bb cert // We just reuse this java cert info, it's not quite blackberry-ish... KeystoreCertificateInfo certInfo = KeystoreCertificateInfo.loadOne( BlackBerryPlugin.BLACKBERRY_SIGNING_INFO, new PreferenceStorePropertyOwner(BlackBerryPlugin.getDefault().getPreferenceStore()), CoreMoSyncPlugin.getDefault().getSecureProperties()); if (Util.isEmpty(certInfo.getKeyPassword())) { throw new CoreException(new Status(IStatus.OK, BlackBerryPlugin.PLUGIN_ID, "No key password for blackberry signing. Please note that for security reasons, passwords are locally stored. You may need to set the password in the BlackBerry preference page.")); } // Sign it try { jde.sign(finalOutput, certInfo); } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, BlackBerryPlugin.PLUGIN_ID, "Could not sign BlackBerry app", e)); } } buildResult.setBuildResult(finalOutput); }*/ private boolean shouldSign(MoSyncProject project) { return PropertyUtil.getBoolean(project, BlackBerryPlugin.PROPERTY_SHOULD_SIGN); } public static JDE matchingJDE(int type, MoSyncProject project, IProfile profile) { Version version = new Version(profile.getName()); if (version.getMajor() == Version.UNDEFINED) { throw new IllegalArgumentException( "BlackBerry profiles must have a version number as name (eg 4.1)"); } if (type == JDE.TYPE_DEV_TOOLS) { return BlackBerryPlugin.getDefault().getCompatibleJDE(version, false); } else { return BlackBerryPlugin.getDefault().getCompatibleSimulator(version, false); } } public static boolean isSigningRequired(MoSyncProject project) { // Yep, it seems that not even PIM requires this? return false; } }