From: <jsa...@us...> - 2008-10-26 11:05:01
|
Revision: 38 http://flexotask.svn.sourceforge.net/flexotask/?rev=38&view=rev Author: jsauerbach Date: 2008-10-26 11:00:40 +0000 (Sun, 26 Oct 2008) Log Message: ----------- Add RuntimeProvider interface and an OpenRuntimeProvider to include the open source natives. There will be at least an IBM runtime provider to provide the WebSphere Real Time J9 natives but this will not be distributed via sourceforge. Modified Paths: -------------- trunk/flexotask-editor/META-INF/MANIFEST.MF trunk/flexotask-editor/build.properties trunk/flexotask-editor/plugin.xml trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/EEditPlugin.java trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/FlexotaskClasspathInitializer.java Added Paths: ----------- trunk/flexotask-editor/openRuntime-build.xml trunk/flexotask-editor/schema/RuntimeProvider.exsd trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/OpenRuntimeProvider.java trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizard.java trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizardPage.java trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeProvider.java Modified: trunk/flexotask-editor/META-INF/MANIFEST.MF =================================================================== --- trunk/flexotask-editor/META-INF/MANIFEST.MF 2008-10-26 10:58:00 UTC (rev 37) +++ trunk/flexotask-editor/META-INF/MANIFEST.MF 2008-10-26 11:00:40 UTC (rev 38) @@ -24,5 +24,7 @@ org.eclipse.jdt.ui, org.eclipse.jdt.core, org.eclipse.ant.core, - org.eclipse.pde.core + org.eclipse.pde.core, + org.apache.ant, + org.eclipse.core.filesystem Eclipse-LazyStart: true Modified: trunk/flexotask-editor/build.properties =================================================================== --- trunk/flexotask-editor/build.properties 2008-10-26 10:58:00 UTC (rev 37) +++ trunk/flexotask-editor/build.properties 2008-10-26 11:00:40 UTC (rev 38) @@ -3,7 +3,8 @@ task16.gif,\ flexotaskEditor.jar,\ doc.zip,\ - flexotask-toc.xml + flexotask-toc.xml \ + openRuntimeProvider.zip source.flexotaskEditor.jar = src/ Added: trunk/flexotask-editor/openRuntime-build.xml =================================================================== --- trunk/flexotask-editor/openRuntime-build.xml (rev 0) +++ trunk/flexotask-editor/openRuntime-build.xml 2008-10-26 11:00:40 UTC (rev 38) @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project default="build-runtime"> + <!-- To rebuild the standard openRuntimeProvider.zip, you must have a directory + (mounted from a linux machine, unless this is a linux machine) where the following can be found: + flexotask/native/libflexotaskUtil.so + JavaTraceGenerationLibrary/native/libTuningForkNativeTraceSupport.so + JavaTraceGenerationViaNative/native/libTuningForkNativeBridge.so + The name of that directory must be in the ant property open-runtime-directory --> + <target name="build-runtime"> + <fail message="open-runtime-directory property not specified" unless="open-runtime-directory"/> + <property name="flexotask-util" value="libflexotaskUtil.so"/> + <property name="full-flexotask-util" value="${open-runtime-directory}/flexotask/native/${flexotask-util}"/> + <property name="tf-std" value="libTuningForkNativeTraceSupport.so"/> + <property name="full-tf-std" value="${open-runtime-directory}/JavaTraceGenerationLibrary/native/${tf-std}"/> + <property name="tf-native" value="libTuningForkNativeBridge.so"/> + <property name="full-tf-native" value="${open-runtime-directory}/JavaTraceGenerationViaNative/native/${tf-native}"/> + <fail message="${flexotask-util} so not found"> + <condition><not><available file="${full-flexotask-util}"/></not></condition> + </fail> + <fail message="${tf-std} not found"> + <condition><not><available file="${full-tf-std}"/></not></condition> + </fail> + <fail message="${tf-native} not found"> + <condition><not><available file="${full-tf-native}"/></not></condition> + </fail> + <delete file="openRuntimeProvider.zip"/> + <zip destfile="openRuntimeProvider.zip"> + <zipfileset filemode="775" file="${full-flexotask-util}" fullpath="bin/common/${flexotask-util}"/> + <zipfileset filemode="775" file="${full-tf-std}" fullpath="bin/common/${tf-std}"/> + <zipfileset filemode="775" file="${full-flexotask-util}" fullpath="bin/common/${tf-native}"/> + </zip> + </target> +</project> \ No newline at end of file Property changes on: trunk/flexotask-editor/openRuntime-build.xml ___________________________________________________________________ Added: svn:mime-type + text/xml Added: svn:eol-style + native Modified: trunk/flexotask-editor/plugin.xml =================================================================== --- trunk/flexotask-editor/plugin.xml 2008-10-26 10:58:00 UTC (rev 37) +++ trunk/flexotask-editor/plugin.xml 2008-10-26 11:00:40 UTC (rev 38) @@ -3,6 +3,7 @@ <plugin> <extension-point id="TimingGrammar" name="Timing Grammar Provider" schema="schema/TimingGrammar.exsd"/> <extension-point id="Libraries" name="Additional Libraries for Flexotask Classpath Container" schema="schema/Libraries.exsd"/> + <extension-point id="RuntimeProvider" name="Runtime Binary Files Provider" schema="schema/RuntimeProvider.exsd"/> <extension point="org.eclipse.ui.editors"> <editor name="Flexotask Editor" @@ -70,4 +71,24 @@ class="com.ibm.realtime.flexotask.editor.timing.simple.SimpleMultiModeGrammarProvider" kind="simple (multi-mode)"/> </extension> + <extension + point="org.eclipse.ui.exportWizards"> + <category + id="com.ibm.realtime.flexotask" + name="Flexotask"> + </category> + <wizard + category="com.ibm.realtime.flexotask" + class="com.ibm.realtime.flexotask.editor.dialogs.RuntimeExportWizard" + icon="task16.gif" + id="com.ibm.realtime.flexotask.exportRuntime" + name="Flexotask Runtime"> + </wizard> + </extension> + <extension + point="com.ibm.realtime.flexotask.editor.RuntimeProvider"> + <handler + class="com.ibm.realtime.flexotask.editor.dialogs.OpenRuntimeProvider"> + </handler> + </extension> </plugin> Added: trunk/flexotask-editor/schema/RuntimeProvider.exsd =================================================================== --- trunk/flexotask-editor/schema/RuntimeProvider.exsd (rev 0) +++ trunk/flexotask-editor/schema/RuntimeProvider.exsd 2008-10-26 11:00:40 UTC (rev 38) @@ -0,0 +1,105 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="com.ibm.realtime.flexotask.editor"> +<annotation> + <appInfo> + <meta.schema plugin="com.ibm.realtime.flexotask.editor" id="RuntimeProvider" name="Runtime Binary Files Provider"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <complexType> + <sequence> + <element ref="handler"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="handler"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":com.ibm.realtime.flexotask.editor.dialogs.RuntimeProvider"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + + </documentation> + </annotation> + +</schema> Modified: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/EEditPlugin.java =================================================================== --- trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/EEditPlugin.java 2008-10-26 10:58:00 UTC (rev 37) +++ trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/EEditPlugin.java 2008-10-26 11:00:40 UTC (rev 38) @@ -16,14 +16,14 @@ /******************************************************************************* * GEF Examples * Copyright (c) 2004, 2005 Elias Volanakis and others. -\xA0* All rights reserved. This program and the accompanying materials -\xA0* are made available under the terms of the Eclipse Public License v1.0 -\xA0* which accompanies this distribution, and is available at -\xA0* http://www.eclipse.org/legal/epl-v10.html -\xA0* -\xA0* Contributors: -\xA0*\xA0\xA0\xA0\xA0Elias Volanakis - initial API and implementation -\xA0*******************************************************************************/ + \xA0* All rights reserved. This program and the accompanying materials + \xA0* are made available under the terms of the Eclipse Public License v1.0 + \xA0* which accompanies this distribution, and is available at + \xA0* http://www.eclipse.org/legal/epl-v10.html + \xA0* + \xA0* Contributors: + \xA0*\xA0\xA0\xA0\xA0Elias Volanakis - initial API and implementation + \xA0*******************************************************************************/ package com.ibm.realtime.flexotask.editor; import org.eclipse.ui.plugin.AbstractUIPlugin; @@ -34,28 +34,34 @@ * This instance can be shared between all extensions in the plugin. Information * shared between extensions can be persisted by using the PreferenceStore. * </p> + * * @see org.eclipse.ui.plugin.AbstractUIPlugin#getPreferenceStore() * @author Elias Volanakis */ -public class EEditPlugin extends AbstractUIPlugin { +public class EEditPlugin extends AbstractUIPlugin +{ + /** ID of this plugin */ + public final static String ID = "com.ibm.realtime.flexotask.editor"; -/** Single plugin instance. */ -private static EEditPlugin singleton; + /** Single plugin instance. */ + private static EEditPlugin singleton; -/** - * Returns the shared plugin instance. - */ -public static EEditPlugin getDefault() { - return singleton; -} + /** + * Returns the shared plugin instance. + */ + public static EEditPlugin getDefault() + { + return singleton; + } -/** - * The constructor. - */ -public EEditPlugin() { - if (singleton == null) { - singleton = this; - } -} + /** + * The constructor. + */ + public EEditPlugin() + { + if (singleton == null) { + singleton = this; + } + } } Modified: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/FlexotaskClasspathInitializer.java =================================================================== --- trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/FlexotaskClasspathInitializer.java 2008-10-26 10:58:00 UTC (rev 37) +++ trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/FlexotaskClasspathInitializer.java 2008-10-26 11:00:40 UTC (rev 38) @@ -54,9 +54,12 @@ /** The id of the flexotask generic plugin and hence its bundle */ public final static String FLEXOTASK_GENERIC_PLUGIN = "com.ibm.realtime.flexotask.generic"; + /** File that is used as the debugging assistance file (built by all flexotask projects that may be put in a classpath container) */ + public static final String DEBUG_FILE = "debug.zip"; + /** The local file name suffix to use for source attachments, when present */ private final static String SRC_NAME = "src.zip"; - + /** Special flag to allow the mechanism for running under a debugger itself to be debugged */ private static final boolean DEBUG_DEBUGGING = Boolean.valueOf(System.getProperty("FLEXOTASK_DEBUG_DEBUGGING")); @@ -125,7 +128,7 @@ */ File possibleProj = new File(altLocation); if (possibleProj.isDirectory()) { - File possibleZip = new File(possibleProj, "debug.zip"); + File possibleZip = new File(possibleProj, DEBUG_FILE); if (possibleZip.exists() && possibleZip.isFile()) { IPath zip = new Path(possibleZip.getAbsolutePath()); accumulator.add(JavaCore.newLibraryEntry(zip, zip, null)); Added: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/OpenRuntimeProvider.java =================================================================== --- trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/OpenRuntimeProvider.java (rev 0) +++ trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/OpenRuntimeProvider.java 2008-10-26 11:00:40 UTC (rev 38) @@ -0,0 +1,48 @@ +/* + * This file is part of Flexible Task Graphs + * (http://sourceforge.net/projects/flexotasks) + * + * Copyright (c) 2006 - 2008 IBM Corporation. + * 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: + * IBM Corporation - initial API and implementation + */ +package com.ibm.realtime.flexotask.editor.dialogs; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; + +import com.ibm.realtime.flexotask.editor.EEditPlugin; + +/** + * RuntimeProvider providing just the things that are available in open source. + */ +public class OpenRuntimeProvider implements RuntimeProvider +{ + /* (non-Javadoc) + * @see com.ibm.realtime.flexotask.editor.dialogs.RuntimeProvider#contribute() + */ + public String contribute() + { + Bundle bundle = Platform.getBundle(EEditPlugin.ID); + URL entryURL = bundle.getEntry("/"); + try { + entryURL = FileLocator.toFileURL(entryURL); + File zipFile = new File(entryURL.getPath(), "openRuntimeProvider.zip").getAbsoluteFile(); + if (zipFile.exists()) { + return zipFile.getAbsolutePath(); + } + } catch (IOException e) { + } + return null; + } +} Property changes on: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/OpenRuntimeProvider.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizard.java =================================================================== --- trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizard.java (rev 0) +++ trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizard.java 2008-10-26 11:00:40 UTC (rev 38) @@ -0,0 +1,493 @@ +/* + * This file is part of Flexible Task Graphs + * (http://sourceforge.net/projects/flexotasks) + * + * Copyright (c) 2006 - 2008 IBM Corporation. + * 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: + * IBM Corporation - initial API and implementation + */ +package com.ibm.realtime.flexotask.editor.dialogs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipFile; +import org.apache.tools.zip.ZipOutputStream; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileInfo; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.filesystem.IFileSystem; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IExportWizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.actions.WorkspaceModifyOperation; + +import com.ibm.realtime.flexotask.editor.EEditPlugin; +import com.ibm.realtime.flexotask.editor.FlexotaskClasspathInitializer; +import com.ibm.realtime.flexotask.editor.model.GlobalTiming; + +/** + * Export a Flexotask Runtime based contributed libraries, including a special NativeRuntime provider + */ +public class RuntimeExportWizard extends Wizard implements IExportWizard +{ + /** The array of RuntimeProviders configured in this Eclipse instance */ + private static RuntimeProvider[] runtimeProviders; + + /** The extension-point id for RuntimeProviders */ + private static final String RUNTIME_PROVIDER_EXTENSION = "com.ibm.realtime.flexotask.editor.RuntimeProvider"; + + /** Maximum size of a data transfer buffer */ + private static final int BUFFER_THRESHHOLD = 1024 * 1024; + + /** The one page of this wizard */ + RuntimeExportWizardPage page; + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#addPages() + */ + public void addPages() + { + page = new RuntimeExportWizardPage(); + addPage(page); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection) + */ + public void init(IWorkbench workbench, IStructuredSelection selection) { + setNeedsProgressMonitor(true); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#performFinish() + */ + public boolean performFinish() + { + final File destination = page.getDestination(); + page.saveSettings(); + if (destination.exists()) { + if (!page.shouldOverwrite() && !MessageDialog.openConfirm(getShell(), + "Should overwrite?", destination.getAbsolutePath() + " exists. Replace with new contents?")) { + return false; + } + } + final Shell shell = getShell(); + final boolean isDirectory = page.isDirectory(); + WorkspaceModifyOperation op = new WorkspaceModifyOperation() { + protected void execute(IProgressMonitor monitor) throws CoreException, + InvocationTargetException, InterruptedException + { + monitor.beginTask("Exporting Runtime", 100); + if (destination.exists()) { + if (!deleteDestination(destination)) { + monitor.worked(100); + MessageDialog.openError(shell, "Could not delete", destination.getAbsolutePath() + " could not be deleted"); + return; + } + } + monitor.worked(10); + if (monitor.isCanceled()) { + return; + } + exportRuntime(shell, destination, isDirectory, monitor); + } + }; + try { + getContainer().run(false, true, op); + } catch (Throwable e) { + handleException(shell, e); + } + return true; + } + + /** + * Remove a destination file or directory if possible + * @param destination the file or directory to remove + * @return true if removal was successful, false on error + */ + private boolean deleteDestination(File destination) { + if (!destination.canWrite()) { + return false; + } + if (destination.isFile()) { + return destination.delete(); + } + File[] children = destination.listFiles(); + for (int i = 0; i < children.length; i++) { + if (!deleteDestination(children[i])) { + return false; + } + } + return destination.delete(); + } + + /** + * Export a runtime for use in a real-time VM. At entry the destination is guaranteed not to exist + * @param shell the shell to use for any error messages or prompts + * @param destination the destination of the export + * @param isDirectory true if the export should be to a directory, false if to a zip file + * @param monitor the progress monitor to report progress + * @return true iff the export was successful, false otherwise (diagnostic will have been issued) + */ + public static boolean exportRuntime(Shell shell, File destination, boolean isDirectory, IProgressMonitor monitor) { + OutputStream output = null; + //MessageDialog.openInformation(shell, "", "Export started"); + /* Try block catches all stray exceptions, particularly IOExceptions */ + try { + ExportController controller = isDirectory ? new DirectoryExportController(destination) : new ZipFileExportController(destination); + /* Compute work units per operation on the assumption that there are a total of 90 */ + RuntimeProvider[] providers = getRuntimeProviders(); + List<IClasspathEntry> accumulator = new ArrayList<IClasspathEntry>(); + GlobalTiming.addToClasspath(accumulator); + int units = providers.length + accumulator.size() + 2; + units = (int) (90.0 / units); + /* Add contributions of all runtime providers */ + for (RuntimeProvider runtimeProvider : providers) { + //MessageDialog.openInformation(shell, "", "Processing runtime provider: " + runtimeProvider.getClass().getName()); + ZipFile contribution = new ZipFile(runtimeProvider.contribute()); + if (contribution != null) { + output = transferZipFile(contribution, controller, output); + } + if (monitor.isCanceled()) { + return false; + } + monitor.worked(units); + } + /* Add the standard contributions from the analysis and flexotask plugins */ + //MessageDialog.openInformation(shell, "", "Adding standard java libraries"); + output = transferFile(getBestAvailableJar(FlexotaskClasspathInitializer.FLEXOTASK_PLUGIN, "flexotask.jar"), + controller, output, "lib/flexotask.jar"); + if (monitor.isCanceled()) { + return false; + } + monitor.worked(units); + //MessageDialog.openInformation(shell, "", "flexotask.jar added"); + output = transferFile(getBestAvailableJar(FlexotaskClasspathInitializer.ANALYSIS_PLUGIN, "realtimeAnalysis.jar"), + controller, output, "lib/realtimeAnalysis.jar"); + if (monitor.isCanceled()) { + return false; + } + monitor.worked(units); + //MessageDialog.openInformation(shell, "", "realtimeAnalysis.jar added"); + /* Add optional libraries identified by library providers */ + //MessageDialog.openInformation(shell, "", "Adding optional libraries"); + for (IClasspathEntry classpathEntry : accumulator) { + File toTransfer; + String transferName; + IPath path = classpathEntry.getPath(); + switch (classpathEntry.getEntryKind()) { + case IClasspathEntry.CPE_LIBRARY: + transferName = path.lastSegment(); + if (FlexotaskClasspathInitializer.DEBUG_FILE.equals(transferName)) { + transferName = path.removeLastSegments(1).lastSegment() + ".jar"; + } + toTransfer = new File(path.toString()); + break; + case IClasspathEntry.CPE_PROJECT: + transferName = path.lastSegment() + ".jar"; + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(classpathEntry.getPath().toString()); + File location = project.getLocation().toFile(); + toTransfer = new File(location, FlexotaskClasspathInitializer.DEBUG_FILE); + break; + default: + throw new IllegalStateException("Unexpected classpath entry type during export: " + classpathEntry); + } + //MessageDialog.openInformation(shell, "", "transferring " + toTransfer.getAbsolutePath() + " to " + transferName); + output = transferFile(toTransfer, controller, output, "lib/ext/" + transferName); + if (monitor.isCanceled()) { + return false; + } + monitor.worked(units); + } + output.close(); + //MessageDialog.openInformation(shell, "", "Export complete"); + return true; + } catch (Throwable e) { + handleException(shell, e); + return false; + } + } + + /** + * Find the best available copy of a standard jar for a plugin, either from the plugin itself, or from the "debug.zip" of its + * project + * @param pluginID the ID of the plugin + * @param jarToFind the name of the jar to find there + * @return the best available copy of jar + * @throws CoreException if thrown by the addPluginClasspath utility + * @throws IllegalStateException if no suitable copy could be found + */ + private static File getBestAvailableJar(String pluginID, String jarToFind) throws CoreException + { + List<IClasspathEntry> accumulator = new ArrayList<IClasspathEntry>(); + FlexotaskClasspathInitializer.addPluginClasspath(accumulator, pluginID); + for (IClasspathEntry classpathEntry : accumulator) { + switch (classpathEntry.getEntryKind()) { + case IClasspathEntry.CPE_LIBRARY: + IPath path = classpathEntry.getPath(); + if (jarToFind.equals(path.lastSegment()) || FlexotaskClasspathInitializer.DEBUG_FILE.equals(path.lastSegment())) { + return path.toFile(); + } + break; + case IClasspathEntry.CPE_PROJECT: + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(classpathEntry.getPath().toString()); + File location = project.getLocation().toFile(); + return new File(location, FlexotaskClasspathInitializer.DEBUG_FILE); + } + } + throw new IllegalStateException("No usable copy of " + jarToFind + " was found"); + } + + /** + * Utility to find all the RuntimeProviders in the system + * @return an array containing all the RuntimeProviders in the system + */ + private static RuntimeProvider[] getRuntimeProviders() { + if (runtimeProviders == null) { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry.getExtensionPoint(RUNTIME_PROVIDER_EXTENSION); + if (extensionPoint == null) { + runtimeProviders = new RuntimeProvider[0]; + } else { + IConfigurationElement points[] = extensionPoint.getConfigurationElements(); + List<RuntimeProvider> runtimeList = new ArrayList<RuntimeProvider>(); + for (int i = 0; i < points.length; i++) { + IConfigurationElement point = points[i]; + RuntimeProvider rtp; + try { + rtp = (RuntimeProvider) point.createExecutableExtension("class"); + runtimeList.add(rtp); + } catch (CoreException e) { + } + } + runtimeProviders = (RuntimeProvider[]) runtimeList.toArray(new RuntimeProvider[runtimeList.size()]); + } + } + return runtimeProviders; + } + + /** + * Handle an exception that occurs in this operation + * @param shell the shell to use + * @param exception the exception that occurred + */ + private static void handleException(final Shell shell, Throwable exception) + { + if (exception instanceof InvocationTargetException) { + exception = ((InvocationTargetException) exception).getTargetException(); + } + IStatus status = null; + if (exception instanceof CoreException) { + status = ((CoreException) exception).getStatus(); + } + if (status == null) { + status = new Status(Status.ERROR, EEditPlugin.ID, exception.getMessage(), exception); + } + ResourcesPlugin.getPlugin().getLog().log(status); + ErrorDialog.openError(shell, "Error during export", status.getMessage(), status); + } + + /** + * Transfer a file to the destination + * @param file the file to transfer + * @param controller the ExportController for the destination + * @param output the OutputStream from the previous export step or null if this is the first step + * @param targetName the name that the logical file should have in the destination + * @return the OutputStream that was used for this export step + * @throws IOException + * @throws CoreException + */ + private static OutputStream transferFile(File file, + ExportController controller, OutputStream output, String targetName) throws IOException, CoreException + { + InputStream input = new FileInputStream(file); + return transferStream(input, controller, output, targetName, 0); + } + + /** + * Transfer an input stream to the destination + * @param input the input stream to transfer + * @param controller the ExportController for the destination + * @param output the OutputStream from the previous export step or null if this is the first step + * @param targetName the name that the logical file should have in the destination + * @param mode the unix mode for the output if non-zero, ignored if zero + * @return the OutputStream that was used for this export step + * @throws IOException + * @throws CoreException + */ + private static OutputStream transferStream(InputStream input, + ExportController controller, OutputStream output, String targetName, int mode) + throws IOException, CoreException + { + output = controller.getOutputStream(output, targetName, mode); + int remaining = input.available(); + byte[] buffer; + if (remaining > BUFFER_THRESHHOLD) { + buffer = new byte[BUFFER_THRESHHOLD]; + } else { + buffer = new byte[remaining]; + } + while (remaining > 0) { + int toRead = remaining > buffer.length ? buffer.length : remaining; + int amount = input.read(buffer, 0, toRead); + output.write(buffer, 0, amount); + remaining -= amount; + } + input.close(); + return output; + } + + /** + * Transfer the contents of a zip file (file by file) to the destination + * @param zipFile the zip file to transfer + * @param controller the ExportController for the destination + * @param output the OutputStream from the previous export step or null if this is the first step + * @return the last OutputStream that was used for this export step + * @throws IOException + * @throws CoreException + */ + private static OutputStream transferZipFile(ZipFile zipFile, + ExportController controller, OutputStream output) throws IOException, CoreException + { + Enumeration<?> entries = zipFile.getEntries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + if (entry.isDirectory()) { + continue; + } + int mode = entry.getUnixMode(); + InputStream input = zipFile.getInputStream(entry); + output = transferStream(input, controller, output, entry.getName(), mode); + } + return output; + } + + /** + * An ExportController implementation for the case where the output is a directory containing files + * and subdirectories + */ + private static final class DirectoryExportController implements ExportController { + /** The base directory */ + private File baseDirectory; + + /** The local file system */ + private static final IFileSystem fileSystem = EFS.getLocalFileSystem(); + + /** The currently open IFileStore iff the executable bit should be set, otherwise null */ + private IFileStore currentlyOpen; + + /** + * Create a new DirectoryExportController + * @param baseDirectory the base directory of the export area + */ + DirectoryExportController(File baseDirectory) { + this.baseDirectory = baseDirectory; + baseDirectory.mkdir(); + } + + /* (non-Javadoc) + * @see com.ibm.realtime.flexotask.editor.dialogs.RuntimeExportWizard.ExportController#getOutputStream(java.io.OutputStream, java.lang.String, int) + */ + public OutputStream getOutputStream(OutputStream former, String newFile, int mode) throws IOException, CoreException + { + if (former != null) { + former.close(); + if (currentlyOpen != null) { + /* Note: this only works if you are running on a unix system ... on windows it does nothing */ + IFileInfo info = EFS.createFileInfo(); + info.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, true); + currentlyOpen.putInfo(info, EFS.SET_ATTRIBUTES, null); + } + } + File toCreate = new File(baseDirectory, newFile); + toCreate.getParentFile().mkdirs(); + IFileStore target = fileSystem.fromLocalFile(toCreate); + OutputStream ans = target.openOutputStream(0, null); + currentlyOpen = ((mode & 0111) != 0) ? target : null; + return ans; + } + } + + /** + * An interface to hide the difference between zipfile and directory/file output + */ + private static interface ExportController { + /** + * Get the output stream for exporting a logical file (which either becomes a file or a + * entry in a zip file) + * @param former the former OutputStream or null if this is the first file to be exported + * @param newFile the path name of the new logical file to be added + * @param mode unix mode if non-zero, ignored if zero + * @return a new (or perhaps the same) OutputStream, positioned to accept the new logical file + * @throws IOException on I/O errors detected by non-Eclipse components + * @throws CoreException on errors detected by Eclipse components + */ + OutputStream getOutputStream(OutputStream former, String newFile, int mode) throws IOException, CoreException; + } + + /** + * An ExportController implementation for the case where the output is a zip file + */ + private static final class ZipFileExportController implements ExportController { + private ZipOutputStream output; + + /** + * Create a new ZipFileExportController + * @param zipFile the file to create (does not yet exist) + * @throws FileNotFoundException + */ + public ZipFileExportController(File zipFile) throws FileNotFoundException { + output = new ZipOutputStream(new FileOutputStream(zipFile)); + } + + /* (non-Javadoc) + * @see com.ibm.realtime.flexotask.editor.dialogs.RuntimeExportWizard.ExportController#getOutputStream(java.io.OutputStream, java.lang.String, int) + */ + public OutputStream getOutputStream(OutputStream former, String newFile, int mode) + throws IOException + { + if (former != null) { + assert former == output; + output.closeEntry(); + } + ZipEntry newEntry = new ZipEntry("flexotask-runtime/" + newFile); + if (mode != 0) { + newEntry.setUnixMode(mode); + } + output.putNextEntry(newEntry); + return output; + } + } +} Property changes on: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizard.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizardPage.java =================================================================== --- trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizardPage.java (rev 0) +++ trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizardPage.java 2008-10-26 11:00:40 UTC (rev 38) @@ -0,0 +1,336 @@ +/* + * This file is part of Flexible Task Graphs + * (http://sourceforge.net/projects/flexotasks) + * + * Copyright (c) 2006 - 2008 IBM Corporation. + * 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: + * IBM Corporation - initial API and implementation + */ +package com.ibm.realtime.flexotask.editor.dialogs; + +import java.io.File; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.FileDialog; + +import com.ibm.realtime.flexotask.editor.EEditPlugin; + +/** + * The single page making up the runtime export wizard. Some of the GUI logic in this page is based + * on ExportDestinationTab from the PDE + */ +class RuntimeExportWizardPage extends WizardPage +{ + /** Section key for dialog settings related to this wizard */ + private static final String RUNTIME_EXPORT_KEY = "RuntimeExportSection"; + + /** Key for the switch indicating whether we last exported to a directory or na archive */ + private static final String EXPORT_DIRECTORY = "exportDirectory"; + + /** Key for the directory destination last exporte to */ + private static final String DESTINATION = "destination"; + + /** Key for the file archive last exporte to */ + private static final String ZIPFILENAME = "zipFileName"; + + /** Key indicating that overwriting the destination is desired */ + private static final String OVERWRITE = "overwrite"; + + /** Extension for zip files */ + private static final String ZIP_EXTENSION = ".zip"; + + /** The Radio button to choose the directory option */ + private Button chooseDirectory; + + /** The Combo for selecting the directory name */ + private Combo directoryName; + + /** Browse button for filling in the directory name */ + private Button browseDirectory; + + /** The Radio button to choose the archive file option */ + private Button chooseArchiveFile; + + /** The Combo for selecting the archive file name */ + private Combo archiveFileName; + + /** Browse button for filling in the archive file name */ + private Button browseFile; + + /** Checkbox indicating that the user wants the destination to be overwritten without prompting */ + private Button overwrite; + + /** + * Create a new RuntimeExportWizardPage + */ + RuntimeExportWizardPage() + { + super("FlexotaskRuntime"); + setTitle("Export Flexotask Runtime"); + setDescription("Export a Flexotask runtime for a real-time VM using existing plugins and flexotask PDE projects"); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) + { + initializeDialogUnits(parent); + Composite control = new Composite(parent, SWT.NONE); + control.setLayout(new GridLayout(2, false)); + control.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + IDialogSettings settings = getSettings(); + String toDirectory = settings.get(EXPORT_DIRECTORY); + boolean useDirectory = toDirectory == null || "true".equals(toDirectory); //$NON-NLS-1$ + + chooseDirectory = new Button(control, SWT.RADIO); + chooseDirectory.setText("Directory:"); + GridData gd = new GridData(); + gd.horizontalSpan = 2; + chooseDirectory.setLayoutData(gd); + chooseDirectory.setSelection(useDirectory); + + directoryName = new Combo(control, SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalIndent = 15; + directoryName.setLayoutData(gd); + initializeCombo(settings, DESTINATION, directoryName); + directoryName.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + evaluateCompleteness(); + } + }); + + + browseDirectory = new Button(control, SWT.PUSH); + browseDirectory.setText("Browse"); + browseDirectory.setLayoutData(new GridData()); + browseDirectory.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + chooseDestination(); + } + }); + + chooseArchiveFile = new Button(control, SWT.RADIO); + chooseArchiveFile.setText("Archive file:"); + gd = new GridData(); + gd.horizontalSpan = 2; + chooseArchiveFile.setLayoutData(gd); + chooseArchiveFile.setSelection(!useDirectory); + chooseArchiveFile.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + toggleDestinationGroup(!chooseArchiveFile.getSelection()); + evaluateCompleteness(); + } + }); + + archiveFileName = new Combo(control, SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalIndent = 15; + archiveFileName.setLayoutData(gd); + initializeCombo(settings, ZIPFILENAME, archiveFileName); + archiveFileName.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + evaluateCompleteness(); + } + }); + + browseFile = new Button(control, SWT.PUSH); + browseFile.setText("Browse"); + browseFile.setLayoutData(new GridData()); + browseFile.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + chooseFile(archiveFileName, "*" + ZIP_EXTENSION); + } + }); + + overwrite = new Button(control, SWT.CHECK); + overwrite.setText("Overwrite without prompting"); + overwrite.setLayoutData(new GridData()); + overwrite.setSelection(settings.getBoolean(OVERWRITE)); + overwrite.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + evaluateCompleteness(); + } + }); + + toggleDestinationGroup(useDirectory); + Dialog.applyDialogFont(control); + setControl(control); + evaluateCompleteness(); + } + + /** + * @return the chosen destination as a java.io.File + */ + File getDestination() { + if (chooseArchiveFile.getSelection()) { + return new File(archiveFileName.getText()); + } else { + return new File(directoryName.getText()); + } + } + + /** + * @return true iff a directory was chosen, false if a file + */ + boolean isDirectory() { + return chooseDirectory.getSelection(); + } + + /** + * Save the dialog settings + */ + void saveSettings() { + IDialogSettings settings = getSettings(); + settings.put(EXPORT_DIRECTORY, chooseDirectory.getSelection()); + settings.put(OVERWRITE, overwrite.getSelection()); + saveCombo(settings, DESTINATION, directoryName); + saveCombo(settings, ZIPFILENAME, archiveFileName); + } + + /** + * @return indication of whether the destination should be overwritten + */ + boolean shouldOverwrite() { + return overwrite.getSelection(); + } + + /** + * Run a dialog to choose a destination directory + */ + private void chooseDestination() { + DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SAVE); + String path = directoryName.getText(); + if (path.trim().length() == 0) + path = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString(); + dialog.setFilterPath(path); + dialog.setText("Destination Directory"); + dialog.setMessage("Set a destination directory for the runtime export operation"); + String res = dialog.open(); + if (res != null) { + if (directoryName.indexOf(res) == -1) + directoryName.add(res, 0); + directoryName.setText(res); + } + } + + /** + * Run a dialog to choose a file + * @param combo the Combo in which to place the file + * @param filter the filter to use in choosing the file + */ + private void chooseFile(Combo combo, String filter) { + FileDialog dialog = new FileDialog(getShell(), SWT.SAVE); + String path = combo.getText(); + if (path.trim().length() == 0) + path = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString(); + dialog.setFileName(path); + dialog.setFilterExtensions(new String[] { filter }); + String res = dialog.open(); + if (res != null) { + if (combo.indexOf(res) == -1) + combo.add(res, 0); + combo.setText(res); + } + } + + /** + * Determine whether the page is complete enough for Finish button to be enabled + * Display any error messages that need displaying + */ + private void evaluateCompleteness() + { + setMessage(null); + String error = null; + if (chooseArchiveFile.getSelection() && archiveFileName.getText().trim().length() == 0) { + error = "Archive file name not specified"; + } + if (chooseDirectory.getSelection() && directoryName.getText().trim().length() == 0) { + error = "Destination directory not specified"; + } + setErrorMessage(error); + setPageComplete(error == null); + } + + /** + * Retrieve dialog settings after ensuring they are present + */ + private IDialogSettings getSettings() { + IDialogSettings settings = getDialogSettings(); + if (settings == null) { + settings = EEditPlugin.getDefault().getDialogSettings().getSection(RUNTIME_EXPORT_KEY); + if (settings == null) { + settings = EEditPlugin.getDefault().getDialogSettings().addNewSection(RUNTIME_EXPORT_KEY); + } + Wizard wizard = (Wizard) getWizard(); + wizard.setDialogSettings(settings); + } + return settings; + } + + /** + * Initialize a combo from the dialog settings, up to six items + * @param settings the dialog settings + * @param key the key to look up + * @param combo the combo to initialize + */ + private void initializeCombo(IDialogSettings settings, String key, Combo combo) { + for (int i = 0; i < 6; i++) { + String curr = settings.get(key + String.valueOf(i)); + if (curr != null && combo.indexOf(curr) == -1) { + combo.add(curr); + } + } + if (combo.getItemCount() > 0) + combo.setText(combo.getItem(0)); + } + + /** + * Save the history from a Combo + * @param settings the IDialogSettings to which the settings should be saved + * @param key the key to use for this Combo + * @param combo the Combo + */ + private void saveCombo(IDialogSettings settings, String key, Combo combo) { + if (combo.getText().trim().length() > 0) { + settings.put(key + String.valueOf(0), combo.getText().trim()); + String[] items = combo.getItems(); + int nEntries = Math.min(items.length, 5); + for (int i = 0; i < nEntries; i++) { + settings.put(key + String.valueOf(i + 1), items[i].trim()); + } + } + } + + /** + * Enable either the directory input or the file input, never both + * @param useDirectory directory input is requested + */ + private void toggleDestinationGroup(boolean useDirectory) { + archiveFileName.setEnabled(!useDirectory); + browseFile.setEnabled(!useDirectory); + directoryName.setEnabled(useDirectory); + browseDirectory.setEnabled(useDirectory); + } +} Property changes on: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeExportWizardPage.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeProvider.java =================================================================== --- trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeProvider.java (rev 0) +++ trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeProvider.java 2008-10-26 11:00:40 UTC (rev 38) @@ -0,0 +1,28 @@ +/* + * This file is part of Flexible Task Graphs + * (http://sourceforge.net/projects/flexotasks) + * + * Copyright (c) 2006 - 2008 IBM Corporation. + * 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: + * IBM Corporation - initial API and implementation + */ +package com.ibm.realtime.flexotask.editor.dialogs; + + +/** + * Interface to be implemented by runtime providers. These contribute native libraries and + * proprietary Java libraries to the runtime. The contribution always takes the form of + * a ZipFile. + */ +public interface RuntimeProvider +{ + /** + * @return this provider's contribution to the runtime as the absolute path name of a zip archive + */ + public String contribute(); +} Property changes on: trunk/flexotask-editor/src/com/ibm/realtime/flexotask/editor/dialogs/RuntimeProvider.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |