blob: 9df5e869e0cce44ceb648f20f1fb6851d1149093 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
******************************************************************************/
package org.eclipse.scout.sdk.pde;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.scout.commons.IOUtility;
import org.eclipse.scout.sdk.ScoutSdk;
import org.eclipse.scout.sdk.ScoutStatus;
/**
* Pde handling using eclipse environment IProject
* NOTE When including jars
* If jar must be included in the delivered plugin jar file:
* 1. add jar to MANIFEST.MF as
* Bundle-ClassPath: my.jar
* 2. add jar to build.properties as
* bin.includes = my.jar
* If jar is only used to compile and should not be delivered in the final plugin jar file:
* 1. add jar to build.properties as
* jars.extra.classpath = my.jar
*/
public final class PdeUtility {
private PdeUtility() {
}
/**
* @return the appended values
*/
public static String[] addExportPackage(IProject project, String packageName) throws CoreException, IOException {
return addExportPackages(project, new String[]{packageName});
}
public static String[] getExportPackages(IProject project) throws CoreException, IOException {
return getAttributeList(project, "Export-Package");
}
public static String[] getImportPackages(IProject project) throws CoreException, IOException {
return getAttributeList(project, "Import-Package");
}
/**
* @return the appended values
*/
public static String[] addExportPackages(IProject project, String[] packageNames) throws CoreException, IOException {
return extendAttributeList(project, "Export-Package", packageNames);
}
/**
* @return the appended values
*/
public static String[] removeExportPackage(IProject project, String packageName) throws CoreException, IOException {
return removeExportPackages(project, new String[]{packageName});
}
/**
* @return the appended values
*/
public static String[] removeExportPackages(IProject project, String[] packageNames) throws CoreException, IOException {
return reduceAttributeList(project, "Export-Package", packageNames);
}
/**
* @return the appended values
*/
public static String[] addBundleClasspath(IProject project, String path) throws CoreException, IOException {
return addBundleClasspaths(project, new String[]{path});
}
/**
* add paths to Manifest.mf Bundle-ClassPath
*
* @return the appended values
*/
public static String[] addBundleClasspaths(IProject project, String[] paths) throws CoreException, IOException {
String[] changedPaths = extendAttributeList(project, "Bundle-ClassPath", paths);
return changedPaths;
}
public static String[] getBundleClasspaths(IProject project) throws CoreException, IOException {
return getAttributeList(project, "Bundle-ClassPath");
}
/**
* add paths to .classpath of the project
*/
public static void addProjectClasspaths(IProject project, String[] paths) throws CoreException, IOException {
ClasspathXml classpathFile = new ClasspathXml(project);
for (String path : paths) {
classpathFile.addEntry(ClasspathEntry.KIND_LIB, path, null, true);
}
classpathFile.store(null);
}
/**
* add paths to build.properties of the project
*/
public static void addBuildPropertiesFiles(IProject project, String propertyName, String[] files) throws CoreException, IOException {
BuildProperties buildProps = new BuildProperties(project);
buildProps.addFiles(propertyName, files);
buildProps.store(null);
}
/**
* remove paths from build.properties of the project
*/
public static void removeBuildPropertiesFiles(IProject project, String propertyName, String[] files) throws CoreException, IOException {
BuildProperties buildProps = new BuildProperties(project);
buildProps.removeFiles(propertyName, files);
buildProps.store(null);
}
/**
* add paths to build.properties of the project
*/
public static void addBuildPropertiesDirectories(IProject project, String propertyName, String[] dirs) throws CoreException, IOException {
BuildProperties buildProps = new BuildProperties(project);
buildProps.addDirectories(propertyName, dirs);
buildProps.store(null);
}
/**
* remove paths from build.properties of the project
*/
public static void removeBuildPropertiesDirectories(IProject project, String propertyName, String[] dirs) throws CoreException, IOException {
BuildProperties buildProps = new BuildProperties(project);
buildProps.removeDirectories(propertyName, dirs);
buildProps.store(null);
}
/**
* @return the appended values
*/
public static String[] extendAttributeList(IProject project, String attributeName, String additionalValue) throws CoreException, IOException {
return extendAttributeList(project, attributeName, new String[]{additionalValue});
}
/**
* @return the appended values
*/
public static String[] extendAttributeList(IProject project, String attributeName, String[] additionalValues) throws CoreException, IOException {
Manifest mf = new Manifest();
mf.read(project);
String[] appendedValues = RawPdeUtility.extendAttributeList(mf, attributeName, additionalValues);
if (appendedValues.length > 0) {
mf.write(project);
}
return appendedValues;
}
public static String[] getAttributeList(IProject project, String attributeName) throws CoreException, IOException {
Manifest mf = new Manifest();
mf.read(project);
return RawPdeUtility.getAttributeList(mf, attributeName);
}
/**
* @return the appended values
*/
public static String[] reduceAttributeList(IProject project, String attributeName, String[] additionalValues) throws CoreException, IOException {
Manifest mf = new Manifest();
mf.read(project);
String[] appendedValues = RawPdeUtility.reduceAttributList(mf, attributeName, additionalValues);
if (appendedValues.length > 0) {
mf.write(project);
}
return appendedValues;
}
/**
* @return the appended values
*/
public static String[] addDependencies(IProject project, String[] d) throws CoreException, IOException {
return extendAttributeList(project, "Require-Bundle", d);
}
public static String[] getDependencies(IProject project) throws CoreException, IOException {
return getAttributeList(project, "Require-Bundle");
}
/**
* @return the appended values
*/
public static String[] removeDependencies(IProject project, String[] d) throws CoreException, IOException {
return reduceAttributeList(project, "Require-Bundle", d);
}
/**
* @param jarFiles
* array of jar files (example: lib/jdbc-1.4/oracle-10g/ojdbc14.jar)
* @param includeInBinaryBuild
* true add to Manifest:Bundle-ClassPath and to build.properties:bin.includes / false only add to
* jarsbuild.properties:jars.extra.classpath
* @param addToProjectClasspath
* true append to .classpath file
* @return installed jarFiles
* @throws CoreException
* @throws IOException
*/
public static String[] installLibraryFilesTo(IProject project, String[] jarFiles, boolean includeInBinaryBuild, IProgressMonitor p) throws CoreException, IOException {
ArrayList<String> importedJarFiles = new ArrayList<String>();
for (int i = 0; i < jarFiles.length; i++) {
URL url = ScoutSdk.getDefault().getBundle().getResource(jarFiles[i]);
if (url == null) {
ScoutSdk.logWarning("Cannot find " + jarFiles[i] + " in bundle " + ScoutSdk.getDefault().getBundle().getSymbolicName());
}
else {
IFile file = project.getFile(jarFiles[i]);
if (!file.exists()) {
InputStream in = url.openStream();
try {
createFolder(project.getFolder(new Path(jarFiles[i]).removeLastSegments(1)));
file.create(in, true, p);
}
finally {
in.close();
}
importedJarFiles.add(jarFiles[i]);
}
}
}
if (includeInBinaryBuild) {
PdeUtility.addBundleClasspaths(project, jarFiles);
PdeUtility.addBuildPropertiesFiles(project, BuildProperties.PROP_BIN_INCLUDES, jarFiles);
}
else {
PdeUtility.addBuildPropertiesFiles(project, BuildProperties.PROP_JARS_EXTRA_CLASSPATH, jarFiles);
}
return importedJarFiles.toArray(new String[0]);
}
/**
* creates a folder recursively
*
* @param folder
* @throws CoreException
*/
public static void createFolder(IContainer folder) throws CoreException {
if (!folder.exists()) {
IContainer parent = folder.getParent();
if (parent instanceof IFolder) {
createFolder(parent);
}
if (folder instanceof IFolder) {
((IFolder) folder).create(true, true, null);
}
}
}
public static void createFile(IFile file, InputStream in, IProgressMonitor monitor) throws CoreException {
if (file.exists()) {
file.setContents(in, true, false, monitor);
}
else {
createFolder(file.getParent());
file.create(in, true, monitor);
}
}
/**
* called when the plugin closes
*/
public static void dispose() {
}
@SuppressWarnings("restriction")
public static String launchLocalJavaApplicationAndWait(String launchName, String projectName, String javaMainTypeName, String argumentList, boolean analyseConsoleOutputForException, IProgressMonitor monitor) throws CoreException {
File consoleFile = null;
try {
consoleFile = File.createTempFile("console", ".log");
}
catch (Throwable t) {
ScoutSdk.logError("creating console buffer for " + launchName, t);
}
//
ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = lm.getLaunchConfigurationType("org.eclipse.jdt.launching.localJavaApplication");
ILaunchConfigurationWorkingCopy w = type.newInstance(null, launchName);
w.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName);
w.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, javaMainTypeName);
w.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, argumentList);
w.setAttribute(org.eclipse.debug.internal.core.LaunchConfiguration.ATTR_MAPPED_RESOURCE_TYPES, Arrays.asList(new String[]{"4"}));
w.setAttribute(org.eclipse.debug.internal.core.LaunchConfiguration.ATTR_MAPPED_RESOURCE_PATHS, Arrays.asList(new String[]{"/" + projectName}));
w.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
if (consoleFile != null) {
w.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, consoleFile.getAbsolutePath());
w.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, false);
}
ILaunchConfiguration lc = w.doSave();
ILaunch launch = lc.launch(ILaunchManager.RUN_MODE, monitor, true, true);
while (!launch.isTerminated()) {
try {
Thread.sleep(200);
}
catch (InterruptedException e) {
}
}
IProcess[] processes = launch.getProcesses();
StringBuilder dump = new StringBuilder();
dump.append("Project: " + projectName + "\n");
dump.append("Program: " + javaMainTypeName + "\n");
dump.append("Arguments: " + argumentList + "\n");
if (processes != null) {
for (IProcess p : processes) {
if (consoleFile != null && consoleFile.exists()) {
try {
dump.append("\n");
dump.append(IOUtility.getContent(new FileReader(consoleFile)));
}
catch (Exception e) {
// nop
}
}
if (p.getExitValue() != 0) {
throw new CoreException(new ScoutStatus(dump.toString()));
}
}
}
String consoleText = dump.toString();
if (analyseConsoleOutputForException) {
Matcher m = Pattern.compile("\\tat [a-zA-Z0-9_.]+\\(").matcher(consoleText);
if (m.find()) {
throw new CoreException(new ScoutStatus(consoleText));
}
}
return consoleText;
}
}