summaryrefslogtreecommitdiff
path: root/eclipse/java/Slice2javaPlugin/src
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2011-12-10 01:57:19 +0100
committerJose <jose@zeroc.com>2011-12-10 01:57:19 +0100
commit42e31f18dc2f34c6b0c427ca0a976ac795349864 (patch)
tree91f81872e55f06c5d6b859039e3c2a633c70c684 /eclipse/java/Slice2javaPlugin/src
parentICE-4705 voip glacier2 configuration (diff)
downloadice-42e31f18dc2f34c6b0c427ca0a976ac795349864.tar.bz2
ice-42e31f18dc2f34c6b0c427ca0a976ac795349864.tar.xz
ice-42e31f18dc2f34c6b0c427ca0a976ac795349864.zip
Eclipse plug-in updates for release 3.4.2.20111024
Diffstat (limited to 'eclipse/java/Slice2javaPlugin/src')
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/Activator.java181
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaBuilder.java1282
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaNature.java108
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/ToggleNatureAction.java128
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/GeneratedDecorator.java67
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/SliceDecorator.java75
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Configuration.java1021
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Dependencies.java528
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainer.java47
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainerIntializer.java95
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathVariableInitializer.java47
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PluginPreferencePage.java102
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PreferenceInitializer.java65
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/ProjectProperties.java387
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/PropertyPage.java484
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SliceFilePropertyPage.java110
-rw-r--r--eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SourceSelectionDialog.java254
17 files changed, 4981 insertions, 0 deletions
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/Activator.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/Activator.java
new file mode 100644
index 00000000000..8a4c847b031
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/Activator.java
@@ -0,0 +1,181 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import com.zeroc.slice2javaplugin.builder.Slice2JavaBuilder;
+import com.zeroc.slice2javaplugin.builder.Slice2JavaNature;
+import com.zeroc.slice2javaplugin.internal.IceClasspathContainerIntializer;
+import com.zeroc.slice2javaplugin.internal.IceClasspathVariableInitializer;
+import com.zeroc.slice2javaplugin.preferences.PluginPreferencePage;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin
+{
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "com.zeroc.Slice2JavaPlugin";
+
+ /**
+ * The constructor
+ */
+ public Activator()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context)
+ throws Exception
+ {
+ super.start(context);
+ _plugin = this;
+
+ IEclipsePreferences prefs = new InstanceScope().getNode(PLUGIN_ID);
+ // set the listener for the preference change
+ //Preferences prefs = getPluginPreferences();
+ prefs.addPreferenceChangeListener(new IPreferenceChangeListener()
+ {
+ public List<IJavaProject> getSlice2JavaProjects(IJavaModel javaModel)
+ {
+ ArrayList<IJavaProject> pl = new ArrayList<IJavaProject>();
+ try
+ {
+ for(IJavaProject p : javaModel.getJavaProjects())
+ {
+ try
+ {
+ if(p.getProject().hasNature(Slice2JavaNature.NATURE_ID))
+ {
+ pl.add(p);
+ }
+ }
+ catch(CoreException e)
+ {
+ // The project isn't opened, or does not exist.
+ }
+ }
+ }
+ catch(JavaModelException jme)
+ {
+ }
+
+ return pl;
+ }
+
+ public void preferenceChange(PreferenceChangeEvent event)
+ {
+ String property = event.getKey();
+ if(PluginPreferencePage.SDK_PATH.equals(property))
+ {
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ IJavaModel javaModel = JavaCore.create(workspaceRoot);
+ List<IJavaProject> projects = getSlice2JavaProjects(javaModel);
+ String value = (String)event.getNewValue();
+ IceClasspathContainerIntializer.updateProjects(value, projects);
+ IceClasspathVariableInitializer.update(value);
+ // Need to trigger a clean build of the projects.
+ for(final IJavaProject p : projects)
+ {
+ Job job = new Job("Rebuild")
+ {
+ protected IStatus run(IProgressMonitor monitor)
+ {
+ try
+ {
+ p.getProject().build(IncrementalProjectBuilder.FULL_BUILD, Slice2JavaBuilder.BUILDER_ID, null,
+ monitor);
+ }
+ catch(CoreException e)
+ {
+ return new Status(Status.ERROR, Activator.PLUGIN_ID, 0, "rebuild failed", e);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ job.setPriority(Job.BUILD);
+ job.schedule(); // start as soon as possible
+ }
+ }
+
+ }
+ });
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context)
+ throws Exception
+ {
+ _plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault()
+ {
+ return _plugin;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given plug-in
+ * relative path
+ *
+ * @param path
+ * the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path)
+ {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+ // The shared instance
+ private static Activator _plugin;
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaBuilder.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaBuilder.java
new file mode 100644
index 00000000000..d65596deb95
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaBuilder.java
@@ -0,0 +1,1282 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.builder;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.zeroc.slice2javaplugin.Activator;
+import com.zeroc.slice2javaplugin.internal.Configuration;
+import com.zeroc.slice2javaplugin.internal.Dependencies;
+
+public class Slice2JavaBuilder extends IncrementalProjectBuilder
+{
+ public static final String BUILDER_ID = "com.zeroc.Slice2JavaPlugin.Slice2JavaBuilder";
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.internal.events.InternalBuilder#build(int,
+ * java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IProject[] build(int kind, @SuppressWarnings("rawtypes")Map args, IProgressMonitor monitor)
+ throws CoreException
+ {
+ long start = System.currentTimeMillis();
+
+ IResourceDelta delta = getDelta(getProject());
+ BuildState state = new BuildState(getProject(), delta, monitor);
+ state.dependencies.read();
+
+ try
+ {
+ if(kind == FULL_BUILD)
+ {
+ fullBuild(state, monitor);
+ }
+ else
+ {
+ if(delta == null)
+ {
+ fullBuild(state, monitor);
+ }
+ else
+ {
+ incrementalBuild(state, monitor);
+ }
+ }
+ }
+ finally
+ {
+ long end = System.currentTimeMillis();
+ if(state.out != null)
+ {
+ state.out.println("Build complete. Elapsed time: " + (end - start) / 1000 + "s.");
+ }
+ state.dependencies.write();
+ }
+ return null;
+ }
+
+ protected void clean(IProgressMonitor monitor)
+ throws CoreException
+ {
+ BuildState state = new BuildState(getProject(), null, monitor);
+
+ // Don't read the existing dependencies. That will have the
+ // effect of trashing them.
+
+ try
+ {
+ // Now, clean the generated sub-directory.
+ Set<IFile> files = new HashSet<IFile>();
+ getResources(files, state.generated.members());
+
+ for(IFile file : files)
+ {
+ // Don't delete "." files (such as .gitignore).
+ if(!file.getName().startsWith("."))
+ {
+ file.delete(true, false, monitor);
+ }
+ }
+ }
+ finally
+ {
+ state.dependencies.write();
+ }
+ }
+
+ static class StreamReaderThread extends Thread
+ {
+ public StreamReaderThread(InputStream in, StringBuffer out)
+ {
+ _in = new BufferedReader(new InputStreamReader(in), 1024);
+ _out = out;
+ }
+
+ public void run()
+ {
+ try
+ {
+ char[] buf = new char[1024];
+ while(true)
+ {
+ int read = _in.read(buf);
+ if(read == -1)
+ {
+ break;
+ }
+ _out.append(buf, 0, read);
+ }
+ }
+ catch(Exception e)
+ {
+ }
+ finally
+ {
+ try
+ {
+ _in.close();
+ }
+ catch(IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+ }
+
+ private StringBuffer _out;
+ private BufferedReader _in;
+ }
+
+ static class BuildState
+ {
+ BuildState(IProject project, IResourceDelta delta, IProgressMonitor monitor) throws CoreException
+ {
+ config = new Configuration(project);
+
+ if(config.getConsole())
+ {
+ initializeConsole();
+ out = _consoleout;
+ err = _consoleerr;
+ }
+
+ generated = project.getFolder(config.getGeneratedDir());
+ if(!generated.exists())
+ {
+ generated.create(false, true, monitor);
+ }
+
+ _sourceLocations = new HashSet<IFolder>();
+ for(Iterator<String> p = config.getSliceSourceDirs().iterator(); p.hasNext();)
+ {
+ _sourceLocations.add(project.getFolder(p.next()));
+ }
+
+ project.accept(new IResourceVisitor()
+ {
+ public boolean visit(IResource resource)
+ throws CoreException
+ {
+ if(resource instanceof IFile)
+ {
+ IFile file = (IFile) resource;
+ if(filter(file))
+ {
+ _resources.add((IFile) resource);
+ }
+ }
+ return true;
+ }
+ });
+
+ if(delta != null)
+ {
+ delta.accept(new IResourceDeltaVisitor()
+ {
+ public boolean visit(IResourceDelta delta)
+ throws CoreException
+ {
+ IResource resource = delta.getResource();
+ if(resource instanceof IFile)
+ {
+ IFile file = (IFile) resource;
+ if(filter(file))
+ {
+ switch (delta.getKind())
+ {
+ case IResourceDelta.ADDED:
+ case IResourceDelta.CHANGED:
+ _deltaCandidates.add(file);
+ break;
+ case IResourceDelta.REMOVED:
+ _removed.add(file);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ dependencies = new Dependencies(project, _resources, err);
+ }
+
+ public Set<IFile> deltas()
+ {
+ return _deltaCandidates;
+ }
+
+ public List<IFile> removed()
+ {
+ return _removed;
+ }
+
+ public Set<IFile> resources()
+ {
+ return _resources;
+ }
+
+ public boolean filter(IFile file)
+ {
+ String ext = file.getFileExtension();
+ if(ext != null && ext.equals("ice"))
+ {
+ //
+ // The parent may not be an IFolder (e.g., it could be a Project).
+ //
+ if(file.getParent() instanceof IFolder)
+ {
+ IFolder folder = (IFolder)file.getParent();
+ if(_sourceLocations.contains(folder))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ synchronized static private void initializeConsole()
+ {
+ if(_consoleout == null)
+ {
+ MessageConsole console = new MessageConsole("slice2java", null);
+ IConsole[] ics = new IConsole[1];
+ ics[0] = console;
+ IConsoleManager csmg = ConsolePlugin.getDefault().getConsoleManager();
+ csmg.addConsoles(ics);
+ csmg.showConsoleView(console);
+
+ _consoleout = console.newMessageStream();
+ _consoleerr = console.newMessageStream();
+
+ final Display display = PlatformUI.getWorkbench().getDisplay();
+ display.syncExec(new Runnable() {
+ public void run() {
+ _consoleerr.setColor(display.getSystemColor(SWT.COLOR_RED));
+ }
+ });
+ }
+ }
+
+ Configuration config;
+ Dependencies dependencies;
+ IFolder generated;
+ private Set<IFolder> _sourceLocations;
+
+ private Set<IFile> _resources = new HashSet<IFile>();
+ private Set<IFile> _deltaCandidates = new HashSet<IFile>();
+ private List<IFile> _removed = new ArrayList<IFile>();
+
+ private MessageConsoleStream out = null;
+ private MessageConsoleStream err = null;
+
+ static private MessageConsoleStream _consoleout = null;
+ static private MessageConsoleStream _consoleerr = null;
+ }
+
+ private int build(BuildState state, Set<IFile> files, boolean depend, StringBuffer out, StringBuffer err)
+ throws CoreException
+ {
+ // Clear the output buffer.
+ out.setLength(0);
+ if(err != null)
+ {
+ err.setLength(0);
+ }
+
+ List<String> cmd = new LinkedList<String>();
+ String translator = state.config.getTranslator();
+ if(translator == null)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Cannot locate slice2java translator: please fix Ice install location", null));
+ }
+
+ cmd.add(translator);
+ if(depend)
+ {
+ cmd.add("--depend-xml");
+ }
+ else
+ {
+ cmd.add("--output-dir=" + state.generated.getProjectRelativePath().toString());
+ cmd.add("--list-generated");
+ }
+ List<String> cmdBase = new LinkedList<String>();
+ cmdBase.addAll(cmd);
+
+ cmd.addAll(state.config.getCommandLine());
+
+ Set<IFile> resourcesWithArguments = new HashSet<IFile>();
+
+ boolean allHasOptions = true;
+ for(Iterator<IFile> p = files.iterator(); p.hasNext();)
+ {
+ IFile f = p.next();
+ if(!Configuration.resourceHasOptions(f))
+ {
+ allHasOptions = false;
+ cmd.add(f.getLocation().toOSString());
+ }
+ else
+ {
+ resourcesWithArguments.add(f);
+ }
+ }
+
+ ProcessBuilder builder;
+ IPath rootLocation = getProject().getLocation();
+ Map<String, String> env;
+ int status = 0;
+
+ if(!allHasOptions)
+ {
+ builder = new ProcessBuilder(cmd);
+ if(err == null)
+ {
+ builder.redirectErrorStream(true);
+ }
+
+ builder.directory(rootLocation.toFile());
+ env = builder.environment();
+ Configuration.setupSharedLibraryPath(env);
+
+ status = runSliceCompiler(builder, state, out, err);
+ }
+
+ for(Iterator<IFile> p = resourcesWithArguments.iterator(); p.hasNext();)
+ {
+ IFile f = p.next();
+ cmd = new LinkedList<String>();
+ cmd.addAll(cmdBase);
+ cmd.addAll(state.config.getCommandLine(f));
+
+ cmd.add(f.getLocation().toOSString());
+
+ builder = new ProcessBuilder(cmd);
+ if(err == null)
+ {
+ builder.redirectErrorStream(true);
+ }
+ builder.directory(rootLocation.toFile());
+ env = builder.environment();
+ Configuration.setupSharedLibraryPath(env);
+
+ status = runSliceCompiler(builder, state, out, err);
+ }
+
+ return status;
+ }
+
+ private int
+ runSliceCompiler(ProcessBuilder builder, BuildState state, StringBuffer out, StringBuffer err)
+ throws CoreException
+ {
+ try
+ {
+
+
+ if(state.out != null)
+ {
+ for(Iterator<String> p = builder.command().iterator(); p.hasNext();)
+ {
+ state.out.print(p.next());
+ state.out.print(" ");
+ }
+ state.out.println("");
+ }
+
+ Process proc = builder.start();
+
+ StreamReaderThread outThread = new StreamReaderThread(proc.getInputStream(), out);
+ outThread.start();
+ StreamReaderThread errThread = null;
+ if(err != null)
+ {
+ errThread = new StreamReaderThread(proc.getErrorStream(), err);
+ errThread.start();
+ }
+
+ int status = proc.waitFor();
+
+ outThread.join();
+ if(errThread != null)
+ {
+ errThread.join();
+ }
+
+ if(status != 0 && state.err != null)
+ {
+ state.err.println("slice2java status: " + status);
+ }
+
+ return status;
+ }
+ catch(Exception e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString(), null));
+ }
+ }
+
+ private void
+ createMarker(BuildState state, IFile source, IPath filename, int line, String msg)
+ throws CoreException
+ {
+ // Process the error.
+ IPath dir = getProject().getLocation();
+
+ IFile file = null;
+ if(filename != null && dir.isPrefixOf(filename))
+ {
+ // Locate the file within the project.
+ file = getProject().getFile(filename.removeFirstSegments(dir.segmentCount()));
+
+ // If the file is not the current source file, and the file exists in the project
+ // then it must already contain a marker, so don't place another.
+ if(!file.equals(source) && state.filter(file))
+ {
+ return;
+ }
+ }
+
+ // If the message isn't contained in the source file, then identify the
+ // file:line in the message itself.
+ if(file == null)
+ {
+ if(line != -1)
+ {
+ msg = filename + ":" + line + ": " + msg;
+ }
+ else
+ {
+ msg = filename + ": " + msg;
+ }
+ }
+
+ IMarker marker = source.createMarker(IMarker.PROBLEM);
+ marker.setAttribute(IMarker.MESSAGE, msg);
+ if(msg.toLowerCase().indexOf("warning:") >= 0)
+ {
+ marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
+ }
+ else
+ {
+ marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+ }
+ if(line != -1)
+ {
+ if(file != null && file.equals(source))
+ {
+ marker.setAttribute(IMarker.LINE_NUMBER, line);
+ }
+ else
+ {
+ marker.setAttribute(IMarker.LINE_NUMBER, 1);
+ }
+ }
+ }
+
+ private void createMarkers(BuildState state, IFile source, String output)
+ throws CoreException
+ {
+ output = output.trim();
+ if(output.length() == 0)
+ {
+ return;
+ }
+
+ String[] lines = output.split("\n");
+
+ IPath filename = null;
+ int line = -1;
+ StringBuffer msg = new StringBuffer();
+
+ boolean continuation = false;
+
+ for(int i = 0; i < lines.length; ++i)
+ {
+ if(continuation)
+ {
+ if(lines[i].startsWith(" "))
+ {
+ // Continuation of the previous message.
+ msg.append(lines[i]);
+ continue;
+ }
+ else
+ {
+ // Process the message.
+ createMarker(state, source, filename, line, msg.toString());
+ }
+ }
+
+ // We're on a new message.
+ msg.setLength(0);
+ continuation = false;
+
+ // Ignore.
+ if(lines[i].contains("errors in preprocessor") || lines[i].contains("error in preprocessor"))
+ {
+ continue;
+ }
+
+ //
+ // Parse a line of the form:
+ //
+ // file:[line:] message
+ //
+ int start = 0;
+ int end;
+ // Handle drive letters.
+ if(lines[i].length() > 2 && lines[i].charAt(1) == ':')
+ {
+ end = lines[i].indexOf(':', 2);
+ }
+ else
+ {
+ end = lines[i].indexOf(':');
+ }
+ if(end != -1)
+ {
+ filename = new Path(lines[i].substring(start, end));
+ start = end + 1;
+ end = lines[i].indexOf(':', start);
+ if(end != -1)
+ {
+ try
+ {
+ line = Integer.parseInt(lines[i].substring(start, end));
+ start = end + 1;
+ }
+ catch(NumberFormatException e)
+ {
+ // The message may not have a line number.
+ line = -1;
+ }
+ msg.append(lines[i].substring(start, lines[i].length()));
+
+ continuation = true;
+ continue;
+ }
+ }
+ // Unknown format.
+ createMarker(state, source, null, -1, lines[i]);
+ }
+
+ if(continuation)
+ {
+ createMarker(state, source, filename, line, msg.toString());
+ }
+ }
+
+ private void getResources(Set<IFile> files, IResource[] members)
+ throws CoreException
+ {
+ for(int i = 0; i < members.length; ++i)
+ {
+ if(members[i] instanceof IFile)
+ {
+ files.add((IFile) members[i]);
+ }
+ else if(members[i] instanceof IFolder)
+ {
+ getResources(files, ((IFolder) members[i]).members());
+ }
+ }
+ }
+
+ private void fullBuild(BuildState state, final IProgressMonitor monitor)
+ throws CoreException
+ {
+ clean(monitor);
+ Set<IFile> candidates = state.resources();
+ if(candidates.isEmpty())
+ {
+ return;
+ }
+
+ if(state.out != null)
+ {
+ java.util.Date date = new java.util.Date();
+ state.out.println("Start full build at " + new SimpleDateFormat("HH:mm:ss").format(date));
+
+ state.out.println("Candidate list:");
+ // This is a complete list of Slice files.
+ for(Iterator<IFile> p = candidates.iterator(); p.hasNext();)
+ {
+ state.out.println(" " + p.next().getProjectRelativePath().toString());
+ }
+ state.out.println("Regenerating java source files.");
+ }
+
+ StringBuffer out = new StringBuffer();
+
+ Set<IFile> depends = new HashSet<IFile>();
+
+ // Delete each marker.
+ for(Iterator<IFile> p = candidates.iterator(); p.hasNext();)
+ {
+ IFile file = p.next();
+ file.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+ }
+
+ // Do the build.
+ build(state, candidates, false, out, null);
+
+ out = mergeXmls(out, false);
+
+ // Refresh the generated subdirectory prior to processing the
+ // generated files list.
+ state.generated.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+
+ // Parse the output.
+ Slice2JavaGeneratedParser parser = getGeneratedFiles(state, candidates, out);
+ for(Map.Entry<IFile, Slice2JavaGeneratedParser.Entry> entry : parser.output.entrySet())
+ {
+ IFile source = entry.getKey();
+
+ Slice2JavaGeneratedParser.Entry outputEntry = entry.getValue();
+ Set<IFile> newGeneratedJavaFiles = outputEntry.files;
+
+ for(IFile f : newGeneratedJavaFiles)
+ {
+ // Mark the resource as derived.
+ f.setDerived(true, null);
+ }
+
+ if(!outputEntry.error)
+ {
+ depends.add(source);
+ if(state.out != null)
+ {
+ if(newGeneratedJavaFiles.isEmpty())
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": No java files emitted.");
+ }
+ else
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": Emitted:");
+ for(Iterator<IFile> q = newGeneratedJavaFiles.iterator(); q.hasNext();)
+ {
+ state.out.println(" " + q.next().getProjectRelativePath().toString());
+ }
+ }
+ }
+ }
+ else
+ {
+ state.dependencies.errorSliceFiles.add(source);
+ if(state.out != null)
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": Error.");
+ }
+ }
+
+ // Update the set of slice -> java dependencies.
+ state.dependencies.sliceJavaDependencies.put(source, newGeneratedJavaFiles);
+
+ // Create markers for each warning/error.
+ createMarkers(state, source, outputEntry.output);
+ }
+
+ // Update the slice->slice dependencies.
+ // Only update the dependencies for those files with no build problems.
+ if(!depends.isEmpty())
+ {
+ if(state.out != null)
+ {
+ state.out.println("Updating dependencies.");
+ }
+
+ StringBuffer err = new StringBuffer();
+ if(build(state, depends, true, out, err) == 0)
+ {
+ out = mergeXmls(out, true);
+ // Parse the new dependency set.
+ state.dependencies.updateDependencies(out.toString());
+ }
+ else if(state.err != null)
+ {
+ state.err.println("Dependencies not updated due to error.");
+ state.err.println(err.toString());
+ }
+ }
+ }
+
+ private void incrementalBuild(BuildState state, IProgressMonitor monitor)
+ throws CoreException
+ {
+ Set<IFile> candidates = state.deltas();
+ List<IFile> removed = state.removed();
+
+ if(state.out != null)
+ {
+ java.util.Date date = new java.util.Date();
+ state.out.println("Start incremental build at " + new SimpleDateFormat("HH:mm:ss").format(date));
+
+ state.out.println("Candidate list:");
+ // This is a complete list of slice files.
+ for(Iterator<IFile> p = candidates.iterator(); p.hasNext();)
+ {
+ state.out.println(" + " + p.next().getProjectRelativePath().toString());
+ }
+ for(Iterator<IFile> p = removed.iterator(); p.hasNext();)
+ {
+ state.out.println(" - " + p.next().getProjectRelativePath().toString());
+ }
+ }
+
+ // The orphan candidate set.
+ Set<IFile> orphanCandidateSet = new HashSet<IFile>();
+
+ // Go through the removed list, removing the dependencies.
+ for(Iterator<IFile> p = removed.iterator(); p.hasNext();)
+ {
+ IFile f = p.next();
+
+ // Remove the file from the error list, if necessary.
+ if(state.dependencies.errorSliceFiles.contains(f))
+ {
+ state.dependencies.errorSliceFiles.remove(f);
+ }
+
+ Set<IFile> dependents = state.dependencies.sliceSliceDependencies.remove(f);
+ if(dependents != null)
+ {
+ Iterator<IFile> dependentsIterator = dependents.iterator();
+ while(dependentsIterator.hasNext())
+ {
+ IFile dependent = dependentsIterator.next();
+ Set<IFile> files = state.dependencies.reverseSliceSliceDependencies.get(dependent);
+ if(files != null)
+ {
+ files.remove(f);
+ }
+ }
+ }
+
+ Set<IFile> oldJavaFiles = state.dependencies.sliceJavaDependencies.remove(f);
+ if(state.out != null)
+ {
+ if(oldJavaFiles == null || oldJavaFiles.isEmpty())
+ {
+ state.out.println(f.getProjectRelativePath().toString() + ": No orphans.");
+ }
+ else
+ {
+ state.out.println(f.getProjectRelativePath().toString() + ": Orphans:");
+ for(Iterator<IFile> q = oldJavaFiles.iterator(); q.hasNext();)
+ {
+ state.out.println(" " + q.next().getProjectRelativePath().toString());
+ }
+ }
+ }
+
+ if(oldJavaFiles != null)
+ {
+ orphanCandidateSet.addAll(oldJavaFiles);
+ }
+ }
+
+ // Add the removed files to the candidates set
+ // prior to determining additional candidates.
+ candidates.addAll(removed);
+
+ // Add to the candidate set any slice files that are in error. Clear the
+ // error list.
+ candidates.addAll(state.dependencies.errorSliceFiles);
+ state.dependencies.errorSliceFiles.clear();
+
+ Set<IFile> candidatesTmp = new HashSet<IFile>();
+
+ for(Iterator<IFile> p = candidates.iterator(); p.hasNext();)
+ {
+ IFile f = p.next();
+
+ Set<IFile> files = state.dependencies.reverseSliceSliceDependencies.get(f);
+ if(files != null)
+ {
+ for(Iterator<IFile> q = files.iterator(); q.hasNext();)
+ {
+ IFile potentialCandidate = q.next();
+ if(potentialCandidate.exists())
+ {
+ candidatesTmp.add(potentialCandidate);
+ }
+ }
+ }
+
+ // If this is a file in the contained list, then remove the
+ // dependency entry.
+ if(removed.contains(f))
+ {
+ state.dependencies.reverseSliceSliceDependencies.remove(f);
+ }
+ }
+ candidates.addAll(candidatesTmp);
+
+ // Remove all the removed files from the candidates list.
+ candidates.removeAll(removed);
+
+ if(state.out != null)
+ {
+ if(candidates.isEmpty())
+ {
+ state.out.println("No remaining candidates.");
+ }
+ else
+ {
+ state.out.println("Expanded candidate list:");
+ // This is a complete list of slice files.
+ for(Iterator<IFile> p = candidates.iterator(); p.hasNext();)
+ {
+ state.out.println(" " + p.next().getProjectRelativePath().toString());
+ }
+ }
+ }
+
+ StringBuffer out = new StringBuffer();
+
+ // The set of files that we'll generate dependencies for.
+ Set<IFile> depends = new HashSet<IFile>();
+
+ if(!candidates.isEmpty())
+ {
+ if(state.out != null)
+ {
+ state.out.println("Regenerating java source files.");
+ }
+
+ // The complete set of generated java files by this build.
+ Set<IFile> generatedJavaFiles = new HashSet<IFile>();
+
+ // Remove all markers for the candidate list.
+ for(Iterator<IFile> p = candidates.iterator(); p.hasNext();)
+ {
+ IFile file = p.next();
+ file.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+ }
+
+ // Do the build.
+ build(state, candidates, false, out, null);
+ out = mergeXmls(out, false);
+
+ // Refresh the generated directory prior to processing the generated
+ // files list.
+ state.generated.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+
+ // Parse the emitted XML file that describes what was produced by
+ // the build.
+ Slice2JavaGeneratedParser parser = getGeneratedFiles(state, candidates, out);
+ for(Map.Entry<IFile, Slice2JavaGeneratedParser.Entry> entry : parser.output.entrySet())
+ {
+ IFile source = entry.getKey();
+
+ Slice2JavaGeneratedParser.Entry outputEntry = entry.getValue();
+
+ Set<IFile> newGeneratedJavaFiles = outputEntry.files;
+ for(IFile f : newGeneratedJavaFiles)
+ {
+ // Mark the resource as derived.
+ f.setDerived(true, null);
+ }
+
+ // If the build of the file didn't result in an error, add to
+ // the dependencies list. Otherwise, add to the error list.
+ if(!outputEntry.error)
+ {
+ depends.add(source);
+ }
+ else
+ {
+ if(state.out != null)
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": Error.");
+ }
+ state.dependencies.errorSliceFiles.add(source);
+ }
+
+ // Compute the set difference between the old set and new set
+ // of generated files. The difference should be added to the
+ // orphan candidate set.
+ Set<IFile> oldJavaFiles = state.dependencies.sliceJavaDependencies.get(source);
+ if(oldJavaFiles != null)
+ {
+ // Compute the set difference.
+ oldJavaFiles.removeAll(newGeneratedJavaFiles);
+ if(state.out != null)
+ {
+ if(oldJavaFiles.isEmpty())
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": No orphans.");
+ }
+ else
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": Orphans:");
+ for(Iterator<IFile> q = oldJavaFiles.iterator(); q.hasNext();)
+ {
+ state.out.println(" " + q.next().getProjectRelativePath().toString());
+ }
+ }
+ }
+ orphanCandidateSet.addAll(oldJavaFiles);
+ }
+
+ // Update the set of slice -> java dependencies.
+ state.dependencies.sliceJavaDependencies.put(source, newGeneratedJavaFiles);
+
+ // If the build resulted in an error, there will be no java source files.
+ if(state.out != null && !outputEntry.error)
+ {
+ if(newGeneratedJavaFiles.isEmpty())
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": No java files emitted.");
+ }
+ else
+ {
+ state.out.println(source.getProjectRelativePath().toString() + ": Emitted:");
+ for(Iterator<IFile> q = newGeneratedJavaFiles.iterator(); q.hasNext();)
+ {
+ state.out.println(" " + q.next().getProjectRelativePath().toString());
+ }
+ }
+ }
+
+ generatedJavaFiles.addAll(newGeneratedJavaFiles);
+
+ // Create markers for each warning/error.
+ createMarkers(state, source, outputEntry.output);
+ }
+
+ // Do a set difference between the orphan candidate set
+ // and the complete set of generated java source files.
+ // Any remaining are complete orphans and should
+ // be removed.
+ orphanCandidateSet.removeAll(generatedJavaFiles);
+ }
+
+ if(state.out != null)
+ {
+ if(orphanCandidateSet.isEmpty())
+ {
+ state.out.println("No orphans from this build.");
+ }
+ else
+ {
+ state.out.println("Orphans from this build:");
+ for(Iterator<IFile> p = orphanCandidateSet.iterator(); p.hasNext();)
+ {
+ state.out.println(" " + p.next().getProjectRelativePath().toString());
+ }
+ }
+ }
+
+ //
+ // Remove orphans.
+ //
+ for(Iterator<IFile> p = orphanCandidateSet.iterator(); p.hasNext();)
+ {
+ p.next().delete(true, false, monitor);
+ }
+
+ // The dependencies of any files without build errors should be updated.
+ if(!depends.isEmpty())
+ {
+ if(state.out != null)
+ {
+ state.out.println("Updating dependencies.");
+ }
+
+ StringBuffer err = new StringBuffer();
+
+ // We've already added markers for any errors... Only update the
+ // dependencies if no problems resulted in the build.
+ if(build(state, depends, true, out, err) == 0)
+ {
+ out = mergeXmls(out, true);
+ // Parse the new dependency set.
+ state.dependencies.updateDependencies(out.toString());
+ }
+ else if(state.err != null)
+ {
+ state.err.println("Dependencies not updated due to error.");
+ state.err.println(err.toString());
+ }
+ }
+ }
+
+ //
+ // This method merge the XML produced by multiple Slice translator
+ // invocations in a single XML. If depend argument is true, the input
+ // buffer is treated as a dependencies XML, otherwise is treated as
+ // a generated list XML.
+ //
+ private StringBuffer
+ mergeXmls(StringBuffer input, boolean depend)
+ {
+ //
+ // Merge depend XMLs in a single XML
+ //
+ String v = input.toString();
+ StringTokenizer lines = new StringTokenizer(v, System.getProperty("line.separator"));
+ boolean firstLine = true;
+ boolean firstGenerated = true;
+ StringBuffer out = new StringBuffer();
+ while(lines.hasMoreTokens())
+ {
+ String line = lines.nextToken();
+ if(line.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") &&
+ !firstLine)
+ {
+ continue;
+ }
+
+ if(depend)
+ {
+ if(line.equals("<dependencies>"))
+ {
+ if(firstGenerated)
+ {
+ firstGenerated = false;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else if(line.equals("</dependencies>") && lines.hasMoreTokens())
+ {
+ continue;
+ }
+ }
+ else
+ {
+ if(line.equals("<generated>"))
+ {
+ if(firstGenerated)
+ {
+ firstGenerated = false;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else if(line.equals("</generated>") && lines.hasMoreTokens())
+ {
+ continue;
+ }
+ }
+
+ out.append(line + "\n");
+ firstLine = false;
+ }
+ return out;
+ }
+
+ private static class Slice2JavaGeneratedParser
+ {
+ static class Entry
+ {
+ boolean error; // Did the build result in an error.
+ String output; // Any warnings/errors from the build.
+ Set<IFile> files; // The set of java source files associated with the source file.
+ }
+ Map<IFile, Entry> output = new HashMap<IFile, Entry>(); // Map of source files to build entry.
+
+ private IFolder _generated;
+ private IPath _generatedPath;
+ // Map of absolute path to project location.
+ private Map<IPath, IFile> _sources = new HashMap<IPath, IFile>();
+
+ Slice2JavaGeneratedParser(IFolder generated, Set<IFile> candidates)
+ {
+ _generated = generated;
+ _generatedPath = generated.getProjectRelativePath();
+ for(IFile f : candidates)
+ {
+ _sources.put(f.getLocation(), f);
+ }
+ }
+
+ private Node findNode(Node n, String qName)
+ throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(qName))
+ {
+ return child;
+ }
+ }
+ throw new SAXException("no such node: " + qName);
+ }
+
+ private IFile convert(String fname)
+ {
+ IPath p = new Path(fname); // fname contains "generated/...".
+ int match = p.matchingFirstSegments(_generatedPath);
+ return _generated.getFile(p.removeFirstSegments(match));
+ }
+
+ public Set<IFile> visitSource(Node source) throws SAXException
+ {
+ Set<IFile> files = new HashSet<IFile>();
+ NodeList sourceNodes = source.getChildNodes();
+ for(int j = 0; j < sourceNodes.getLength(); ++j)
+ {
+ if(sourceNodes.item(j).getNodeType() == Node.ELEMENT_NODE && sourceNodes.item(j).getNodeName().equals("file"))
+ {
+ Element file = (Element)sourceNodes.item(j);
+ String name = file.getAttribute("name");
+ if(name.length() == 0)
+ {
+ throw new SAXException("empty name attribute");
+ }
+ files.add(convert(name));
+ }
+ }
+ return files;
+ }
+
+ private String getText(Node n) throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ if(children.getLength() == 1 && children.item(0).getNodeType() == Node.TEXT_NODE)
+ {
+ return children.item(0).getNodeValue();
+ }
+ return "";
+ }
+
+ public void visit(Node doc) throws SAXException
+ {
+ Node n = findNode(doc, "generated");
+ NodeList fileNodes = n.getChildNodes();
+ for(int j = 0; j < fileNodes.getLength(); ++j)
+ {
+ if(fileNodes.item(j).getNodeType() == Node.ELEMENT_NODE && fileNodes.item(j).getNodeName().equals("source"))
+ {
+ Element sourceElement = (Element)fileNodes.item(j);
+ String name = sourceElement.getAttribute("name");
+ if(name.length() == 0)
+ {
+ throw new SAXException("empty name attribute");
+ }
+
+ // The source file
+ IFile source = _sources.get(new Path(name));
+ if(source == null)
+ {
+ throw new SAXException("unknown source file: " + name);
+ }
+
+ Entry e = new Entry();
+ e.error = true;
+ e.output = getText(findNode(sourceElement, "output"));
+
+ String error = sourceElement.getAttribute("error");
+ if(error.equals("true"))
+ {
+ e.error = true;
+ e.files = new HashSet<IFile>();
+ }
+ else
+ {
+ e.error = false;
+ e.files = visitSource(sourceElement);
+ }
+ output.put(source, e);
+ }
+ }
+ }
+ }
+
+ private Slice2JavaGeneratedParser getGeneratedFiles(BuildState state, Set<IFile> candidates, StringBuffer out)
+ throws CoreException
+ {
+ Slice2JavaGeneratedParser parser = new Slice2JavaGeneratedParser(state.generated, candidates);
+ try
+ {
+ InputStream in = new ByteArrayInputStream(out.toString().getBytes());
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new BufferedInputStream(in));
+ parser.visit(doc);
+ }
+ catch(SAXException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading the generated output list", e));
+ }
+ catch(ParserConfigurationException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading the generated output list", e));
+ }
+ catch(IOException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading the generated output list", e));
+ }
+ return parser;
+ }
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaNature.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaNature.java
new file mode 100644
index 00000000000..af9710ee4b8
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/Slice2JavaNature.java
@@ -0,0 +1,108 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.builder;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public class Slice2JavaNature implements IProjectNature
+{
+ /**
+ * ID of this project nature
+ */
+ public static final String NATURE_ID = "com.zeroc.Slice2JavaPlugin.Slice2JavaNature";
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#configure()
+ */
+ public void configure()
+ throws CoreException
+ {
+ IProjectDescription desc = _project.getDescription();
+ ICommand[] commands = desc.getBuildSpec();
+
+ for(int i = 0; i < commands.length; ++i)
+ {
+ if(commands[i].getBuilderName().equals(Slice2JavaBuilder.BUILDER_ID))
+ {
+ return;
+ }
+ }
+
+ ICommand[] newCommands = new ICommand[commands.length + 1];
+ System.arraycopy(commands, 0, newCommands, 1, commands.length);
+ ICommand command = desc.newCommand();
+ command.setBuilderName(Slice2JavaBuilder.BUILDER_ID);
+ newCommands[0] = command;
+ desc.setBuildSpec(newCommands);
+
+ _project.setDescription(desc, null);
+
+ // Initialize a new configuration for this project.
+ Configuration config = new Configuration(_project);
+ config.initialize();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+ */
+ public void deconfigure()
+ throws CoreException
+ {
+ IProjectDescription description = getProject().getDescription();
+ ICommand[] commands = description.getBuildSpec();
+ for(int i = 0; i < commands.length; ++i)
+ {
+ if(commands[i].getBuilderName().equals(Slice2JavaBuilder.BUILDER_ID))
+ {
+ ICommand[] newCommands = new ICommand[commands.length - 1];
+ System.arraycopy(commands, 0, newCommands, 0, i);
+ System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
+ description.setBuildSpec(newCommands);
+ return;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#getProject()
+ */
+ public IProject getProject()
+ {
+ return _project;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core
+ * .resources.IProject)
+ */
+ public void setProject(IProject project)
+ {
+ _project = project;
+ }
+
+
+ private IProject _project;
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/ToggleNatureAction.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/ToggleNatureAction.java
new file mode 100644
index 00000000000..dbeaf33a359
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/builder/ToggleNatureAction.java
@@ -0,0 +1,128 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.builder;
+
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public class ToggleNatureAction implements IObjectActionDelegate
+{
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ */
+
+ public void run(IAction action)
+ {
+ if(_selection instanceof IStructuredSelection)
+ {
+ for(Iterator<?> it = ((IStructuredSelection) _selection).iterator(); it.hasNext();)
+ {
+ Object element = it.next();
+ IProject project = null;
+ if(element instanceof IProject)
+ {
+ project = (IProject) element;
+ }
+ else if(element instanceof IAdaptable)
+ {
+ project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
+ }
+ if(project != null)
+ {
+ toggleNature(project);
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action
+ * .IAction, org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IAction action, ISelection selection)
+ {
+ this._selection = selection;
+ //action.setEnabled(false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.
+ * action.IAction, org.eclipse.ui.IWorkbenchPart)
+ */
+ public void setActivePart(IAction action, IWorkbenchPart targetPart)
+ {
+ //action.setEnabled(false);
+ }
+
+ /**
+ * Toggles sample nature on a project
+ *
+ * @param project
+ * to have sample nature added or removed
+ */
+ private void toggleNature(IProject project)
+ {
+ try
+ {
+ IProjectDescription description = project.getDescription();
+ String[] natures = description.getNatureIds();
+
+ for(int i = 0; i < natures.length; ++i)
+ {
+ if(Slice2JavaNature.NATURE_ID.equals(natures[i]))
+ {
+ // Remove the nature
+ String[] newNatures = new String[natures.length - 1];
+ System.arraycopy(natures, 0, newNatures, 0, i);
+ System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
+ description.setNatureIds(newNatures);
+ project.setDescription(description, null);
+
+ Configuration c = new Configuration(project);
+ c.deinstall();
+
+ return;
+ }
+ }
+
+ // Add the nature
+ String[] newNatures = new String[natures.length + 1];
+ System.arraycopy(natures, 0, newNatures, 0, natures.length);
+ newNatures[natures.length] = Slice2JavaNature.NATURE_ID;
+ description.setNatureIds(newNatures);
+ project.setDescription(description, null);
+ }
+ catch(CoreException e)
+ {
+ }
+ }
+
+ private ISelection _selection;
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/GeneratedDecorator.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/GeneratedDecorator.java
new file mode 100644
index 00000000000..ec832072a01
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/GeneratedDecorator.java
@@ -0,0 +1,67 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.decorator;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public class GeneratedDecorator implements ILabelDecorator
+{
+
+ public void addListener(ILabelProviderListener arg0)
+ {
+ }
+
+ public void dispose()
+ {
+ }
+
+ public boolean isLabelProperty(Object arg0, String arg1)
+ {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener arg0)
+ {
+ }
+
+ public Image decorateImage(Image arg0, Object arg1)
+ {
+ return null;
+ }
+
+ public String decorateText(String label, Object object)
+ {
+ IResource resource = (IResource) object;
+ if(resource.getType() != IResource.FOLDER)
+ {
+ // Only folders are decorated.
+ return null;
+ }
+ IProject project = resource.getProject();
+ Configuration configuration = new Configuration(project);
+ IFolder generated = project.getFolder(configuration.getGeneratedDir());
+ if(!generated.getLocation().toOSString().equals(resource.getLocation().toOSString()))
+ {
+ // We just need to decorate the slice2java generated folder.
+ return null;
+ }
+
+ return label + " [Generated slice2java sources]";
+ }
+
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/SliceDecorator.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/SliceDecorator.java
new file mode 100644
index 00000000000..bd8336f03e8
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/decorator/SliceDecorator.java
@@ -0,0 +1,75 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.decorator;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public class SliceDecorator implements ILabelDecorator
+{
+
+ public void addListener(ILabelProviderListener arg0)
+ {
+ }
+
+ public void dispose()
+ {
+ }
+
+ public boolean isLabelProperty(Object arg0, String arg1)
+ {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener arg0)
+ {
+ }
+
+ public Image decorateImage(Image arg0, Object arg1)
+ {
+ return null;
+ }
+
+ public String decorateText(String label, Object object)
+ {
+ IResource resource = (IResource) object;
+ if(resource.getType() != IResource.FOLDER)
+ {
+ // Only folders are decorated.
+ return null;
+ }
+ IProject project = resource.getProject();
+ Configuration configuration = new Configuration(project);
+ List<String> slices = configuration.getSliceSourceDirs();
+
+ boolean decorated = false;
+ for(int i = 0; i < slices.size(); ++i)
+ {
+ IFolder f = project.getFolder(slices.get(i));
+ if(f.getLocation().toOSString().equals(resource.getLocation().toOSString()))
+ {
+ decorated = true;
+ break;
+ }
+ }
+
+ return decorated ? label + " [Slice sources]": label;
+ }
+
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Configuration.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Configuration.java
new file mode 100644
index 00000000000..ad50b474c14
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Configuration.java
@@ -0,0 +1,1021 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.internal;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+
+import com.zeroc.slice2javaplugin.Activator;
+import com.zeroc.slice2javaplugin.preferences.PluginPreferencePage;
+
+public class Configuration
+{
+ public Configuration(IProject project)
+ {
+ _project = project;
+
+ _instanceStore = new ScopedPreferenceStore(new InstanceScope(), Activator.PLUGIN_ID + "." + _project.getName());
+
+ _store = new ScopedPreferenceStore(new ProjectScope(project), Activator.PLUGIN_ID);
+
+ _androidProject = false;
+ try
+ {
+ _androidProject = project.hasNature("com.android.ide.eclipse.adt.AndroidNature");
+ }
+ catch(CoreException e)
+ {
+ }
+
+ _store.setDefault(GENERATED_KEY, GENERATED_KEY);
+ _store.setDefault(DEFINES_KEY, "");
+ _store.setDefault(TIE_KEY, false);
+ _store.setDefault(ICE_KEY, false);
+ _store.setDefault(STREAM_KEY, false);
+ _store.setDefault(ICE_INCLUDE_KEY, false);
+ _store.setDefault(META_KEY, "");
+ _store.setDefault(CONSOLE_KEY, false);
+ _store.setDefault(SLICE_SOURCE_DIRS_KEY, "slice");
+ _store.setDefault(INCLUDES_KEY, "");
+ _store.setDefault(ADD_JARS_KEY, true);
+ _store.setDefault(UNDERSCORE_KEY, false);
+
+ _store.setDefault(JARS_KEY, "Ice.jar");
+ }
+
+ /**
+ * Turns list of strings into a single ';' delimited string. ';' in the
+ * string values are escaped with a leading '\'. '\' are turned into '\\'.
+ *
+ * @param l
+ * List of strings.
+ * @return Semicolon delimited string.
+ */
+ static public String fromList(List<String> l)
+ {
+ StringBuffer sb = new StringBuffer();
+ for(Iterator<String> p = l.iterator(); p.hasNext();)
+ {
+ if(sb.length() > 0)
+ {
+ sb.append(";");
+ }
+ sb.append(escape(p.next()));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Turn a semicolon delimited string into a list of strings. Escaped values
+ * are preserved (characters prefixed with a '\').
+ *
+ * @param s
+ * Semicolon delimited string.
+ * @return List of strings.
+ */
+ static public List<String> toList(String s)
+ {
+ java.util.List<String> l = new ArrayList<String>();
+ int curr = 0;
+ int end = s.length();
+ boolean escape = false;
+ StringBuffer sb = new StringBuffer();
+ for(curr = 0; curr < end; ++curr)
+ {
+ char ch = s.charAt(curr);
+ if(escape)
+ {
+ sb.append(ch);
+ escape = false;
+ }
+ else
+ {
+ if(ch == ';')
+ {
+ String tok = sb.toString().trim();
+ sb.setLength(0);
+ if(tok.length() > 0)
+ {
+ l.add(tok);
+ }
+ }
+ else if(ch == '\\')
+ {
+ escape = true;
+ }
+ else
+ {
+ sb.append(ch);
+ }
+ }
+ }
+ String tok = sb.toString().trim();
+ if(tok.length() > 0)
+ {
+ l.add(tok);
+ }
+ return l;
+ }
+
+ public boolean write()
+ throws CoreException, IOException
+ {
+ boolean rc = false;
+ if(_store.needsSaving())
+ {
+ _store.save();
+ rc = true;
+ }
+ if(_instanceStore.needsSaving())
+ {
+ _instanceStore.save();
+ rc = true;
+ }
+
+ if(rc)
+ {
+ IJavaProject javaProject = JavaCore.create(_project);
+ if(getAddJars())
+ {
+ addLibrary(javaProject);
+ }
+ else
+ {
+ removeLibrary(javaProject);
+ }
+ }
+
+ return rc;
+ }
+
+ public void initialize()
+ throws CoreException
+ {
+ // Create the slice source directories, if necessary.
+ for(Iterator<String> p = getSliceSourceDirs().iterator(); p.hasNext();)
+ {
+ IFolder slice = _project.getFolder(p.next());
+ if(!slice.exists())
+ {
+ slice.create(false, true, null);
+ }
+ }
+
+ // Create the generated directory, if necessary.
+ IFolder generated = _project.getFolder(getGeneratedDir());
+ if(!generated.exists())
+ {
+ generated.create(false, true, null);
+ }
+
+ fixGeneratedCP(null, getGeneratedDir());
+
+ IJavaProject javaProject = JavaCore.create(_project);
+ addLibrary(javaProject);
+ }
+
+ public void deinstall()
+ throws CoreException
+ {
+ IJavaProject javaProject = JavaCore.create(_project);
+ removeLibrary(javaProject);
+ removedGeneratedCP();
+ IFolder generatedFolder = _project.getFolder(getGeneratedDir());
+ if(generatedFolder != null && generatedFolder.exists())
+ {
+ generatedFolder.delete(true, null);
+ }
+ }
+
+ public boolean isAndroidProject()
+ {
+ return _androidProject;
+ }
+
+ public List<String> getSliceSourceDirs()
+ {
+ return toList(_store.getString(SLICE_SOURCE_DIRS_KEY));
+ }
+
+ public void setSliceSourceDirs(List<String> sliceSourceDirs)
+ {
+ setValue(SLICE_SOURCE_DIRS_KEY, fromList(sliceSourceDirs));
+ }
+
+ public String getGeneratedDir()
+ {
+ return _store.getString(GENERATED_KEY);
+ }
+
+ public void fixGeneratedCP(String oldG, String newG)
+ throws CoreException
+ {
+ IJavaProject javaProject = JavaCore.create(_project);
+
+ IFolder newGenerated = _project.getFolder(newG);
+
+ IClasspathEntry[] entries = javaProject.getRawClasspath();
+ IClasspathEntry newEntry = JavaCore.newSourceEntry(newGenerated.getFullPath());
+
+ if(oldG != null)
+ {
+ IFolder oldGenerated = _project.getFolder(oldG);
+ IClasspathEntry oldEntry = JavaCore.newSourceEntry(oldGenerated.getFullPath());
+ for(int i = 0; i < entries.length; ++i)
+ {
+ if(entries[i].equals(oldEntry))
+ {
+ entries[i] = newEntry;
+ javaProject.setRawClasspath(entries, null);
+ oldGenerated.delete(true, null);
+ return;
+ }
+ }
+ }
+
+ IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
+ System.arraycopy(entries, 0, newEntries, 1, entries.length);
+ newEntries[0] = newEntry;
+
+ newGenerated.setDerived(true, null);
+
+ try
+ {
+ javaProject.setRawClasspath(newEntries, null);
+ }
+ catch(JavaModelException e)
+ {
+ // This can occur if a duplicate CLASSPATH entry is made.
+ //
+ // throw new CoreException(new Status(IStatus.ERROR,
+ // Activator.PLUGIN_ID, e.toString(), null));
+ }
+ }
+
+ public void removedGeneratedCP()
+ throws CoreException
+ {
+ IJavaProject javaProject = JavaCore.create(_project);
+
+ IFolder generated = _project.getFolder(getGeneratedDir());
+
+ IClasspathEntry generatedEntry = JavaCore.newSourceEntry(generated.getFullPath());
+
+ IClasspathEntry[] entries = javaProject.getRawClasspath();
+ IClasspathEntry[] newEntries = new IClasspathEntry[entries.length - 1];
+
+ for(int i = 0, j = 0; i < entries.length; i++)
+ {
+ if(entries[i].equals(generatedEntry))
+ {
+ continue;
+ }
+ newEntries[j] = entries[i];
+ j++;
+ }
+
+ try
+ {
+ javaProject.setRawClasspath(newEntries, null);
+ }
+ catch(JavaModelException e)
+ {
+ // This can occur if a duplicate CLASSPATH entry is made.
+ //
+ // throw new CoreException(new Status(IStatus.ERROR,
+ // Activator.PLUGIN_ID, e.toString(), null));
+ }
+ }
+
+ public void setGeneratedDir(String generated)
+ throws CoreException
+ {
+ String oldGenerated = getGeneratedDir();
+ if(setValue(GENERATED_KEY, generated))
+ {
+ fixGeneratedCP(oldGenerated, generated);
+ }
+ }
+
+ public List<String> getCommandLine()
+ {
+ List<String> cmds = new ArrayList<String>();
+ for(Iterator<String> p = getIncludes().iterator(); p.hasNext();)
+ {
+ cmds.add("-I" + p.next());
+ }
+ for(Iterator<String> p = getDefines().iterator(); p.hasNext();)
+ {
+ cmds.add("-D" + p.next());
+ }
+ for(Iterator<String> p = getMeta().iterator(); p.hasNext();)
+ {
+ cmds.add("--meta");
+ cmds.add(p.next());
+ }
+ if(getStream())
+ {
+ cmds.add("--stream");
+ }
+ if(getTie())
+ {
+ cmds.add("--tie");
+ }
+ if(getIce())
+ {
+ cmds.add("--ice");
+ }
+ if(getUnderscore())
+ {
+ cmds.add("--underscore");
+ }
+
+ StringTokenizer tokens = new StringTokenizer(getExtraArguments());
+ while(tokens.hasMoreTokens())
+ {
+ cmds.add(tokens.nextToken());
+ }
+
+ return cmds;
+ }
+
+ public List<String> getCommandLine(IResource resource)
+ {
+ List<String> cmds = getCommandLine();
+ for(Iterator<String> p = getBareIncludes(resource).iterator(); p.hasNext();)
+ {
+ cmds.add("-I" + p.next());
+ }
+ for(Iterator<String> p = getDefines(resource).iterator(); p.hasNext();)
+ {
+ cmds.add("-D" + p.next());
+ }
+ for(Iterator<String> p = getMeta(resource).iterator(); p.hasNext();)
+ {
+ cmds.add("--meta");
+ cmds.add(p.next());
+ }
+ if(!getStream() && getStream(resource))
+ {
+ cmds.add("--stream");
+ }
+ if(!getTie() && getTie(resource))
+ {
+ cmds.add("--tie");
+ }
+ if(!getIce() && getIce(resource))
+ {
+ cmds.add("--ice");
+ }
+ if(!getUnderscore() && getUnderscore(resource))
+ {
+ cmds.add("--underscore");
+ }
+
+ StringTokenizer tokens = new StringTokenizer(getExtraArguments(resource));
+ while(tokens.hasMoreTokens())
+ {
+ cmds.add(tokens.nextToken());
+ }
+
+ return cmds;
+ }
+
+ public List<String> getIncludes()
+ {
+ List<String> s = toList(_store.getString(INCLUDES_KEY));
+
+ String iceHome = getIceHome();
+ String os = System.getProperty("os.name");
+ String path = null;
+ if(os.equals("Linux") && iceHome.equals("/usr"))
+ {
+ String version = getIceVersion();
+ if(version != null)
+ {
+ File f = new File("/usr/share/Ice-" + version + "/slice");
+ if(f.exists())
+ {
+ path = f.toString();
+ }
+ }
+ }
+
+ if(path == null)
+ {
+ path = new File(iceHome + File.separator + "slice").toString();
+ }
+
+ s.add(path);
+ return s;
+ }
+
+ // The bare include list.
+ public List<String> getBareIncludes()
+ {
+ return toList(_store.getString(INCLUDES_KEY));
+ }
+
+ public List<String> getBareIncludes(IResource resource)
+ {
+ return toList(_store.getString(resourceKey(resource, INCLUDES_KEY)));
+ }
+
+ public void setIncludes(List<String> includes)
+ {
+ setValue(INCLUDES_KEY, fromList(includes));
+ }
+
+ public void setIncludes(IResource resource, List<String> includes)
+ {
+ setValue(resourceKey(resource, INCLUDES_KEY), fromList(includes));
+ }
+
+ public boolean getAddJars()
+ {
+ return _store.getBoolean(ADD_JARS_KEY);
+ }
+
+ public void setAddJars(boolean b)
+ {
+ _store.setValue(ADD_JARS_KEY, b);
+ }
+
+ public List<String> getJars()
+ {
+ return toList(_store.getString(JARS_KEY));
+ }
+
+ public void setJars(List<String> jars) throws CoreException
+ {
+ if(setValue(JARS_KEY, fromList(jars)))
+ {
+ IceClasspathContainerIntializer.reinitialize(_project, this);
+ }
+ }
+
+ public List<String> getDefines()
+ {
+ return toList(_store.getString(DEFINES_KEY));
+ }
+
+ public List<String> getDefines(IResource resource)
+ {
+ return toList(_store.getString(resourceKey(resource, DEFINES_KEY)));
+ }
+
+ public void setDefines(List<String> defines)
+ {
+ setValue(DEFINES_KEY, fromList(defines));
+ }
+
+ public void setDefines(IResource resource, List<String> defines)
+ {
+ setValue(resourceKey(resource, DEFINES_KEY), fromList(defines));
+ }
+
+ public boolean getStream()
+ {
+ return _store.getBoolean(STREAM_KEY);
+ }
+
+ public boolean getStream(IResource resource)
+ {
+ return _store.getBoolean(resourceKey(resource, STREAM_KEY));
+ }
+
+ public void setStream(boolean stream)
+ {
+ _store.setValue(STREAM_KEY, stream);
+ }
+
+ public void setStream(IResource resource, boolean stream)
+ {
+ _store.setValue(resourceKey(resource, STREAM_KEY), stream);
+ }
+
+ public boolean getTie()
+ {
+ return _store.getBoolean(TIE_KEY);
+ }
+
+ public boolean getTie(IResource resource)
+ {
+ return _store.getBoolean(resourceKey(resource, TIE_KEY));
+ }
+
+ public void setTie(boolean tie)
+ {
+ _store.setValue(TIE_KEY, tie);
+ }
+
+ public void setTie(IResource resource, boolean tie)
+ {
+ _store.setValue(resourceKey(resource, TIE_KEY), tie);
+ }
+
+ public boolean getIce()
+ {
+ return _store.getBoolean(ICE_KEY);
+ }
+
+ public boolean getIce(IResource resource)
+ {
+ return _store.getBoolean(resourceKey(resource, ICE_KEY));
+ }
+
+ public void setIce(boolean ice)
+ {
+ _store.setValue(ICE_KEY, ice);
+ }
+
+ public void setIce(IResource resource, boolean ice)
+ {
+ _store.setValue(resourceKey(resource, ICE_KEY), ice);
+ }
+
+ public boolean getUnderscore()
+ {
+ return _store.getBoolean(UNDERSCORE_KEY);
+ }
+
+ public boolean getUnderscore(IResource resource)
+ {
+ return _store.getBoolean(resourceKey(resource, UNDERSCORE_KEY));
+ }
+
+ public void setUnderscore(boolean underscore)
+ {
+ _store.setValue(UNDERSCORE_KEY, underscore);
+ }
+
+ public void setUnderscore(IResource resource, boolean underscore)
+ {
+ _store.setValue(resourceKey(resource, UNDERSCORE_KEY), underscore);
+ }
+
+ public boolean getConsole()
+ {
+ return _store.getBoolean(CONSOLE_KEY);
+ }
+
+ public void setConsole(boolean console)
+ {
+ _store.setValue(CONSOLE_KEY, console);
+ }
+
+ public List<String> getMeta()
+ {
+ return toList(_store.getString(META_KEY));
+ }
+
+ public List<String> getMeta(IResource resource)
+ {
+ return toList(_store.getString(resourceKey(resource, META_KEY)));
+ }
+
+ public void setMeta(List<String> meta)
+ {
+ setValue(META_KEY, fromList(meta));
+ }
+
+ public void setMeta(IResource resource, List<String> meta)
+ {
+ setValue(resourceKey(resource, META_KEY), fromList(meta));
+ }
+
+ public String getExtraArguments()
+ {
+ return _store.getString(EXTRA_ARGUMENTS_KEY);
+ }
+
+ public String getExtraArguments(IResource resource)
+ {
+ return _store.getString(resourceKey(resource, EXTRA_ARGUMENTS_KEY));
+ }
+
+ public void setExtraArguments(String arguments)
+ {
+ setValue(EXTRA_ARGUMENTS_KEY, arguments);
+ }
+
+ public void setExtraArguments(IResource resource, String arguments)
+ {
+ setValue(resourceKey(resource, EXTRA_ARGUMENTS_KEY), arguments);
+ }
+
+ public static void setupSharedLibraryPath(Map<String, String> env)
+ {
+ String iceHome = getIceHome();
+
+ String libPath;
+ boolean srcdist = false;
+ if(new File(iceHome + File.separator + "cpp" + File.separator + "bin").exists())
+ {
+ // iceHome points at a source distribution.
+ libPath = new File(iceHome + File.separator + "cpp" + File.separator + "lib").toString();
+ srcdist = true;
+ }
+ else
+ {
+ libPath = new File(iceHome + File.separator + "lib").toString();
+ }
+
+ String ldLibPathEnv = null;
+ String ldLib64PathEnv = null;
+ String lib64Path = null;
+
+ String os = System.getProperty("os.name");
+ if(os.equals("Mac OS X"))
+ {
+ ldLibPathEnv = "DYLD_LIBRARY_PATH";
+ }
+ else if(os.equals("AIX"))
+ {
+ ldLibPathEnv = "LIBPATH";
+ }
+ else if(os.equals("HP-UX"))
+ {
+ ldLibPathEnv = "SHLIB_PATH";
+ ldLib64PathEnv = "LD_LIBRARY_PATH";
+ if(srcdist)
+ {
+ lib64Path = libPath;
+ }
+ else
+ {
+ lib64Path = new File(iceHome + File.separator + "lib" + File.separator + "pa20_64").toString();
+ }
+ }
+ else if(os.startsWith("Windows"))
+ {
+ //
+ // No need to change the PATH environment variable on Windows, the
+ // DLLs should be found
+ // in the translator local directory.
+ //
+ // ldLibPathEnv = "PATH";
+ }
+ else if(os.equals("SunOS"))
+ {
+ ldLibPathEnv = "LD_LIBRARY_PATH";
+ ldLib64PathEnv = "LD_LIBRARY_PATH_64";
+ String arch = System.getProperty("os.arch");
+ if(srcdist)
+ {
+ lib64Path = libPath;
+ }
+ else if(arch.equals("x86"))
+ {
+ lib64Path = new File(iceHome + File.separator + "lib" + File.separator + "amd64").toString();
+ }
+ else
+ // Sparc
+ {
+ lib64Path = new File(iceHome + File.separator + "lib" + File.separator + "sparcv9").toString();
+ }
+ }
+ else
+ {
+ ldLibPathEnv = "LD_LIBRARY_PATH";
+ ldLib64PathEnv = "LD_LIBRARY_PATH";
+ if(srcdist)
+ {
+ lib64Path = libPath;
+ }
+ else
+ {
+ lib64Path = new File(iceHome + File.separator + "lib64").toString();
+ }
+ }
+
+ if(ldLibPathEnv != null)
+ {
+ if(ldLibPathEnv.equals(ldLib64PathEnv))
+ {
+ libPath = libPath + File.pathSeparator + lib64Path;
+ }
+
+ String envLibPath = env.get(ldLibPathEnv);
+ if(envLibPath != null)
+ {
+ libPath = libPath + File.pathSeparator + envLibPath;
+ }
+
+ env.put(ldLibPathEnv, libPath);
+ }
+
+ if(ldLib64PathEnv != null && !ldLib64PathEnv.equals(ldLibPathEnv))
+ {
+ String envLib64Path = env.get(ldLib64PathEnv);
+ if(envLib64Path != null)
+ {
+ lib64Path = lib64Path + File.pathSeparator + envLib64Path;
+ }
+ env.put(ldLib64PathEnv, lib64Path);
+ }
+ }
+
+ public String getTranslator()
+ {
+ return getTranslatorForHome(getIceHome());
+ }
+
+ static public boolean verifyIceHome(String dir)
+ {
+ return getTranslatorForHome(dir) != null;
+ }
+
+ public String getJarDir()
+ {
+ String iceHome = getIceHome();
+ String os = System.getProperty("os.name");
+ if(os.equals("Linux") && iceHome.equals("/usr"))
+ {
+ File f = new File(iceHome + File.separator + "share" + File.separator + "java");
+ if(f.exists())
+ {
+ return f.toString();
+ }
+ }
+
+ File f = new File(iceHome + File.separator + "lib");
+ if(!f.exists())
+ {
+ File f2 = new File(iceHome + File.separator + "java" + File.separator + "lib");
+ if(f2.exists())
+ {
+ return f2.toString();
+ }
+ }
+ // Add the platform default even if it cannot be found.
+ return f.toString();
+ }
+
+ private static String getIceHome()
+ {
+ return Activator.getDefault().getPreferenceStore().getString(PluginPreferencePage.SDK_PATH);
+ }
+
+ // For some reason ScopedPreferenceStore.setValue(String, String)
+ // doesn't check to see whether the stored value is the same as
+ // the new value.
+ private boolean setValue(String key, String value)
+ {
+ return setValue(_store, key, value);
+ }
+
+ private boolean setValue(ScopedPreferenceStore store, String key, String value)
+ {
+ if(!store.getString(key).equals(value))
+ {
+ store.setValue(key, value);
+ return true;
+ }
+ return false;
+ }
+
+ static private String escape(String s)
+ {
+ int curr = 0;
+ int end = s.length();
+ StringBuffer sb = new StringBuffer();
+ for(curr = 0; curr < end; ++curr)
+ {
+ char ch = s.charAt(curr);
+ if(ch == '\\' || ch == ';')
+ {
+ sb.append('\\');
+ }
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
+
+ // Obtain the Ice version by executing the translator with the -v option.
+ private String getIceVersion()
+ {
+ String version = null;
+ String exec = getTranslatorForHome(getIceHome());
+ if(exec != null)
+ {
+ try
+ {
+ ProcessBuilder b = new ProcessBuilder(exec, "-v");
+ b.redirectErrorStream(true);
+ Map<String, String> env = b.environment();
+ setupSharedLibraryPath(env);
+ Process p = b.start();
+ int status = p.waitFor();
+ if(status == 0)
+ {
+ BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = r.readLine();
+ version = line.trim();
+ }
+ }
+ catch(Throwable ex)
+ {
+ // Ignore.
+ }
+ }
+ return version;
+ }
+
+ private static String getTranslatorForHome(String dir)
+ {
+ String suffix = "";
+ String os = System.getProperty("os.name");
+ if(os.startsWith("Windows"))
+ {
+ suffix = ".exe";
+ }
+ File f = new File(dir + File.separator + "bin" + File.separator + "slice2java" + suffix);
+ if(f.exists())
+ {
+ return f.toString();
+ }
+ f = new File(dir + File.separator + "cpp" + File.separator + "bin" + File.separator + "slice2java" + suffix);
+ if(f.exists())
+ {
+ return f.toString();
+ }
+ return null;
+ }
+
+ private void addLibrary(IJavaProject project)
+ throws CoreException
+ {
+ IClasspathEntry cpEntry = null;
+ if(!isAndroidProject())
+ {
+ cpEntry = IceClasspathContainerIntializer.getContainerEntry();
+ }
+ else
+ {
+ cpEntry = JavaCore.newVariableEntry(new Path("ICE_HOME/lib/Ice.jar"), null, null);
+ }
+
+ IClasspathEntry[] entries = project.getRawClasspath();
+ boolean found = false;
+ for(int i = 0; i < entries.length; ++i)
+ {
+ if(entries[i].equals(cpEntry))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found)
+ {
+ IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
+ System.arraycopy(entries, 0, newEntries, 0, entries.length);
+ newEntries[entries.length] = cpEntry;
+
+ try
+ {
+ project.setRawClasspath(newEntries, null);
+ }
+ catch(JavaModelException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString(), null));
+ }
+ }
+ }
+
+ public void removeLibrary(IJavaProject project)
+ throws CoreException
+ {
+ IClasspathEntry cpEntry = null;
+ if(!isAndroidProject())
+ {
+ cpEntry = IceClasspathContainerIntializer.getContainerEntry();
+ }
+ else
+ {
+ cpEntry = JavaCore.newVariableEntry(new Path("ICE_HOME/lib/Ice.jar"), null, null);
+ }
+ IClasspathEntry[] entries = project.getRawClasspath();
+
+ for(int i = 0; i < entries.length; ++i)
+ {
+ if(entries[i].equals(cpEntry))
+ {
+ IClasspathEntry[] newEntries = new IClasspathEntry[entries.length - 1];
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ System.arraycopy(entries, i + 1, newEntries, i, entries.length - i - 1);
+
+ try
+ {
+ project.setRawClasspath(newEntries, null);
+ }
+ catch(JavaModelException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.toString(), null));
+ }
+ break;
+ }
+ }
+ }
+
+ //
+ // Check if the given resource has any Slice compiler options set.
+ //
+ public static boolean resourceHasOptions(IResource resource)
+ {
+ Configuration configuration = new Configuration(resource.getProject());
+ if(configuration.getDefines(resource) != null && configuration.getDefines(resource).size() > 0)
+ {
+ return true;
+ }
+ if(configuration.getMeta(resource) != null && configuration.getMeta(resource).size() > 0)
+ {
+ return true;
+ }
+ if(!configuration.getStream() && configuration.getStream(resource))
+ {
+ return true;
+ }
+ if(!configuration.getTie() && configuration.getTie(resource))
+ {
+ return true;
+ }
+ if(!configuration.getIce() && configuration.getIce(resource))
+ {
+ return true;
+ }
+ if(!configuration.getUnderscore() && configuration.getUnderscore(resource))
+ {
+ return true;
+ }
+ if(configuration.getExtraArguments(resource) != null && !configuration.getExtraArguments(resource).isEmpty())
+ {
+ return true;
+ }
+ return false;
+ }
+
+ public static String resourceKey(IResource resource, String key)
+ {
+ return resource.getFullPath().toString() + "." + key;
+ }
+
+ private static final String JARS_KEY = "jars";
+ private static final String INCLUDES_KEY = "includes";
+ private static final String SLICE_SOURCE_DIRS_KEY = "sliceSourceDirs";
+ private static final String CONSOLE_KEY = "console";
+ private static final String META_KEY = "meta";
+ private static final String STREAM_KEY = "stream";
+ private static final String ICE_INCLUDE_KEY = "iceIncludes";
+ private static final String ICE_KEY = "ice";
+ private static final String TIE_KEY = "tie";
+ private static final String DEFINES_KEY = "defines";
+ private static final String GENERATED_KEY = "generated";
+ private static final String ADD_JARS_KEY = "addJars";
+ private static final String UNDERSCORE_KEY = "underscore";
+
+ private static final String EXTRA_ARGUMENTS_KEY = "extraArguments";
+
+ // Preferences store for items which should go in SCM. This includes things
+ // like build flags.
+ private ScopedPreferenceStore _store;
+
+ // Preferences store per project items which should not go in SCM, such as
+ // the location of the Ice installation.
+ private ScopedPreferenceStore _instanceStore;
+
+ private IProject _project;
+
+ private boolean _androidProject;
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Dependencies.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Dependencies.java
new file mode 100644
index 00000000000..4204a676d69
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/Dependencies.java
@@ -0,0 +1,528 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.internal;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+import com.zeroc.slice2javaplugin.Activator;
+
+public class Dependencies
+{
+ public Dependencies(IProject project, Set<IFile> LprojectResources, MessageConsoleStream err)
+ {
+ _project = project;
+ _projectResources = LprojectResources;
+ _err = err;
+
+ // Build a map of location to project resource.
+
+ for(IFile f : _projectResources)
+ {
+ _locationToResource.put(f.getLocation(), f);
+ }
+ }
+
+ /**
+ *
+ * @param allDependencies The string of all dependencies.
+ * @throws CoreException
+ */
+ public void updateDependencies(String allDependencies)
+ throws CoreException
+ {
+ Slice2JavaDependenciesParser parser = new Slice2JavaDependenciesParser();
+ try
+ {
+ InputStream in = new ByteArrayInputStream(allDependencies.getBytes());
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new BufferedInputStream(in));
+ parser.visit(doc);
+ }
+ catch(SAXException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading dependencies", e));
+ }
+ catch(ParserConfigurationException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading dependencies", e));
+ }
+ catch(IOException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading dependencies", e));
+ }
+
+ for(Map.Entry<String, List<String>> entry : parser.dependencies.entrySet())
+ {
+ Path sourcePath = new Path(entry.getKey());
+ assert sourcePath.isAbsolute();
+
+ IFile sourceFile = _locationToResource.get(sourcePath);
+ if(sourceFile == null)
+ {
+ if(_err != null)
+ {
+ _err.println("Dependencies: ignoring non-project resource " + sourcePath.toString());
+ }
+ // This should not occur.
+ continue;
+ }
+
+ for(String s : entry.getValue())
+ {
+ IFile f = getProjectResource(new Path(s));
+ // Ignore any resources not in the project.
+ if(f != null)
+ {
+ Set<IFile> dependents = reverseSliceSliceDependencies.get(f);
+ if(dependents == null)
+ {
+ dependents = new HashSet<IFile>();
+ reverseSliceSliceDependencies.put(f, dependents);
+ }
+ dependents.add(sourceFile);
+ }
+ }
+
+ Set<IFile> dependents = new HashSet<IFile>();
+ sliceSliceDependencies.put(sourceFile, dependents);
+ for(String s : entry.getValue())
+ {
+ IFile f = getProjectResource(new Path(s));
+ // Ignore any resources not in the project.
+ if(f != null)
+ {
+ dependents.add(f);
+ }
+ }
+ }
+ }
+
+ private IFile getProjectResource(Path path)
+ {
+ IFile f = null;
+ if(path.isAbsolute())
+ {
+ f = _locationToResource.get(path);
+ }
+ else
+ {
+ f = _project.getFile(path.toString());
+ if(!f.exists())
+ {
+ f = null;
+ }
+ }
+ if(_projectResources.contains(f))
+ {
+ return f;
+ }
+ return null;
+ }
+
+ public void read()
+ throws CoreException
+ {
+ IFileStore dependencies = getDependenciesStore();
+ if(!dependencies.fetchInfo(EFS.NONE, null).exists())
+ {
+ return;
+ }
+ InputStream in = dependencies.openInputStream(EFS.NONE, null);
+
+ try
+ {
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new BufferedInputStream(in));
+ DependenciesParser parser = new DependenciesParser(_project);
+ parser.visit(doc);
+ sliceSliceDependencies = parser.sliceSliceDependencies;
+ reverseSliceSliceDependencies = parser.reverseSliceSliceDependencies;
+ sliceJavaDependencies = parser.sliceJavaDependencies;
+ errorSliceFiles = parser.errorSliceFiles;
+ }
+ catch(SAXException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading dependencies", e));
+ }
+ catch(ParserConfigurationException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading dependencies", e));
+ }
+ catch(IOException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error reading dependencies", e));
+ }
+ }
+
+ public void write()
+ throws CoreException
+ {
+ // Create a DOM of the map.
+ Document doc = null;
+ try
+ {
+ doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ }
+ catch(ParserConfigurationException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error writing dependencies", e));
+ }
+
+ Element root = doc.createElement("dependencies");
+ doc.appendChild(root);
+
+ writeDependencies(sliceSliceDependencies, doc, "sliceSliceDependencies", root);
+ writeDependencies(reverseSliceSliceDependencies, doc, "reverseSliceSliceDependencies", root);
+ writeDependencies(sliceJavaDependencies, doc, "sliceJavaDependencies", root);
+ writeErrorSliceFiles(errorSliceFiles, doc, "errorSliceFiles", root);
+
+ // Write the DOM to the dependencies.xml file.
+ TransformerFactory transfac = TransformerFactory.newInstance();
+ Transformer trans = null;
+ try
+ {
+ trans = transfac.newTransformer();
+ }
+ catch(TransformerConfigurationException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error writing dependencies", e));
+ }
+ // tf.setAttribute("indent-number", 4);
+
+ // trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+ trans.setOutputProperty(OutputKeys.ENCODING, "UTF8");
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+ trans.setOutputProperty(OutputKeys.METHOD, "XML");
+
+ IFileStore dependencies = getDependenciesStore();
+ OutputStream out = dependencies.openOutputStream(EFS.NONE, null);
+ StreamResult result = new StreamResult(new BufferedOutputStream(out));
+ DOMSource source = new DOMSource(doc);
+ try
+ {
+ trans.transform(source, result);
+ }
+ catch(TransformerException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error writing dependencies", e));
+ }
+ try
+ {
+ out.close();
+ }
+ catch(IOException e)
+ {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "internal error writing dependencies", e));
+ }
+ }
+
+ private void writeErrorSliceFiles(Set<IFile> s, Document doc, String name, Element root)
+ {
+ Element jsd = doc.createElement(name);
+ root.appendChild(jsd);
+
+ for(IFile f : s)
+ {
+ Element elem = doc.createElement("file");
+ jsd.appendChild(elem);
+ Text text = doc.createTextNode(f.getProjectRelativePath().toString());
+ elem.appendChild(text);
+ }
+ }
+
+ private void writeDependencies(Map<IFile, Set<IFile>> map, Document doc, String name, Element root)
+ {
+ Element jsd = doc.createElement(name);
+ root.appendChild(jsd);
+
+ Iterator<Map.Entry<IFile, Set<IFile>>> p = map.entrySet().iterator();
+ while(p.hasNext())
+ {
+ Map.Entry<IFile, Set<IFile>> e = p.next();
+ Element entry = doc.createElement("entry");
+ jsd.appendChild(entry);
+
+ Element key = doc.createElement("key");
+ entry.appendChild(key);
+ Text text = doc.createTextNode(e.getKey().getProjectRelativePath().toString());
+ key.appendChild(text);
+
+ Element value = doc.createElement("value");
+ entry.appendChild(value);
+
+ Iterator<IFile> q = e.getValue().iterator();
+ while(q.hasNext())
+ {
+ IFile f = q.next();
+ Element elem = doc.createElement("file");
+ value.appendChild(elem);
+ text = doc.createTextNode(f.getProjectRelativePath().toString());
+ elem.appendChild(text);
+ }
+ }
+ }
+
+ private IFileStore getDependenciesStore()
+ throws CoreException
+ {
+ IPath name = new Path(_project.getName());
+ IFileStore store = EFS.getLocalFileSystem().getStore(Activator.getDefault().getStateLocation()).getFileStore(
+ name);
+ if(!store.fetchInfo(EFS.NONE, null).exists())
+ {
+ store.mkdir(EFS.NONE, null);
+ }
+ return store.getFileStore(new Path("dependencies.xml"));
+ }
+
+ private static class Slice2JavaDependenciesParser
+ {
+ Map<String, List<String>> dependencies = new java.util.HashMap<String, List<String>>();
+
+ private Node findNode(Node n, String qName)
+ throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(qName))
+ {
+ return child;
+ }
+ }
+ throw new SAXException("no such node: " + qName);
+ }
+
+ private void visitDependencies(Node n) throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ if(children.item(i).getNodeType() == Node.ELEMENT_NODE && children.item(i).getNodeName().equals("source"))
+ {
+ String source = ((Element)children.item(i)).getAttribute("name");
+ if(source.length() == 0)
+ {
+ throw new SAXException("empty name attribute");
+ }
+ List<String> dependsOn = visitDependsOn(children.item(i));
+ dependencies.put(source, dependsOn);
+ }
+ }
+ }
+
+ private List<String> visitDependsOn(Node source) throws SAXException
+ {
+ List<String> depends = new ArrayList<String>();
+ NodeList dependencies = source.getChildNodes();
+ for(int j = 0; j < dependencies.getLength(); ++j)
+ {
+ if(dependencies.item(j).getNodeType() == Node.ELEMENT_NODE && dependencies.item(j).getNodeName().equals("dependsOn"))
+ {
+ Element dependsOn = (Element)dependencies.item(j);
+ String name = dependsOn.getAttribute("name");
+ if(name.length() == 0)
+ {
+ throw new SAXException("empty name attribute");
+ }
+ depends.add(name);
+ }
+ }
+ return depends;
+ }
+
+ public void visit(Node doc) throws SAXException
+ {
+ Node n = findNode(doc, "dependencies");
+ visitDependencies(n);
+ }
+ }
+
+ private static class DependenciesParser
+ {
+ private IProject _project;
+
+ Map<IFile, Set<IFile>> sliceSliceDependencies = new java.util.HashMap<IFile, Set<IFile>>();
+ Map<IFile, Set<IFile>> reverseSliceSliceDependencies = new java.util.HashMap<IFile, Set<IFile>>();
+ Map<IFile, Set<IFile>> sliceJavaDependencies = new java.util.HashMap<IFile, Set<IFile>>();
+ Set<IFile> errorSliceFiles = new java.util.HashSet<IFile>();
+
+ private Node findNode(Node n, String qName)
+ throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(qName))
+ {
+ return child;
+ }
+ }
+ throw new SAXException("no such node: " + qName);
+ }
+
+ private String getText(Node n)
+ throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ if(children.getLength() == 1 && children.item(0).getNodeType() == Node.TEXT_NODE)
+ {
+ return children.item(0).getNodeValue();
+ }
+ throw new SAXException("no text element");
+ }
+
+ private List<String> processFiles(Node n)
+ throws SAXException
+ {
+ List<String> files = new ArrayList<String>();
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("file"))
+ {
+ files.add(getText(child));
+ }
+ }
+ return files;
+ }
+
+ public void visitDependencies(Map<IFile, Set<IFile>> map, Node n)
+ throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("entry"))
+ {
+ IFile key = _project.getFile(new Path(getText(findNode(child, "key"))));
+
+ Node value = findNode(child, "value");
+ List<String> files = processFiles(value);
+ Set<IFile> f = new HashSet<IFile>();
+ for(String s : files)
+ {
+ f.add(_project.getFile(new Path(s)));
+ }
+
+ map.put(key, f);
+ }
+ }
+ }
+
+ public void visitErrorList(Set<IFile> s, Node n) throws SAXException
+ {
+ NodeList children = n.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i)
+ {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("file"))
+ {
+ s.add(_project.getFile(new Path(getText(child))));
+ }
+ }
+ }
+
+ public void visit(Node doc)
+ throws SAXException
+ {
+ Node dependencies = findNode(doc, "dependencies");
+ visitDependencies(sliceSliceDependencies, findNode(dependencies, "sliceSliceDependencies"));
+ visitDependencies(reverseSliceSliceDependencies, findNode(dependencies, "reverseSliceSliceDependencies"));
+ visitDependencies(sliceJavaDependencies, findNode(dependencies, "sliceJavaDependencies"));
+ try
+ {
+ visitErrorList(errorSliceFiles, findNode(dependencies, "errorSliceFiles"));
+ }
+ catch(SAXException e)
+ {
+ // Optional.
+ }
+ }
+
+ DependenciesParser(IProject project)
+ {
+ _project = project;
+ }
+ }
+
+ // A map of slice to dependencies.
+ //
+ // sliceSliceDependencies is the set of slice files that depend on the IFile
+ // (the output of slice2java --depend).
+ //
+ // _reverseSliceSliceDependencies is the reverse.
+ public Map<IFile, Set<IFile>> sliceSliceDependencies = new java.util.HashMap<IFile, Set<IFile>>();
+ public Map<IFile, Set<IFile>> reverseSliceSliceDependencies = new java.util.HashMap<IFile, Set<IFile>>();
+
+ // A map of slice file to java source files.
+ public Map<IFile, Set<IFile>> sliceJavaDependencies = new java.util.HashMap<IFile, Set<IFile>>();
+
+ // A set of slice files that have not, or cannot be built.
+ public Set<IFile> errorSliceFiles = new java.util.HashSet<IFile>();
+
+ private IProject _project;
+ private MessageConsoleStream _err;
+ private Set<IFile> _projectResources;
+ private Map<IPath, IFile> _locationToResource = new HashMap<IPath, IFile>();
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainer.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainer.java
new file mode 100644
index 00000000000..915234c1304
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainer.java
@@ -0,0 +1,47 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.internal;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+
+public class IceClasspathContainer implements IClasspathContainer
+{
+ private IClasspathEntry[] _cpEntry;
+ private IPath _path;
+
+ IceClasspathContainer(IClasspathEntry[] entries, IPath path)
+ {
+ _cpEntry = entries;
+ _path = path;
+ }
+
+ public IClasspathEntry[] getClasspathEntries()
+ {
+ return _cpEntry;
+ }
+
+ public String getDescription()
+ {
+ return "Ice Library";
+ }
+
+ public int getKind()
+ {
+ return IClasspathContainer.K_APPLICATION;
+ }
+
+ public IPath getPath()
+ {
+ return _path;
+ }
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainerIntializer.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainerIntializer.java
new file mode 100644
index 00000000000..7d16cb2983c
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathContainerIntializer.java
@@ -0,0 +1,95 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+public class IceClasspathContainerIntializer extends ClasspathContainerInitializer
+{
+ private final static String CONTAINER_ID = "com.zeroc.Slice2JavaPlugin.ICE_FRAMEWORK";
+
+ @Override
+ public void initialize(IPath containerPath, IJavaProject project)
+ throws CoreException
+ {
+ if(containerPath.toString().equals(CONTAINER_ID))
+ {
+ Configuration c = new Configuration(project.getProject());
+ configure(c, project, containerPath);
+ }
+ }
+
+ public static IClasspathEntry getContainerEntry()
+ {
+ return JavaCore.newContainerEntry(new Path(CONTAINER_ID));
+ }
+
+ public static void reinitialize(IProject project, Configuration c)
+ throws CoreException
+ {
+ IJavaProject javaProject = JavaCore.create(project);
+ IPath containerPath = new Path(CONTAINER_ID);
+
+ configure(c, javaProject, containerPath);
+ }
+
+ private static void configure(Configuration c, IJavaProject javaProject, IPath containerPath)
+ throws JavaModelException
+ {
+ if(c.getAddJars())
+ {
+ Path dir = new Path(c.getJarDir());
+ List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+ for(String jar : c.getJars())
+ {
+ IPath path = dir.append(new Path(jar));
+ IClasspathEntry classpathEntry = JavaCore.newLibraryEntry(path, null, null, new IAccessRule[0], new IClasspathAttribute[0], false);
+ entries.add(classpathEntry);
+ }
+
+ IClasspathContainer container = new IceClasspathContainer(entries.toArray(new IClasspathEntry[0]), containerPath);
+ JavaCore.setClasspathContainer(containerPath, new IJavaProject[] { javaProject },
+ new IClasspathContainer[] { container }, new NullProgressMonitor());
+ }
+ }
+
+ public static void updateProjects(String value, List<IJavaProject> projects)
+ {
+ for(IJavaProject p : projects)
+ {
+ IPath containerPath = new Path(CONTAINER_ID);
+ Configuration c = new Configuration(p.getProject());
+ try
+ {
+ configure(c, p, containerPath);
+ }
+ catch(JavaModelException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathVariableInitializer.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathVariableInitializer.java
new file mode 100644
index 00000000000..06af5b796a9
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/internal/IceClasspathVariableInitializer.java
@@ -0,0 +1,47 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.internal;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.ClasspathVariableInitializer;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+import com.zeroc.slice2javaplugin.Activator;
+import com.zeroc.slice2javaplugin.preferences.PluginPreferencePage;
+
+public class IceClasspathVariableInitializer extends ClasspathVariableInitializer
+{
+ private final static String VARIABLE_NAME = "ICE_HOME";
+
+ @Override
+ public void initialize(String variable)
+ {
+ if(variable.equals(VARIABLE_NAME))
+ {
+ update(Activator.getDefault().getPreferenceStore().getString(PluginPreferencePage.SDK_PATH));
+ }
+ }
+
+ public static void update(String value)
+ {
+ IPath path = new Path(value);
+ try
+ {
+ JavaCore.setClasspathVariable(VARIABLE_NAME, path, null);
+ }
+ catch(JavaModelException e)
+ {
+ e.printStackTrace();
+ }
+ }
+} \ No newline at end of file
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PluginPreferencePage.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PluginPreferencePage.java
new file mode 100644
index 00000000000..e478f3d037d
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PluginPreferencePage.java
@@ -0,0 +1,102 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.preferences;
+
+import org.eclipse.jface.preference.*;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.IWorkbench;
+
+import com.zeroc.slice2javaplugin.Activator;
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+/**
+ * This class represents a preference page that is contributed to the
+ * Preferences dialog. By subclassing <samp>FieldEditorPreferencePage</samp>, we
+ * can use the field support built into JFace that allows us to create a page
+ * that is small and knows how to save, restore and apply itself.
+ * <p>
+ * This page is used to modify preferences only. They are stored in the
+ * preference store that belongs to the main plug-in class. That way,
+ * preferences can be accessed directly via the preference store.
+ */
+
+public class PluginPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage
+{
+ public static final String SDK_PATH = "pathPreference";
+
+ public PluginPreferencePage()
+ {
+ super(GRID);
+ setPreferenceStore(Activator.getDefault().getPreferenceStore());
+ setDescription("Slice2Java Preferences");
+ }
+
+ /**
+ * Creates the field editors. Field editors are abstractions of the common
+ * GUI blocks needed to manipulate various types of preferences. Each field
+ * editor knows how to save and restore itself.
+ */
+ public void createFieldEditors()
+ {
+ addField(new SdkDirectoryFieldEditor(SDK_PATH, "&SDK Location:", getFieldEditorParent()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ public void init(IWorkbench workbench)
+ {
+ }
+
+ private static class SdkDirectoryFieldEditor extends DirectoryFieldEditor
+ {
+
+ public SdkDirectoryFieldEditor(String name, String labelText, Composite parent)
+ {
+ super(name, labelText, parent);
+ setEmptyStringAllowed(false);
+ }
+
+ /**
+ * Method declared on StringFieldEditor and overridden in
+ * DirectoryFieldEditor. Checks whether the text input field contains a
+ * valid directory.
+ *
+ * @return True if the apply/ok button should be enabled in the pref
+ * panel
+ */
+ @Override
+ protected boolean doCheckState()
+ {
+ String dir = getTextControl().getText();
+ dir = dir.trim();
+ if(!Configuration.verifyIceHome(dir))
+ {
+ setErrorMessage("Invalid SDK Location");
+ return false;
+ }
+ clearMessage();
+ return true;
+ }
+
+ @Override
+ public Text getTextControl(Composite parent)
+ {
+ setValidateStrategy(VALIDATE_ON_KEY_STROKE);
+ return super.getTextControl(parent);
+ }
+ }
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PreferenceInitializer.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PreferenceInitializer.java
new file mode 100644
index 00000000000..2e953b343a5
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/preferences/PreferenceInitializer.java
@@ -0,0 +1,65 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.preferences;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import com.zeroc.slice2javaplugin.Activator;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer
+{
+ private String getDefaultHome()
+ {
+ String os = System.getProperty("os.name");
+ if(os.startsWith("Windows"))
+ {
+ File f = new File("C:\\Program Files\\ZeroC\\Ice-3.4.2");
+ if(!f.exists())
+ {
+ File f2 = new File("C:\\Program Files (x86)\\ZeroC\\Ice-3.4.2");
+ if(f2.exists())
+ {
+ return f2.toString();
+ }
+ }
+ return f.toString();
+ }
+ if(os.equals("Linux"))
+ {
+ File f = new File("/usr/bin/slice2java");
+ if(f.exists())
+ {
+ return "/usr";
+ }
+ }
+ return "/opt/Ice-3.4.2";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#
+ * initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences()
+ {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+
+ store.setDefault(PluginPreferencePage.SDK_PATH, getDefaultHome() );
+ }
+
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/ProjectProperties.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/ProjectProperties.java
new file mode 100644
index 00000000000..28611e45fcd
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/ProjectProperties.java
@@ -0,0 +1,387 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.properties;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+
+import com.zeroc.slice2javaplugin.Activator;
+import com.zeroc.slice2javaplugin.builder.Slice2JavaBuilder;
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public class ProjectProperties extends PropertyPage
+{
+ public ProjectProperties()
+ {
+ super(true);
+ setTitle("Slice2Java Settings");
+ noDefaultAndApplyButton();
+ }
+
+ public void performApply()
+ {
+ super.performApply();
+ }
+
+ public boolean performOk()
+ {
+ final IProject project = getProject();
+
+ try
+ {
+ _config.setGeneratedDir(_generatedDir.getText());
+ _config.setSliceSourceDirs(Arrays.asList(_sourceDirectories.getItems()));
+ _config.setIncludes(Arrays.asList(_includes.getItems()));
+ _config.setDefines(Configuration.toList(_defines.getText()));
+ _config.setMeta(Configuration.toList(_meta.getText()));
+ _config.setStream(_stream.getSelection());
+ _config.setTie(_tie.getSelection());
+ _config.setIce(_ice.getSelection());
+ _config.setUnderscore(_underscore.getSelection());
+ _config.setConsole(_console.getSelection());
+ _config.setExtraArguments(_extraArguments.getText());
+ if(_config.getAddJars())
+ {
+ java.util.List<String> jars = new ArrayList<String>();
+ jars.add("Ice.jar");
+ if(_freezeJar.getSelection())
+ {
+ jars.add("Freeze.jar");
+ }
+ _config.setJars(jars);
+ }
+
+ if(_config.write())
+ {
+ // The configuration properties were changed. We need to rebuild
+ // the slice files.
+ Job job = new Job("Rebuild")
+ {
+ protected IStatus run(IProgressMonitor monitor)
+ {
+ try
+ {
+ project.build(IncrementalProjectBuilder.FULL_BUILD, Slice2JavaBuilder.BUILDER_ID, null,
+ monitor);
+ }
+ catch(CoreException e)
+ {
+ return new Status(Status.ERROR, Activator.PLUGIN_ID, 0, "rebuild failed", e);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ job.setPriority(Job.BUILD);
+ job.schedule(); // start as soon as possible
+ }
+ }
+ catch(CoreException e)
+ {
+ return false;
+ }
+ catch(IOException e)
+ {
+ ErrorDialog.openError(getShell(), "Error", "Error saving preferences",
+ new Status(Status.ERROR, Activator.PLUGIN_ID, 0, null, e));
+ return false;
+ }
+ return true;
+ }
+
+ protected void createPostOptions(Composite composite)
+ {
+ _jarsGroup = new Group(composite, SWT.NONE);
+ _jarsGroup.setText("Add references to the following JAR files:");
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+
+ _jarsGroup.setLayout(gridLayout);
+ _jarsGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ _freezeJar = new Button(_jarsGroup, SWT.CHECK);
+ _freezeJar.setText("Freeze.jar");
+ }
+ /**
+ * @see PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent)
+ {
+ // Composite composite = new Composite(parent, SWT.NONE);
+
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ {
+ TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
+ tabItem.setText("Source");
+ Control source = createSource(tabFolder);
+ tabItem.setControl(source);
+ }
+ {
+ TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
+ tabItem.setText("Options");
+ Control source = createOptions(tabFolder);
+ tabItem.setControl(source);
+ }
+ tabFolder.pack();
+
+ loadPrefs();
+
+ return tabFolder;
+ }
+
+ private void loadPrefs()
+ {
+ IProject project = getProject();
+ _config = new Configuration(project);
+
+ _generatedDir.setText(_config.getGeneratedDir());
+ for(Iterator<String> iter = _config.getSliceSourceDirs().iterator(); iter.hasNext();)
+ {
+ _sourceDirectories.add(iter.next());
+ }
+ for(Iterator<String> iter = _config.getBareIncludes().iterator(); iter.hasNext();)
+ {
+ _includes.add(iter.next());
+ }
+ for(Iterator<String> iter = _config.getJars().iterator(); iter.hasNext();)
+ {
+ String jarFile = iter.next();
+ if(jarFile.equals("Freeze.jar"))
+ {
+ _freezeJar.setSelection(true);
+ }
+ }
+ _defines.setText(Configuration.fromList(_config.getDefines()));
+ _meta.setText(Configuration.fromList(_config.getMeta()));
+ _stream.setSelection(_config.getStream());
+ _tie.setSelection(_config.getTie());
+ _ice.setSelection(_config.getIce());
+ _underscore.setSelection(_config.getUnderscore());
+ _console.setSelection(_config.getConsole());
+ _extraArguments.setText(_config.getExtraArguments());
+
+ //
+ // Android projects don't support extra Jar.
+ //
+ _jarsGroup.setEnabled(!_config.isAndroidProject());
+ _freezeJar.setEnabled(!_config.isAndroidProject());
+
+ checkValid();
+ }
+
+ private void checkValid()
+ {
+ IProject project = getProject();
+ IFolder folder = project.getFolder(_generatedDir.getText());
+ if(!folder.exists())
+ {
+ setErrorMessage("Generated folder does not exist");
+ setValid(false);
+ return;
+ }
+ setValid(true);
+ setErrorMessage(null);
+ }
+
+ private Control createSource(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ composite.setLayout(gridLayout);
+
+ Group sourceGroup = new Group(composite, SWT.NONE);
+ sourceGroup.setText("Location of Slice Source Files");
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ sourceGroup.setLayout(gridLayout);
+ sourceGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Composite c1 = new Composite(sourceGroup, SWT.NONE);
+
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ c1.setLayout(gridLayout);
+ c1.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ _sourceDirectories = new List(c1, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER);
+ _sourceDirectories.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Composite c2 = new Composite(c1, SWT.NONE);
+
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ c2.setLayout(gridLayout);
+
+ Button but1 = new Button(c2, SWT.PUSH);
+ but1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ but1.setText("Add Folder");
+ but1.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ IProject project = getProject();
+
+ SourceSelectionDialog dialog = new SourceSelectionDialog(getShell(), project, "Select Source Location");
+ String[] items = _sourceDirectories.getItems();
+ IFolder[] resources = new IFolder[items.length];
+ for(int i = 0; i < items.length; ++i)
+ {
+ resources[i] = project.getFolder(items[i]);
+ }
+ dialog.setInitialSelections(resources);
+ if(dialog.open() == ContainerSelectionDialog.OK)
+ {
+ Object[] selection = dialog.getResult();
+ for(int i = 0; i < selection.length; ++i)
+ {
+ IFolder path = (IFolder) selection[i];
+ _sourceDirectories.add(path.getProjectRelativePath().toString());
+ }
+ }
+ }
+ });
+
+ Button but2 = new Button(c2, SWT.PUSH);
+ but2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ but2.setText("Remove");
+ but2.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ _sourceDirectories.remove(_sourceDirectories.getSelectionIndices());
+ }
+ });
+
+ Group gclGroup = new Group(composite, SWT.NONE);
+ gclGroup.setText("Generated Code Location");
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gclGroup.setLayout(gridLayout);
+ gclGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Composite tc = new Composite(gclGroup, SWT.NONE);
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ tc.setLayout(gridLayout);
+ tc.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label l = new Label(tc, SWT.WRAP);
+ l.setForeground(new Color(null, 255, 0, 0));
+ l.setText("This subdirectory is used by the plug-in to manage the source files generated from " +
+ "your Slice definitions. It should not be used for any other purpose. " +
+ "Files added manually are removed during project rebuilds.");
+
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.widthHint = 400;
+ l.setLayoutData(gridData);
+
+ Composite c = new Composite(tc, SWT.NONE);
+
+ GridLayout gridLayout2 = new GridLayout();
+ gridLayout2.numColumns = 2;
+ gridLayout2.marginLeft = 0;
+ gridLayout2.marginTop = 0;
+ gridLayout2.marginBottom = 0;
+ c.setLayout(gridLayout2);
+
+ c.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ _generatedDir = new Text(c, SWT.BORDER | SWT.READ_ONLY);
+ gridData = new GridData(GridData.FILL_HORIZONTAL);
+ // gridData.horizontalSpan = 2;
+ _generatedDir.setLayoutData(gridData);
+
+ Button but3 = new Button(c, SWT.PUSH);
+ but3.setText("Browse");
+ but3.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ IProject project = getProject();
+
+ SourceSelectionDialog dialog = new SourceSelectionDialog(getShell(), project,
+ "Select Generated Code Location");
+ dialog.setMultiple(false);
+ if(dialog.open() == ContainerSelectionDialog.OK)
+ {
+ Object[] selection = dialog.getResult();
+ if(selection.length == 1)
+ {
+ IFolder path = (IFolder) selection[0];
+ String oldPath = _generatedDir.getText();
+ String newPath = path.getProjectRelativePath().toString();
+ if(oldPath.equals(newPath))
+ {
+ return;
+ }
+ try
+ {
+ if(path.members().length > 0)
+ {
+ ErrorDialog.openError(getShell(), "Error",
+ "Generated code location should be an empty folder",
+ new Status(Status.ERROR, Activator.PLUGIN_ID, "The chosen directory '" +
+ path.getFullPath().toOSString() + "' is not empty." ));
+ return;
+ }
+ }
+ catch(CoreException ex)
+ {
+ ErrorDialog.openError(getShell(), "Error", ex.toString(),
+ new Status(Status.ERROR, Activator.PLUGIN_ID, 0, "Failed to set generated code location.", ex));
+ return;
+ }
+ _generatedDir.setText(newPath);
+ }
+ }
+ }
+ });
+
+ return composite;
+ }
+
+ private Button _freezeJar;
+
+ private Text _generatedDir;
+ private List _sourceDirectories;
+ private Group _jarsGroup;
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/PropertyPage.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/PropertyPage.java
new file mode 100644
index 00000000000..48281f575da
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/PropertyPage.java
@@ -0,0 +1,484 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.properties;
+
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+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.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Text;
+
+import com.zeroc.slice2javaplugin.Activator;
+import com.zeroc.slice2javaplugin.builder.Slice2JavaBuilder;
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public abstract class PropertyPage extends org.eclipse.ui.dialogs.PropertyPage
+{
+ public PropertyPage(boolean projectPage)
+ {
+ super();
+ _projectPage = projectPage;
+ noDefaultAndApplyButton();
+ }
+
+ public void performApply()
+ {
+ super.performApply();
+ }
+
+ protected Control createIncludes(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ _includes = new List(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER);
+ _includes.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Composite c2 = new Composite(composite, SWT.NONE);
+
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ c2.setLayout(gridLayout);
+
+ Button but1 = new Button(c2, SWT.PUSH);
+ but1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ but1.setText("Add");
+ but1.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ IProject project = getProject();
+ DirectoryDialog dialog = new DirectoryDialog(getShell());
+ String dir = dialog.open();
+ if(dir != null)
+ {
+ IPath projectLocation = project.getLocation();
+ IPath includeLocation = new Path(dir);
+ String dev1 = projectLocation.getDevice();
+ if(dev1 == null)
+ {
+ dev1 = "";
+ }
+ String dev2 = includeLocation.getDevice();
+ if(dev2 == null)
+ {
+ dev2 = "";
+ }
+ IPath result;
+
+ // If the directories are on different devices, then we have
+ // no choice but to use an absolute path.
+ if(!dev1.equals(dev2))
+ {
+ result = includeLocation;
+ }
+ else
+ {
+
+ // Convert the absolute path to a relative path.
+ int n = projectLocation.matchingFirstSegments(includeLocation);
+ result = includeLocation.removeFirstSegments(n);
+
+ IPath up = new Path("..");
+ for(n = projectLocation.segmentCount() - n; n > 0; --n)
+ {
+ result = up.append(result);
+ }
+ // The devices must match, so remove it.
+ result = result.setDevice(null);
+ }
+ _includes.add(result.toString());
+ }
+ }
+ });
+ Button but2 = new Button(c2, SWT.PUSH);
+ but2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ but2.setText("Remove");
+ but2.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ _includes.remove(_includes.getSelectionIndices());
+ }
+ });
+ Button but3 = new Button(c2, SWT.PUSH);
+ but3.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ but3.setText("Up");
+ but3.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int index = _includes.getSelectionIndex();
+ if(index > 0)
+ {
+ String[] items = _includes.getItems();
+ String tmp = items[index-1];
+ items[index-1] = items[index];
+ items[index] = tmp;
+ _includes.setItems(items);
+ _includes.setSelection(index-1);
+ }
+ }
+ });
+ Button but4 = new Button(c2, SWT.PUSH);
+ but4.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ but4.setText("Down");
+ but4.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int index = _includes.getSelectionIndex();
+ if(index != -1)
+ {
+ String[] items = _includes.getItems();
+ if(index != items.length-1)
+ {
+ String tmp = items[index+1];
+ items[index+1] = items[index];
+ items[index] = tmp;
+ _includes.setItems(items);
+ _includes.setSelection(index+1);
+ }
+ }
+ }
+ });
+
+ return composite;
+ }
+
+ private String semiFilter(String text)
+ {
+ java.util.List<String> l = Arrays.asList(text.split(";"));
+ StringBuffer sb = new StringBuffer();
+ for(Iterator<String> p = l.iterator(); p.hasNext();)
+ {
+ String n = p.next().trim();
+ if(n.length() > 0)
+ {
+ if(sb.length() != 0)
+ {
+ sb.append(';');
+ }
+ sb.append(n);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected Control createDefines(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gridLayout.marginLeft = 0;
+ gridLayout.marginTop = 0;
+ gridLayout.marginBottom = 0;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label l = new Label(composite, SWT.WRAP);
+ l.setText("Enter macros (';' separated). For example, enter FOO;BAR to define -DFOO -DBAR.");
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.widthHint = 400;
+ l.setLayoutData(gridData);
+
+ _defines = new Text(composite, SWT.BORDER);
+ _defines.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ _defines.addFocusListener(new FocusListener()
+ {
+ public void focusGained(FocusEvent e)
+ {
+ }
+
+ public void focusLost(FocusEvent e)
+ {
+ Text t = (Text)e.widget;
+ String f = t.getText();
+ String filtered = semiFilter(f);
+ if(!f.equals(filtered))
+ {
+ t.setText(filtered);
+ }
+ }
+ });
+
+ return composite;
+ }
+
+ protected Control createMeta(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gridLayout.marginLeft = 0;
+ gridLayout.marginTop = 0;
+ gridLayout.marginBottom = 0;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label l = new Label(composite, SWT.WRAP);
+ l.setText("Enter metadata (';' separated). For example, enter as:package:com.acme to define --meta=as:package:com.acme.");
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.widthHint = 400;
+ l.setLayoutData(gridData);
+
+ _meta = new Text(composite, SWT.BORDER);
+ _meta.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ _meta.addFocusListener(new FocusListener()
+ {
+ public void focusGained(FocusEvent e)
+ {
+ }
+
+ public void focusLost(FocusEvent e)
+ {
+ Text t = (Text)e.widget;
+ String f = t.getText();
+ String filtered = semiFilter(f);
+ if(!f.equals(filtered))
+ {
+ t.setText(filtered);
+ }
+ }
+ });
+
+ return composite;
+ }
+
+ protected void createPreOptions(Composite parent)
+ {
+ }
+
+ protected void createPostOptions(Composite parent)
+ {
+ }
+
+ protected Control createOptions(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ composite.setLayout(gridLayout);
+
+ createPreOptions(composite);
+
+ Group includesGroup = new Group(composite, SWT.NONE);
+ includesGroup.setText("Location of Include Files");
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ includesGroup.setLayout(gridLayout);
+ includesGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ createIncludes(includesGroup);
+
+ Group definesGroup = new Group(composite, SWT.NONE);
+ definesGroup.setText("Preprocessor Definitions");
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ definesGroup.setLayout(gridLayout);
+ definesGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ createDefines(definesGroup);
+
+ Group metaGroup = new Group(composite, SWT.NONE);
+ metaGroup.setText("Metadata Definitions");
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ metaGroup.setLayout(gridLayout);
+ metaGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ createMeta(metaGroup);
+
+ Group optionsGroup = new Group(composite, SWT.NONE);
+
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 5;
+ optionsGroup.setText("Options");
+ optionsGroup.setLayout(gridLayout);
+ optionsGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ _stream = new Button(optionsGroup, SWT.CHECK);
+ _stream.setText("Enable streaming");
+ _tie = new Button(optionsGroup, SWT.CHECK);
+ _tie.setText("Enable tie");
+ _ice = new Button(optionsGroup, SWT.CHECK);
+ _ice.setText("Enable ice");
+ if(_projectPage)
+ {
+ _console = new Button(optionsGroup, SWT.CHECK);
+ _console.setText("Enable console");
+ }
+ _underscore = new Button(optionsGroup, SWT.CHECK);
+ _underscore.setText("Enable underscore");
+
+ Group extraArgumentsGroup = new Group(composite, SWT.NONE);
+ extraArgumentsGroup.setText("Extra Compiler Arguments");
+ gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ extraArgumentsGroup.setLayout(gridLayout);
+ extraArgumentsGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+ createExtraArguments(extraArgumentsGroup);
+
+ createPostOptions(composite);
+
+ return composite;
+ }
+
+ public Control createExtraArguments(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gridLayout.marginLeft = 0;
+ gridLayout.marginTop = 0;
+ gridLayout.marginBottom = 0;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label l = new Label(composite, SWT.WRAP);
+ l.setText("Enter extra arguments for the Slice compiler, such as --checksum=foo.Bar.SliceChecksums. " +
+ "These arguments are appended to the compiler command line.");
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.widthHint = 400;
+ l.setLayoutData(gridData);
+
+ _extraArguments = new Text(composite, SWT.BORDER);
+ _extraArguments.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ return composite;
+ }
+
+ protected IProject getProject()
+ {
+ IAdaptable a = getElement();
+ if(a instanceof IProject)
+ {
+ return (IProject)a;
+ }
+ else if(a instanceof IJavaProject)
+ {
+ return ((IJavaProject) a).getProject();
+ }
+ else if(a instanceof IResource)
+ {
+ return ((IResource)a).getProject();
+ }
+ else
+ {
+ assert(false);
+ return null;
+ }
+ }
+
+ protected IResource getResource()
+ {
+ IAdaptable a = getElement();
+ if(a instanceof IResource)
+ {
+ return (IResource)a;
+ }
+ else
+ {
+ assert(false);
+ return null;
+ }
+ }
+
+ protected boolean configSaveAndRebuild()
+ {
+ final IProject project = getProject();
+ try
+ {
+ if(_config.write())
+ {
+ // The configuration properties were changed. We need to rebuild
+ // the slice files.
+ Job job = new Job("Rebuild")
+ {
+ protected IStatus run(IProgressMonitor monitor)
+ {
+ try
+ {
+ project.build(IncrementalProjectBuilder.FULL_BUILD, Slice2JavaBuilder.BUILDER_ID, null,
+ monitor);
+ }
+ catch(CoreException e)
+ {
+ return new Status(Status.ERROR, Activator.PLUGIN_ID, 0, "rebuild failed", e);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ job.setPriority(Job.BUILD);
+ job.schedule(); // start as soon as possible
+ }
+ }
+ catch(CoreException e)
+ {
+ return false;
+ }
+ catch(IOException e)
+ {
+ ErrorDialog.openError(getShell(), "Error", "Error saving preferences",
+ new Status(Status.ERROR, Activator.PLUGIN_ID, 0, null, e));
+ return false;
+ }
+ return true;
+ }
+
+ protected Configuration _config;
+ protected Button _console;
+ protected List _includes;
+
+ protected Text _defines;
+ protected Button _stream;
+ protected Button _tie;
+ protected Button _ice;
+ protected Button _underscore;
+ protected Text _meta;
+ protected Text _extraArguments;
+ protected boolean _projectPage;
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SliceFilePropertyPage.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SliceFilePropertyPage.java
new file mode 100644
index 00000000000..b1509ae3b6f
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SliceFilePropertyPage.java
@@ -0,0 +1,110 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.properties;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+
+import com.zeroc.slice2javaplugin.internal.Configuration;
+
+public class SliceFilePropertyPage extends PropertyPage
+{
+ public SliceFilePropertyPage()
+ {
+ super(false);
+ setTitle("Slice2as Settings");
+ }
+
+ protected void createPreOptions(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gridLayout.marginLeft = 0;
+ gridLayout.marginTop = 0;
+ gridLayout.marginBottom = 0;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label l = new Label(composite, SWT.WRAP);
+ l.setText("File:");
+ GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+ l.setLayoutData(gridData);
+
+ Text pathValueText = new Text(composite, SWT.WRAP | SWT.READ_ONLY);
+ pathValueText.setText(getResource().getFullPath().toString());
+ pathValueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ }
+
+ protected Control createContents(Composite parent)
+ {
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ {
+ TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
+
+
+ Control source = createOptions(tabFolder);
+ tabItem.setText("Options");
+ tabItem.setControl(source);
+ }
+
+ tabFolder.pack();
+ loadPrefs();
+ return tabFolder;
+ }
+
+ public boolean performOk()
+ {
+ final IResource resource = getResource();
+ _config.setIncludes(resource, Arrays.asList(_includes.getItems()));
+ _config.setDefines(resource, Configuration.toList(_defines.getText()));
+ _config.setStream(_stream.getSelection());
+ _config.setMeta(resource, Configuration.toList(_meta.getText()));
+ _config.setTie(resource, _tie.getSelection());
+ _config.setIce(resource, _ice.getSelection());
+ _config.setUnderscore(resource, _underscore.getSelection());
+ _config.setExtraArguments(resource, _extraArguments.getText());
+ return configSaveAndRebuild();
+ }
+
+ private void loadPrefs()
+ {
+ IProject project = getProject();
+ IResource resource = getResource();
+ _config = new Configuration(project);
+
+ for(Iterator<String> iter = _config.getBareIncludes(resource).iterator(); iter.hasNext();)
+ {
+ _includes.add(iter.next());
+ }
+
+ _defines.setText(Configuration.fromList(_config.getDefines(resource)));
+ _meta.setText(Configuration.fromList(_config.getMeta(resource)));
+ _stream.setSelection(_config.getStream());
+ _tie.setSelection(_config.getTie(resource));
+ _ice.setSelection(_config.getIce(resource));
+ _underscore.setSelection(_config.getUnderscore(resource));
+ _extraArguments.setText(_config.getExtraArguments(resource));
+ }
+}
diff --git a/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SourceSelectionDialog.java b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SourceSelectionDialog.java
new file mode 100644
index 00000000000..b9634da3415
--- /dev/null
+++ b/eclipse/java/Slice2javaPlugin/src/com/zeroc/slice2javaplugin/properties/SourceSelectionDialog.java
@@ -0,0 +1,254 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This plug-in is provided to you under the terms and conditions
+// of the Eclipse Public License Version 1.0 ("EPL"). A copy of
+// the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+//
+// **********************************************************************
+
+package com.zeroc.slice2javaplugin.properties;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+class SourceSelectionDialog extends SelectionDialog
+{
+ // Do we allow multiple selections?
+ private boolean multiple = true;
+
+ // the root element to populate the viewer with
+ private IProject root;
+
+ // the visual selection widget group
+ private CheckboxTreeViewer selectionGroup;
+
+ // constants
+ private final static int SIZING_SELECTION_WIDGET_WIDTH = 400;
+
+ private final static int SIZING_SELECTION_WIDGET_HEIGHT = 300;
+
+ /**
+ * Creates a resource selection dialog rooted at the given element.
+ *
+ * @param parentShell
+ * the parent shell
+ * @param rootElement
+ * the root element to populate this dialog with
+ * @param message
+ * the message to be displayed at the top of this dialog, or
+ * <code>null</code> to display a default message
+ */
+ public SourceSelectionDialog(Shell parentShell, IProject project, String message)
+ {
+ super(parentShell);
+ setTitle("Source Folder Selection");
+ root = project;
+ if(message != null)
+ {
+ setMessage(message);
+ }
+ else
+ {
+ setMessage("Select source folder:");
+ }
+ }
+
+ public void setMultiple(boolean m)
+ {
+ multiple = m;
+ }
+
+ /*
+ * (non-Javadoc) Method declared in Window.
+ */
+ protected void configureShell(Shell shell)
+ {
+ super.configureShell(shell);
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IIDEHelpContextIds.RESOURCE_SELECTION_DIALOG);
+ }
+
+ public void create()
+ {
+ super.create();
+ initializeDialog();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite parent)
+ {
+ // page group
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ // create the input element, which has the root resource
+ // as its only child
+ ArrayList<IProject> input = new ArrayList<IProject>();
+ input.add(root);
+
+ createMessageArea(composite);
+
+ Tree tree = new Tree(composite, ((multiple) ? SWT.CHECK : SWT.SINGLE) | SWT.BORDER);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
+ data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
+ tree.setLayoutData(data);
+ tree.setFont(parent.getFont());
+
+ selectionGroup = new CheckboxTreeViewer(tree);
+ selectionGroup.setContentProvider(getResourceProvider(IResource.FILE | IResource.PROJECT));
+ selectionGroup.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider());
+ selectionGroup.setInput(input);
+
+ selectionGroup.expandToLevel(2);
+
+ return composite;
+ }
+
+ /**
+ * Returns a content provider for <code>IResource</code>s that returns only
+ * children of the given resource type.
+ */
+ private ITreeContentProvider getResourceProvider(final int resourceType)
+ {
+ return new WorkbenchContentProvider()
+ {
+ @SuppressWarnings("unchecked")
+ public Object[] getChildren(Object o)
+ {
+ if(o instanceof IContainer)
+ {
+ IResource[] members = null;
+ try
+ {
+ members = ((IContainer) o).members();
+ }
+ catch(CoreException e)
+ {
+ // just return an empty set of children
+ return new Object[0];
+ }
+
+ // filter out the desired resource types
+ ArrayList<Object> results = new ArrayList<Object>();
+ for(int i = 0; i < members.length; i++)
+ {
+ if(members[i] instanceof IFolder)
+ {
+ results.add(members[i]);
+ }
+ }
+ return results.toArray();
+ }
+ // input element case
+ if(o instanceof ArrayList)
+ {
+ return ((ArrayList<Object>) o).toArray();
+ }
+ return new Object[0];
+ }
+ };
+ }
+
+ /**
+ * Initializes this dialog's controls.
+ */
+ private void initializeDialog()
+ {
+ getOkButton().setEnabled(false);
+ if(multiple)
+ {
+ selectionGroup.addCheckStateListener(new ICheckStateListener()
+ {
+ public void checkStateChanged(CheckStateChangedEvent event)
+ {
+ if(!event.getChecked() && selectionGroup.getGrayed(event.getElement()))
+ {
+ selectionGroup.setChecked(event.getElement(), true);
+ }
+ else
+ {
+ int count = selectionGroup.getCheckedElements().length - getInitialElementSelections().size();
+ getOkButton().setEnabled(count > 0);
+ }
+ }
+ });
+
+ for(Iterator<?> iter = getInitialElementSelections().iterator(); iter.hasNext(); )
+ {
+ IResource cur = (IResource)iter.next();
+ selectionGroup.setGrayChecked(cur, true);
+ }
+ }
+ else
+ {
+ selectionGroup.addSelectionChangedListener(new ISelectionChangedListener()
+ {
+ public void selectionChanged(SelectionChangedEvent event)
+ {
+ getOkButton().setEnabled(true);
+ }
+ });
+ }
+ }
+
+ /**
+ * The <code>ResourceSelectionDialog</code> implementation of this
+ * <code>Dialog</code> method builds a list of the selected resources for
+ * later retrieval by the client and closes this dialog.
+ */
+ protected void okPressed()
+ {
+ /*
+ * Iterator resultEnum = selectionGroup.getAllCheckedListItems();
+ * ArrayList list = new ArrayList(); while (resultEnum.hasNext()) {
+ * list.add(resultEnum.next()); } setResult(list);
+ */
+ ArrayList<Object> list = new ArrayList<Object>();
+ if(multiple)
+ {
+ Object[] objs = selectionGroup.getCheckedElements();
+ for(int i = 0; i < objs.length; ++i)
+ {
+ if(!selectionGroup.getGrayed(objs[i]))
+ {
+ list.add(objs[i]);
+ }
+ }
+ }
+ else
+ {
+ TreeSelection obj = (TreeSelection)selectionGroup.getSelection();
+ if(!obj.isEmpty())
+ {
+ list.add(obj.getFirstElement());
+ }
+ }
+ setResult(list);
+ super.okPressed();
+ }
+}