use of com.twinsoft.convertigo.beans.mobileplatforms.IOs in project convertigo by convertigo.
the class CLI method installCordova.
public Map<String, BuildLocally> installCordova(Project project, List<String> platforms) throws EngineException {
List<MobilePlatform> mobilePlatforms;
MobileApplication mobileApplication = project.getMobileApplication();
if (platforms == null || platforms.isEmpty()) {
mobilePlatforms = mobileApplication.getMobilePlatformList();
} else {
mobilePlatforms = new ArrayList<>(platforms.size());
for (String platform : platforms) {
try {
mobilePlatforms.add(mobileApplication.getMobilePlatformByName(platform));
} catch (EngineException e) {
Engine.logConvertigo.error("Failed to find the mobile platform: " + platform, e);
}
}
}
Map<String, BuildLocally> localBuilders = new HashMap<>(mobilePlatforms.size());
for (MobilePlatform platform : mobilePlatforms) {
if (platform instanceof IOs && !Engine.isMac()) {
Engine.logConvertigo.info("Skip IOs build because this is not Mac OS.");
continue;
}
BuildLocally localBuilder = new BuildLocally(platform) {
@Override
protected void showLocationInstallFile(MobilePlatform mobilePlatform, int exitValue, String errorLines, String buildOption) {
Engine.logConvertigo.error("BuildLocally location: " + exitValue + " error: " + errorLines + " options: " + buildOption);
}
@Override
protected void logException(Throwable e, String message) {
Engine.logConvertigo.error("BuildLocally exception: " + message, e);
}
@Override
protected String getLocalBuildAdditionalPath() {
// TODO Auto-generated method stub
return null;
}
};
Engine.logConvertigo.info("Checking cordova ...");
Status status = localBuilder.installCordova();
Engine.logConvertigo.info("Cordova: " + status);
localBuilders.put(platform.getName(), localBuilder);
}
return localBuilders;
}
use of com.twinsoft.convertigo.beans.mobileplatforms.IOs in project convertigo by convertigo.
the class XPathToCheck method migrate.
public static void migrate(String projectName) {
try {
Project project = Engine.theApp.databaseObjectsManager.getOriginalProjectByName(projectName, false);
MobileApplication mobileApplication = project.getMobileApplication();
if (mobileApplication != null) {
TwsCachedXPathAPI xpathApi = new TwsCachedXPathAPI();
// Tags to change for all platforms
List<XPathToCheck> xPathToCheckDefault = new LinkedList<XPathToCheck>();
xPathToCheckDefault.add(new XPathToCheck("/widget/preference[@name='phonegap-version']", "", true));
xPathToCheckDefault.add(new XPathToCheck("/widget/preference[@name='SplashScreen']", "", true));
xPathToCheckDefault.add(new XPathToCheck("/widget/preference[@name='ShowSplashScreenSpinner']", "", true));
String[][] pluginList = new String[][] { { "org.apache.cordova.device", "org.apache.cordova.file", "org.apache.cordova.file-transfer", "org.apache.cordova.splashscreen", "cordova-plugin-whitelist", "org.apache.cordova.console" }, { "cordova-plugin-device", "cordova-plugin-file", "cordova-plugin-file-transfer", "cordova-plugin-splashscreen", "cordova-plugin-whitelist", "cordova-plugin-console" } };
for (int i = 0; i < pluginList[0].length; i++) {
xPathToCheckDefault.add(new XPathToCheck("/widget/*[local-name()='plugin' and @name='" + pluginList[0][i] + "']", "/widget/plugin[@name='" + pluginList[1][i] + "']", true));
xPathToCheckDefault.add(new XPathToCheck("/widget/*[local-name()='plugin' and @name='" + pluginList[1][i] + "']", "/widget/plugin[@name='" + pluginList[1][i] + "']", true));
}
pluginList = new String[][] { { "com.couchbase.lite.phonegap", "org.apache.cordova.battery-status", "org.apache.cordova.camera", "org.apache.cordova.media-capture", "org.apache.cordova.contacts", "org.apache.cordova.device-motion", "org.apache.cordova.device-orientation", "org.apache.cordova.dialogs", "org.apache.cordova.geolocation", "org.apache.cordova.globalization", "org.apache.cordova.inappbrowser", "org.apache.cordova.media", "org.apache.cordova.network-information", "org.apache.cordova.vibration", "org.apache.cordova.statusbar", "com.phonegap.plugins.pushplugin", "com.phonegap.plugins.barcodescanner" }, { "couchbase-lite-phonegap-plugin", "cordova-plugin-battery-status", "cordova-plugin-camera", "cordova-plugin-media-capture", "cordova-plugin-contacts", "cordova-plugin-device-motion", "cordova-plugin-device-orientation", "cordova-plugin-dialogs", "cordova-plugin-geolocation", "cordova-plugin-globalization", "cordova-plugin-inappbrowser", "cordova-plugin-media", "cordova-plugin-network-information", "cordova-plugin-vibration", "cordova-plugin-statusbar", "phonegap-plugin-push", "phonegap-plugin-barcodescanner" } };
// Tags to change only for Android
List<XPathToCheck> xPathToCheckAndroid = new LinkedList<XPathToCheck>();
xPathToCheckAndroid.addAll(xPathToCheckDefault);
xPathToCheckAndroid.add(new XPathToCheck("/widget/platform[@name='android' and not(*)]", "/widget/engine[@name='$(CordovaPlatform)$']", true));
xPathToCheckAndroid.add(new XPathToCheck("/widget/preference[@name='android-minSdkVersion']", "", true));
xPathToCheckAndroid.add(new XPathToCheck("/widget/preference[@name='android-build-tool']", "", true));
String[] androidResList = new String[] { "ldpi", "mdpi", "hdpi", "xhdpi" };
for (String androidRes : androidResList) {
xPathToCheckAndroid.add(new XPathToCheck("/widget/icon[@gap:platform='android' and @gap:qualifier='" + androidRes + "']", "/widget/platform[@name='android']/icon[@density='" + androidRes + "']", false));
}
androidResList = new String[] { "ldpi", "mdpi", "hdpi", "xhdpi", "land-ldpi", "land-mdpi", "land-hdpi", "land-xhdpi" };
for (String androidRes : androidResList) {
xPathToCheckAndroid.add(new XPathToCheck("/widget/splash[@gap:platform='android' and @gap:qualifier='" + androidRes + "']", "/widget/platform[@name='android']/splash[@density='" + androidRes + "']", false));
}
// Tags to change only for iOS
List<XPathToCheck> xPathToCheckIOs = new LinkedList<XPathToCheck>();
xPathToCheckIOs.addAll(xPathToCheckDefault);
xPathToCheckIOs.add(new XPathToCheck("/widget/platform[@name='ios']", "/widget/engine[@name='$(CordovaPlatform)$']", true));
xPathToCheckIOs.add(new XPathToCheck("/widget/preference[@name='target-device' and @value='universal']", null, true));
String[] iosResList = new String[] { "180", "120", "57", "72", "114", "144" };
for (String iosRes : iosResList) {
xPathToCheckIOs.add(new XPathToCheck("/widget/icon[@gap:platform='ios' and @width='" + iosRes + "']", "/widget/platform[@name='ios']/icon[@width='" + iosRes + "']", false));
}
iosResList = new String[] { "2208", "1334", "1136", "1496", "748", "2008", "1004", "960", "480" };
for (String iosRes : iosResList) {
xPathToCheckIOs.add(new XPathToCheck("/widget/splash[@gap:platform='ios' and @height='" + iosRes + "']", "/widget/platform[@name='ios']/splash[@height='" + iosRes + "']", false));
}
xPathToCheckIOs.add(new XPathToCheck("/widget/access", "", true));
// Tags to change only for Windows Phone 8
List<XPathToCheck> xPathToCheckWinPhone8 = new LinkedList<XPathToCheck>();
xPathToCheckWinPhone8.addAll(xPathToCheckDefault);
xPathToCheckWinPhone8.add(new XPathToCheck("/widget/platform[@name='winphone' and not(*)]", "/widget/engine[@name='$(CordovaPlatform)$']", true));
xPathToCheckWinPhone8.add(new XPathToCheck("/widget/icon[@gap:platform='winphone' and not(@gap:role)]", "/widget/platform[@name='wp8']/icon[not(@role)]", false));
xPathToCheckWinPhone8.add(new XPathToCheck("/widget/icon[@gap:platform='winphone' and @gap:role='background']", "/widget/platform[@name='wp8']/icon[@role='background']", false));
xPathToCheckWinPhone8.add(new XPathToCheck("/widget/splash[@gap:platform='winphone']", "/widget/platform[@name='wp8']/splash[@src]", false));
// Iterates on each platforms
List<MobilePlatform> mobilePlatformList = mobileApplication.getMobilePlatformList();
for (MobilePlatform mobilePlatform : mobilePlatformList) {
// Get the config.xml file and load the xml
File configFile = new File(mobilePlatform.getResourceFolder(), "config.xml");
if (configFile.exists()) {
Document oldDoc = XMLUtils.loadXml(configFile);
// Gets the tags to change depending to the platform
List<XPathToCheck> xPathToCheckList = null;
String platformName = null;
if (mobilePlatform instanceof Android) {
xPathToCheckList = xPathToCheckAndroid;
platformName = "Android";
} else if (mobilePlatform instanceof IOs) {
xPathToCheckList = xPathToCheckIOs;
platformName = "IOs";
} else if (mobilePlatform instanceof WindowsPhone8) {
xPathToCheckList = xPathToCheckWinPhone8;
platformName = "WindowsPhone8";
} else {
continue;
}
// Gets the template config.xml file and load the xml
String configTemplatePath = Engine.TEMPLATES_PATH + "/base/DisplayObjects/platforms/" + platformName + "/config.xml";
File configTemplateFile = new File(configTemplatePath);
if (!configTemplateFile.exists()) {
throw new Exception("Can't find template config.xml at " + configTemplatePath);
}
Document templateDoc = XMLUtils.loadXml(configTemplateFile);
for (XPathToCheck xPathToCheck : xPathToCheckList) {
Element oldElement = (Element) xpathApi.selectSingleNode(oldDoc, xPathToCheck.oldXpath);
// If the goal is to remove the old node
if (xPathToCheck.templateXpath == null) {
if (oldElement != null) {
oldElement.getParentNode().removeChild(oldElement);
}
continue;
}
Element templateElement = (Element) xpathApi.selectSingleNode(templateDoc, xPathToCheck.templateXpath);
// Can't do anything if the element is not found in the template file
if (templateElement == null) {
continue;
}
// Replace the old element by the template
if (oldElement != null || xPathToCheck.required) {
// If the template is already in the old config.xml
Element templateOldElement = (Element) xpathApi.selectSingleNode(oldDoc, xPathToCheck.templateXpath);
if (templateOldElement != null && templateElement.isEqualNode(templateOldElement)) {
continue;
}
String xPathTemplateParent = xPathToCheck.templateXpath.substring(0, xPathToCheck.templateXpath.lastIndexOf('/'));
Node parentNode = createSameTree(oldDoc, templateElement.getParentNode(), xPathTemplateParent, xpathApi);
Node newNode = oldDoc.adoptNode(templateElement.cloneNode(true));
if (oldElement != null) {
if (parentNode.isSameNode(oldElement.getParentNode())) {
parentNode.replaceChild(newNode, oldElement);
} else {
parentNode.appendChild(newNode);
oldElement.getParentNode().removeChild(oldElement);
}
} else {
parentNode.appendChild(newNode);
}
}
}
for (int i = 0; i < pluginList[0].length; i++) {
Node comment = xpathApi.selectNode(oldDoc, "//comment()[contains(.,\"" + pluginList[1][i] + "\")]");
if (comment == null) {
comment = xpathApi.selectNode(oldDoc, "//comment()[contains(.,\"" + pluginList[0][i] + "\")]");
}
if (comment != null) {
Node newComment = xpathApi.selectNode(templateDoc, "//comment()[contains(.,\"" + pluginList[1][i] + "\")]");
comment.getParentNode().replaceChild(oldDoc.adoptNode(newComment), comment);
}
}
File oldConfigFile = new File(configFile.getParent(), "config.xml.old");
if (!oldConfigFile.exists()) {
oldConfigFile.createNewFile();
}
FileUtils.copyFile(configFile, oldConfigFile);
File newConfigFile = new File(mobilePlatform.getResourceFolder(), "config.xml");
if (!newConfigFile.exists()) {
newConfigFile.createNewFile();
}
XMLUtils.saveXml(oldDoc, newConfigFile.getAbsolutePath());
}
}
}
} catch (Exception e) {
Engine.logDatabaseObjectManager.error("[Migration 7.4.0] An error occured while migrating project \"" + projectName + "\"", e);
}
}
use of com.twinsoft.convertigo.beans.mobileplatforms.IOs in project convertigo by convertigo.
the class BuildLocally method checkPlatformCompatibility.
/**
* Check is the current os can build the specified platform.
* @param platform
* @return
* @throws Throwable
*/
public boolean checkPlatformCompatibility() throws Throwable {
// Implement Compatibility matrix
// Step 1: Check cordova version, compatibility over 3.4.x
String version = getCordovaVersion();
Pattern pattern = Pattern.compile("^(\\d)+\\.(\\d)+\\.");
Matcher matcher = pattern.matcher(version);
if (matcher.find()) {
// We check first just the decimal part
if (Integer.parseInt(matcher.group(1)) < versionMinimalRequiredDecimalPart) {
return false;
// Next we check the fractional part
} else if (Integer.parseInt(matcher.group(1)) == versionMinimalRequiredDecimalPart && Integer.parseInt(matcher.group(2)) < versionMinimalRequiredFractionalPart) {
return false;
}
} else {
return false;
}
// Step 2: Check build local platform with mobile platform
if (mobilePlatform instanceof Android) {
return true;
} else if (mobilePlatform instanceof IOs) {
return is(OS.mac);
} else if (mobilePlatform.getType().startsWith("Windows")) {
return is(OS.win32);
}
return false;
}
use of com.twinsoft.convertigo.beans.mobileplatforms.IOs in project convertigo by convertigo.
the class BuildLocally method runBuild.
public Status runBuild(String option, boolean run, String target) {
try {
File cordovaDir = getCordovaDir();
File wwwDir = new File(cordovaDir, "www");
wwwDir.mkdirs();
if (!wwwDir.exists()) {
throw new EngineException("Cannot create the build folder '" + wwwDir.getAbsolutePath() + "', check the current user can create files or change the Eclipse preference: 'Convertigo/Studio/Local Build Folder'.");
}
// Cordova environment is already created, we have to build
// Step 1: Call Mobile packager to prepare the source package
MobileResourceHelper mobileResourceHelper = new MobileResourceHelper(mobilePlatform, wwwDir.getAbsolutePath());
wwwDir = mobileResourceHelper.preparePackage();
// Step 2: Add platform and read config.xml to copy needed icons and splash resources
String cordovaPlatform = mobilePlatform.getCordovaPlatform();
//
FileUtils.copyFile(new File(wwwDir, "config.xml"), new File(cordovaDir, "config.xml"));
FileUtils.deleteQuietly(new File(wwwDir, "config.xml"));
if (iosProvisioningProfileUUID != null) {
boolean release = "release".equals(option);
JSONObject json = new JSONObject();
if (iosSignIdentity != null) {
json.put("codeSignIdentity", iosSignIdentity);
} else {
json.put("codeSignIdentity", release ? "iPhone Distribution" : "iPhone Developer");
}
json.put("provisioningProfile", iosProvisioningProfileUUID);
json = new JSONObject().put(release ? "release" : "debug", json);
json = new JSONObject().put("ios", json);
FileUtils.write(new File(cordovaDir, "build.json"), json.toString(2), "utf-8");
}
if (androidKeystore != null) {
boolean release = "release".equals(option);
JSONObject json = new JSONObject();
json.put("keystore", androidKeystore.getAbsolutePath());
json.put("storePassword", androidKeystorePassword);
json.put("alias", androidAlias);
json.put("password", androidPassword);
json.put("keystoreType", "");
json = new JSONObject().put(release ? "release" : "debug", json);
json = new JSONObject().put("android", json);
FileUtils.write(new File(cordovaDir, "build.json"), json.toString(2), "utf-8");
}
processConfigXMLResources(wwwDir, cordovaDir);
List<String> commandsList = new LinkedList<String>();
if (mobilePlatform instanceof Windows) {
File configFile = new File(cordovaDir, "config.xml");
Document doc = XMLUtils.loadXml(configFile);
TwsCachedXPathAPI xpathApi = new TwsCachedXPathAPI();
Element singleElement = (Element) xpathApi.selectSingleNode(doc, "/widget/engine[@name='windows']");
if (singleElement == null) {
throw new Exception("The tag 'engine' is not specified in the file config.xml.");
}
String appx = singleElement.getAttribute("appx");
String archs = singleElement.getAttribute("archs");
if (appx == null || archs == null || appx.isEmpty() || archs.isEmpty()) {
throw new Exception("The attributes 'appx' and 'archs' are not specified in the tag engine.");
}
commandsList.add("--");
commandsList.add("--appx=" + appx);
commandsList.add("--archs=" + archs);
}
jdk8Dir = null;
if ("android".equals(mobilePlatform.getCordovaPlatform())) {
Engine.logEngine.info("Check or install for the JDK8 to build the Android application");
jdk8Dir = ProcessUtils.getJDK8((pBytesRead, pContentLength, pItems) -> {
Engine.logEngine.info("download JDK8: " + Math.round(100f * pBytesRead / pContentLength) + "% [" + pBytesRead + "/" + pContentLength + "]");
});
androidSdkDir = ProcessUtils.getAndroidSDK(preferedAndroidBuildTools, (pBytesRead, pContentLength, pItems) -> {
Engine.logEngine.info("download Android SDK: " + Math.round(100f * pBytesRead / pContentLength) + "% [" + pBytesRead + "/" + pContentLength + "]");
});
gradleDir = ProcessUtils.getGradle((pBytesRead, pContentLength, pItems) -> {
Engine.logEngine.info("download Gradle: " + Math.round(100f * pBytesRead / pContentLength) + "% [" + pBytesRead + "/" + pContentLength + "]");
});
}
runCordovaCommand(cordovaDir, "prepare", cordovaPlatform);
// Step 3: Build or Run using Cordova the specific platform.
if (run) {
commandsList.add(0, "run");
commandsList.add(1, cordovaPlatform);
commandsList.add(2, "--" + option);
commandsList.add(3, "--" + target);
runCordovaCommand(cordovaDir, commandsList);
} else {
commandsList.add(0, "build");
commandsList.add(1, cordovaPlatform);
commandsList.add(2, "--" + option);
commandsList.add(3, "--" + target);
String out = runCordovaCommand(cordovaDir, commandsList);
Matcher m = Pattern.compile("[^\\s]+(?:\\.apk|/build/device)").matcher(out);
if (m.find()) {
File pkg;
do {
pkg = new File(m.group());
if (pkg.exists()) {
if (pkg.getName().equals("device")) {
for (File f : pkg.listFiles()) {
if (f.getName().endsWith(".ipa")) {
pkg = f;
break;
}
}
}
mobilePackage = pkg;
}
} while (m.find());
}
// Step 4: Show dialog with path to apk/ipa/xap
if (!processCanceled) {
showLocationInstallFile(mobilePlatform, process.exitValue(), errorLines, option);
}
}
return Status.OK;
} catch (Throwable e) {
logException(e, "Error when processing Cordova build: " + e);
return Status.CANCEL;
}
}
use of com.twinsoft.convertigo.beans.mobileplatforms.IOs in project convertigo by convertigo.
the class BuildLocallyEndingDialog method createDialogArea.
/**
* Create contents of the dialog.
* @param parent
*/
@Override
protected Control createDialogArea(Composite parent) {
String applicationName = mobilePlatform.getParent().getApplicationName();
Composite container = (Composite) super.createDialogArea(parent);
container.setLayout(new GridLayout(1, true));
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.grabExcessHorizontalSpace = true;
String message = null;
Label label = new Label(container, SWT.NONE);
// Normal ending
if (exitValue == 0) {
if (!applicationName.isEmpty()) {
message = "Application \"" + applicationName + "\" has been successfully built locally." + "\nThe built file for \"" + mobilePlatform.getCordovaPlatform() + "\" platform is located here:";
} else {
message = "Application from the Convertigo project \"" + mobilePlatform.getProject().getName() + "\" has been successfully built locally." + "\nThe built file for \"" + mobilePlatform.getCordovaPlatform() + "\" platform is located here:";
}
// Error ending
} else {
if (!applicationName.isEmpty()) {
message = "An error occurred on the \"" + applicationName + "\" application during the \"Local build\"!";
} else {
message = "An error occurred on the application from the Convertigo project \"" + mobilePlatform.getProject().getName() + "\" during the \"Local build\"!";
}
}
label.setText(message);
label.setLayoutData(data);
data = new GridData(GridData.FILL_HORIZONTAL);
data.grabExcessHorizontalSpace = true;
if (exitValue == 0) {
String href = applicationBuilt.getParentFile().getAbsolutePath();
String text = applicationBuilt.getAbsolutePath();
try {
href = applicationBuilt.getParentFile().getCanonicalPath();
text = applicationBuilt.getCanonicalPath();
} catch (IOException e1) {
}
Text absolutePath = new Text(container, SWT.NONE);
absolutePath.setText(text);
absolutePath.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
absolutePath.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
absolutePath.setEditable(false);
absolutePath.setLayoutData(data);
data = new GridData(GridData.FILL_HORIZONTAL);
data.grabExcessHorizontalSpace = true;
Link link = new Link(container, SWT.WRAP);
link.setText("<a href=\"" + href + "\">Click here to open the parent folder.</a>");
link.setLayoutData(data);
link.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
org.eclipse.swt.program.Program.launch(e.text);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
if (mobilePlatform instanceof IOs) {
Label iosNotify = new Label(container, SWT.NONE);
data = new GridData(GridData.FILL_HORIZONTAL);
data.grabExcessHorizontalSpace = true;
iosNotify.setText("\nTo generate your \"ipa\" file you need to open the \".xcodeproj\" with Xcode \napplication and go to the menu \"Product>Archive\".");
iosNotify.setLayoutData(data);
}
} else if (errorLines != null && !errorLines.equals("")) {
Text absolutePath = new Text(container, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
absolutePath.setText(errorLines);
absolutePath.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
absolutePath.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
absolutePath.setEditable(false);
absolutePath.setLayoutData(data);
}
return container;
}
Aggregations