You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/07/13 15:26:06 UTC
svn commit: r793581 [12/23] - in /felix/trunk/sigil: ./ bld-ivy/
bld-ivy/example/ bld-ivy/example/dependence/
bld-ivy/example/dependence/dependee/ bld-ivy/example/dependence/dependee/src/
bld-ivy/example/dependence/dependee/src/standalone/ bld-ivy/exam...
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/SigilCore.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/SigilCore.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/SigilCore.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/SigilCore.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,570 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.cauldron.bld.config.IBldProject;
+import org.cauldron.bld.core.BldCore;
+import org.cauldron.sigil.install.IOSGiInstallManager;
+import org.cauldron.sigil.internal.install.OSGiInstallManager;
+import org.cauldron.sigil.internal.model.project.SigilModelRoot;
+import org.cauldron.sigil.internal.model.project.SigilProject;
+import org.cauldron.sigil.internal.model.repository.RepositoryConfiguration;
+import org.cauldron.sigil.internal.repository.eclipse.GlobalRepositoryManager;
+import org.cauldron.sigil.internal.repository.eclipse.SigilRepositoryManager;
+import org.cauldron.sigil.model.ModelElementFactory;
+import org.cauldron.sigil.model.eclipse.ISigilBundle;
+import org.cauldron.sigil.model.project.ISigilModelRoot;
+import org.cauldron.sigil.model.project.ISigilProjectModel;
+import org.cauldron.sigil.model.repository.IRepositoryConfiguration;
+import org.cauldron.sigil.model.util.JavaHelper;
+import org.cauldron.sigil.repository.IBundleRepository;
+import org.cauldron.sigil.repository.IRepositoryManager;
+import org.cauldron.sigil.repository.IRepositoryVisitor;
+import org.cauldron.sigil.repository.ResolutionConfig;
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+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.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class SigilCore extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.cauldron.sigil.core";
+ public static final String NATURE_ID = PLUGIN_ID + ".sigilnature";
+ public static final String PREFERENCES_ID = "org.cauldron.sigil.ui.preferences.SigilPreferencePage";
+ public static final String OSGI_INSTALLS_PREFERENCES_ID = "org.cauldron.sigil.ui.preferences.osgiInstalls";
+ public static final String EXCLUDED_RESOURCES_PREFERENCES_ID = "org.cauldron.sigil.ui.preferences.excludedResources";
+ public static final String REPOSITORIES_PREFERENCES_ID = "org.cauldron.sigil.ui.preferences.repositoriesPreferencePage";
+ public static final String OSGI_SCRIPT_TYPE = "org.cauldron.sigil.content.OSGiScriptType";
+ public static final String SIGIL_PROJECT_FILE = IBldProject.PROJECT_FILE;
+ public static final String BUILDER_ID = PLUGIN_ID + ".sigilBuilder";
+ public static final String CLASSPATH_CONTAINER_PATH = PLUGIN_ID + ".classpathContainer";
+
+ public static final String OSGI_INSTALLS = "org.cauldron.osgi.installs";
+ public static final String OSGI_DEFAULT_INSTALL_ID = "org.cauldron.osgi.default.install.id";
+ public static final String OSGI_INSTALL_PREFIX = "org.cauldron.osgi.install.";
+ public static final String OSGI_SOURCE_LOCATION = "org.cauldron.osgi.source.location";
+ public static final String OSGI_INSTALL_CHECK_PREFERENCE = "org.cauldron.osgi.install.check";
+ public static final String LIBRARY_KEYS_PREF = "org.cauldron.osgi.library.keys";
+ public static final String PREFERENCES_REBUILD_PROJECTS = "org.cauldron.sigil.rebuild.projects";
+ public static final String QUALIFY_VERSIONS = "org.cauldron.sigil.qualify.versions";
+
+ public static final String DEFAULT_VERSION_LOWER_BOUND = "org.cauldron.sigil.versionLowerBound";
+ public static final String DEFAULT_VERSION_UPPER_BOUND = "org.cauldron.sigil.versionUpperBound";
+
+ public static final String DEFAULT_EXCLUDED_RESOURCES = "org.cauldron.sigil.excludedResources";
+ public static final String PREFERENCES_NOASK_OSGI_INSTALL = "org.cauldron.sigil.noAskOSGIHome";
+ public static final String PREFERENCES_ADD_IMPORT_FOR_EXPORT = "org.cauldron.sigil.addImportForExport";
+ public static final String INCLUDE_OPTIONAL_DEPENDENCIES = "org.cauldron.sigil.includeOptionalDependencies";
+
+ public static final String INSTALL_BUILDER_EXTENSION_POINT_ID = "org.cauldron.sigil.installbuilder";
+ public static final String REPOSITORY_PROVIDER_EXTENSION_POINT_ID = "org.cauldron.sigil.repositoryprovider";
+
+ public static final String MARKER_UNRESOLVED_DEPENDENCY = "org.cauldron.sigil.unresolvedDependencyMarker";
+ public static final String MARKER_UNRESOLVED_IMPORT_PACKAGE = "org.cauldron.sigil.unresolvedDependencyMarker.importPackage";
+ public static final String MARKER_UNRESOLVED_REQUIRE_BUNDLE = "org.cauldron.sigil.unresolvedDependencyMarker.requireBundle";
+ public static final String REPOSITORY_SET = PLUGIN_ID + ".repository.set";
+ public static final String PREFERENCES_INCLUDE_OPTIONAL = PLUGIN_ID + ".include.optional";
+
+ private static final Object NULL = new Object();
+
+ // The shared instance
+ private static SigilCore plugin;
+
+ private ServiceTracker descriptorTracker;
+ private ServiceTracker registryTracker;
+ private ServiceTracker serializerTracker;
+
+ private static IRepositoryConfiguration repositoryConfig;
+ private static OSGiInstallManager installs;
+ private static ISigilModelRoot modelRoot;
+ private static HashMap<Object, SigilRepositoryManager> repositoryManagers = new HashMap<Object, SigilRepositoryManager>();
+ private static GlobalRepositoryManager globalRepositoryManager;
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static SigilCore getDefault() {
+ return plugin;
+ }
+
+ public static CoreException newCoreException(String msg, Throwable t) {
+ return new CoreException(makeStatus(msg, t, IStatus.ERROR));
+ }
+
+ public static void log(String msg) {
+ DebugPlugin.log(makeStatus(msg, null, IStatus.INFO));
+ }
+
+ public static void error(String msg) {
+ DebugPlugin.log(makeStatus(msg, null, IStatus.ERROR));
+ }
+
+ public static void error(String msg, Throwable t) {
+ DebugPlugin.log(makeStatus(msg, t, IStatus.ERROR));
+ }
+
+ public static void warn(String msg) {
+ DebugPlugin.log(makeStatus(msg, null, IStatus.WARNING));
+ }
+
+ public static void warn(String msg, Throwable t) {
+ DebugPlugin.log(makeStatus(msg, t, IStatus.WARNING));
+ }
+
+ private static IStatus makeStatus(String msg, Throwable t, int status) {
+ if (t instanceof CoreException) {
+ CoreException c = (CoreException) t;
+ return c.getStatus();
+ } else {
+ return new Status(status, SigilCore.PLUGIN_ID, status, msg, t);
+ }
+ }
+
+ public static boolean isSigilProject(IProject resource) {
+ if ( resource == null ) return false;
+
+ if ( resource.isAccessible() && resource instanceof IProject ) {
+ IProject project = (IProject) resource;
+ try {
+ return project.hasNature(NATURE_ID);
+ } catch (CoreException e) {
+ error( e.getMessage(), e );
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ public static boolean hasProjectNature(IProject project)
+ throws CoreException {
+ return project.getNature(NATURE_ID) != null;
+ }
+
+ public static ResourceBundle getResourceBundle() {
+ return ResourceBundle.getBundle("resources."
+ + SigilCore.class.getName(), Locale.getDefault(),
+ SigilCore.class.getClassLoader());
+ }
+
+ public static ISigilProjectModel create(IProject project)
+ throws CoreException {
+ if (project.hasNature(NATURE_ID)) {
+ return new SigilProject(project);
+ } else {
+ throw newCoreException("Project " + project.getName()
+ + " is not a sigil project", null);
+ }
+ }
+
+ /**
+ * The constructor
+ */
+ public SigilCore() {
+ plugin = this;
+ }
+
+ public void earlyStartup() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(final BundleContext context) throws Exception {
+ super.start(context);
+
+ modelRoot = new SigilModelRoot();
+
+ repositoryConfig = new RepositoryConfiguration();
+
+ installs = new OSGiInstallManager();
+
+ globalRepositoryManager = new GlobalRepositoryManager();
+
+ registerModelElements(context);
+ registerResourceListeners();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ if (descriptorTracker != null) {
+ descriptorTracker.close();
+ descriptorTracker = null;
+ }
+
+ if (registryTracker != null) {
+ registryTracker.close();
+ registryTracker = null;
+ }
+
+ if (serializerTracker != null) {
+ serializerTracker.close();
+ serializerTracker = null;
+ }
+
+ for ( SigilRepositoryManager m : repositoryManagers.values() ) {
+ m.destroy();
+ }
+
+ repositoryManagers.clear();
+
+ globalRepositoryManager.destroy();
+ globalRepositoryManager = null;
+
+ plugin = null;
+
+ super.stop(context);
+ }
+
+
+ public static boolean isBundledPath(String bp) throws CoreException {
+ boolean bundle = JavaHelper.isCachedBundle(bp);
+
+ if (!bundle) {
+ bundle = isProjectPath(bp);
+
+ if (!bundle) {
+ for (IBundleRepository r : getGlobalRepositoryManager().getRepositories()) {
+ bundle = isBundlePath(bp, r);
+ if (bundle)
+ break;
+ }
+ }
+ }
+
+ return bundle;
+ }
+
+ private static boolean isBundlePath(final String bp, IBundleRepository r) {
+ final AtomicBoolean flag = new AtomicBoolean();
+
+ IRepositoryVisitor visitor = new IRepositoryVisitor() {
+ public boolean visit(ISigilBundle b) {
+ IPath path = b.getLocation();
+ if (path != null && path.toOSString().equals(bp)) {
+ flag.set(true);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ };
+
+ r.accept(visitor, ResolutionConfig.INDEXED_ONLY
+ | ResolutionConfig.LOCAL_ONLY);
+
+ return flag.get();
+ }
+
+ private static boolean isProjectPath(String bp) throws CoreException {
+ for (ISigilProjectModel p : SigilCore.getRoot().getProjects()) {
+ IPath path = p.findOutputLocation();
+
+ if (path.toOSString().equals(bp)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void registerResourceListeners() {
+ final IResourceChangeListener listener = new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDelta delta = event.getDelta();
+ if ( delta != null ) {
+ try {
+ delta.accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource resource = delta.getResource();
+ if(resource instanceof IProject) {
+ IProject project = (IProject) resource;
+ if ( SigilCore.isSigilProject(project) ) {
+ switch (delta.getKind()) {
+ case IResourceDelta.REMOVED:
+ case IResourceDelta.ADDED:
+ rebuildAllBundleDependencies(Job.getJobManager().createProgressGroup());
+ break;
+ }
+ }
+ // Recurse no more
+ return false;
+ }
+ return true;
+ }
+ });
+ } catch (CoreException e) {
+ error("Failed to update after change", e);
+ }
+ }
+ }
+ };
+
+ Job job = new Job("Initialising sigil resource listeners") {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE);
+ return Status.OK_STATUS;
+ }
+ };
+ job.setSystem(true);
+ job.schedule();
+ }
+
+ private void registerModelElements(BundleContext context) {
+ // trick to get eclipse to lazy load BldCore for model elements
+ BldCore.getLicenseManager();
+ String uri = "http://sigil.codecauldron.org/xml/sigil-namespace";
+ ModelElementFactory.getInstance().register(ISigilProjectModel.class,
+ SigilProject.class, "project", "sigil", uri);
+ }
+
+ public static IOSGiInstallManager getInstallManager() {
+ return installs;
+ }
+
+ public static ISigilModelRoot getRoot() {
+ return modelRoot;
+ }
+
+ public static IRepositoryManager getGlobalRepositoryManager() {
+ return globalRepositoryManager;
+ }
+
+ public static IRepositoryManager getRepositoryManager(String set) {
+ SigilRepositoryManager manager = null;
+
+ if ( set == null ) {
+ manager = repositoryManagers.get( NULL );
+ if ( manager == null ) {
+ manager = new SigilRepositoryManager(null);
+ manager.initialise();
+ repositoryManagers.put( NULL, manager );
+ }
+ }
+ else {
+ manager = repositoryManagers.get(set);
+
+ if ( manager == null ) {
+ manager = new SigilRepositoryManager(set);
+ manager.initialise();
+ repositoryManagers.put( set, manager );
+ }
+ }
+
+ return manager;
+ }
+ public static IRepositoryManager getRepositoryManager(ISigilProjectModel model) {
+ return getRepositoryManager(loadProjectRepositorySet(model));
+ }
+
+ private static String loadProjectRepositorySet(ISigilProjectModel model) {
+ if ( model == null ) {
+ return null;
+ }
+
+ return model.getPreferences().get(REPOSITORY_SET, null );
+ }
+
+
+ public static IRepositoryConfiguration getRepositoryConfiguration() {
+ return repositoryConfig;
+ }
+
+ public static void rebuildAllBundleDependencies(IProgressMonitor monitor) {
+ Collection<ISigilProjectModel> projects = getRoot().getProjects();
+ if ( !projects.isEmpty() ) {
+ SubMonitor progress = SubMonitor.convert(monitor, projects.size()*20);
+ for ( ISigilProjectModel p : projects ) {
+ rebuild(p, progress);
+ }
+ }
+
+ monitor.done();
+ }
+
+ public static void rebuildBundleDependencies(ISigilProjectModel project, IProgressMonitor monitor) {
+ HashSet<ISigilProjectModel> affected = new HashSet<ISigilProjectModel>(project.findDependentProjects(monitor));
+ affected.add(project);
+
+ SubMonitor progress = SubMonitor.convert(monitor, affected.size()*20);
+ for (ISigilProjectModel dependent : affected) {
+ rebuild(dependent, progress);
+ }
+ }
+
+
+ private static void rebuild(ISigilProjectModel dependent, SubMonitor progress) {
+ try {
+ dependent.resetClasspath(progress.newChild(10));
+ dependent.getProject().build(IncrementalProjectBuilder.FULL_BUILD, progress.newChild(10));
+ } catch (CoreException e) {
+ SigilCore.error("Failed to rebuild " + dependent, e);
+ }
+ }
+
+ public IPath findDefaultBundleLocation(ISigilProjectModel m)
+ throws CoreException {
+ IPath loc = m.getProject().getLocation();
+ loc = loc.append(m.getJavaModel().getOutputLocation().removeFirstSegments(1));
+ loc = loc.removeLastSegments(1).append( "lib" );
+ return loc.append(m.getSymbolicName() + ".jar");
+ }
+
+ public static void makeSigilProject(IProject project,
+ IProgressMonitor monitor) throws CoreException {
+ IProjectDescription description = project.getDescription();
+
+ String[] natures = description.getNatureIds();
+ String[] newNatures = new String[natures.length + 1];
+ System.arraycopy(natures, 0, newNatures, 0, natures.length);
+ newNatures[natures.length] = SigilCore.NATURE_ID;
+ description.setNatureIds(newNatures);
+
+ ICommand sigilBuild = description.newCommand();
+ sigilBuild.setBuilderName(SigilCore.BUILDER_ID);
+
+ ICommand javaBuild = description.newCommand();
+ javaBuild.setBuilderName(JavaCore.BUILDER_ID);
+
+ description.setBuildSpec(new ICommand[] { javaBuild, sigilBuild });
+
+ project.setDescription(description, new SubProgressMonitor(monitor, 2));
+
+ IJavaProject java = JavaCore.create(project);
+ if (java.exists()) {
+ IClasspathEntry[] cp = java.getRawClasspath();
+ // XXX fix for http://jira.codecauldron.org/browse/SIGIL-304
+ if ( !isSigilOnClasspath(cp) ) {
+ ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(
+ Arrays.asList(cp));
+ entries.add(JavaCore.newContainerEntry(new Path(
+ SigilCore.CLASSPATH_CONTAINER_PATH)));
+ java.setRawClasspath(entries.toArray(new IClasspathEntry[entries
+ .size()]), monitor);
+ }
+ }
+ }
+
+ /**
+ * @param cp
+ * @return
+ */
+ private static boolean isSigilOnClasspath(IClasspathEntry[] cp) {
+ for ( IClasspathEntry e : cp ) {
+ if ( e.getEntryKind() == IClasspathEntry.CPE_CONTAINER && e.getPath().segment(0).equals(SigilCore.CLASSPATH_CONTAINER_PATH) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Image loadImage(URL url) throws IOException {
+ ImageRegistry registry = getDefault().getImageRegistry();
+
+ String key = url.toExternalForm();
+ Image img = registry.get( key );
+
+ if ( img == null ) {
+ img = openImage(url);
+ registry.put( key, img );
+ }
+
+ return img;
+ }
+
+ private static Image openImage(URL url) throws IOException {
+ Display display = Display.getCurrent();
+ if ( display == null ) {
+ display = Display.getDefault();
+ }
+
+ InputStream in = null;
+ try {
+ in = url.openStream();
+ return new Image(display, in);
+ }
+ finally {
+ if ( in != null ) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ error( "Failed to close stream", e );
+ }
+ }
+ }
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstall.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstall.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstall.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstall.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.install;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Encapsulates all information about a particular OSGi install.
+ *
+ * @author dave
+ *
+ */
+public interface IOSGiInstall {
+
+ /**
+ * A unique id which can be used to refer to this install within the eclipse runtime.
+ * @return
+ */
+ String getId();
+
+ /**
+ * Where this install is located
+ * @return
+ */
+ IPath getInstallLocation();
+
+ /**
+ * @return
+ */
+ Map<String, String> getProperties();
+
+ /**
+ * @return
+ */
+ String[] getLaunchArguments();
+
+ /**
+ * @return
+ */
+ IPath getVarDirectory();
+
+ /**
+ * @return
+ */
+ IOSGiInstallType getType();
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallBuilder.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallBuilder.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallBuilder.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.install;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+public interface IOSGiInstallBuilder {
+ IOSGiInstall build(String id, IPath path) throws CoreException;
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallManager.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallManager.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallManager.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.install;
+
+public interface IOSGiInstallManager {
+ IOSGiInstall findInstall(String id);
+ String[] getInstallIDs();
+ IOSGiInstall[] getInstalls();
+ IOSGiInstall getDefaultInstall();
+ IOSGiInstallType findInstallType(String location);
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallType.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallType.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallType.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/IOSGiInstallType.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.install;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.swt.graphics.Image;
+
+//import org.eclipse.swt.graphics.Image;
+
+public interface IOSGiInstallType {
+ /**
+ * @return
+ */
+ String getName();
+
+ /**
+ *
+ * @return
+ */
+ String getVersion();
+
+ /**
+ * @return
+ */
+ String getMainClass();
+
+ /**
+ * @return
+ */
+ String[] getClassPath();
+
+ /**
+ * @return
+ */
+ IPath getSourceLocation();
+
+ /**
+ * @return
+ */
+ IPath getJavaDocLocation();
+
+ /**
+ * Return the paths of any bundles that are started by default in this OSGi instance.
+ * @return
+ */
+ IPath[] getDefaultBundleLocations();
+
+ String getId();
+
+ Image getIcon();
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstall.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstall.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstall.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstall.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.install;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+
+public class OSGiInstall implements IOSGiInstall {
+
+ private String id;
+ private IPath installLocation;
+ private String[] launchArgs;
+ private Map<String, String> properties;
+ private IPath varDirectory;
+ private IOSGiInstallType type;
+
+ public IPath getVarDirectory() {
+ return varDirectory;
+ }
+
+ public void setVarDirectory(IPath varDirectory) {
+ this.varDirectory = varDirectory;
+ }
+
+ public OSGiInstall(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public IPath getInstallLocation() {
+ return installLocation;
+ }
+
+ public void setInstallLocation(IPath installLocation) {
+ this.installLocation = installLocation;
+ }
+
+ public String[] getLaunchArguments() {
+ return launchArgs;
+ }
+
+ public void setLaunchArguments(String[] launchArgs) {
+ this.launchArgs = launchArgs;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String,String> properties) {
+ this.properties = properties;
+ }
+
+ public String toString() {
+ return "OSGiInstall[\n" +
+ "id=" + id + "\n" +
+ "type=" + type + "\n" +
+ "installLocation=" + installLocation + "\n" +
+ "launchArgs=" + Arrays.asList(launchArgs) + "\n" +
+ "properties=" + properties + "\n" +
+ "]";
+ }
+
+ public IOSGiInstallType getType() {
+ return type;
+ }
+
+ public void setType(IOSGiInstallType type) {
+ this.type = type;
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstallType.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstallType.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstallType.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/install/OSGiInstallType.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.install;
+
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.swt.graphics.Image;
+
+public class OSGiInstallType implements IOSGiInstallType {
+
+ private String id;
+ private String name;
+ private String version;
+ private String mainClass;
+ private String[] classPath;
+ private IPath javaDocLocation;
+ private IPath sourceLocation;
+ private IPath[] defaultBundleLocations;
+ private Image icon;
+
+ public Image getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Image icon) {
+ this.icon = icon;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String[] getClassPath() {
+ return classPath;
+ }
+
+ public IPath[] getDefaultBundleLocations() {
+ return defaultBundleLocations;
+ }
+
+ public IPath getJavaDocLocation() {
+ return javaDocLocation;
+ }
+
+ public String getMainClass() {
+ return mainClass;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public IPath getSourceLocation() {
+ return sourceLocation;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public void setMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ public void setClassPath(String[] classPath) {
+ this.classPath = classPath;
+ }
+
+ public void setJavaDocLocation(IPath javaDocLocation) {
+ this.javaDocLocation = javaDocLocation;
+ }
+
+ public void setSourceLocation(IPath sourceLocation) {
+ this.sourceLocation = sourceLocation;
+ }
+
+ public void setDefaultBundleLocations(IPath[] defaultBundleLocations) {
+ this.defaultBundleLocations = defaultBundleLocations;
+ }
+
+ public String toString() {
+ return "OSGiInstallType[\n" +
+ "name=" + name + "\n" +
+ "version=" + version + "\n" +
+ "mainClass=" + mainClass + "\n" +
+ "classPath=" + Arrays.asList(classPath) + "\n" +
+ "javaDocLocation=" + javaDocLocation + "\n" +
+ "sourceLocation=" + sourceLocation + "\n" +
+ "defaultBundleLocations=" + Arrays.asList(defaultBundleLocations) + "\n" +
+ "]";
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/FileAdaptorFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/FileAdaptorFactory.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/FileAdaptorFactory.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/FileAdaptorFactory.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.adapter;
+
+import org.cauldron.sigil.SigilCore;
+import org.cauldron.sigil.model.ModelElementFactory;
+import org.cauldron.sigil.model.ModelElementFactoryException;
+import org.cauldron.sigil.model.eclipse.ISigilBundle;
+import org.cauldron.sigil.model.project.ISigilProjectModel;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdapterFactory;
+
+/**
+ * @author savage
+ *
+ */
+public class FileAdaptorFactory implements IAdapterFactory {
+
+ public FileAdaptorFactory() {
+
+ }
+ private Class<?>[] types = new Class<?>[] { ISigilBundle.class };
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public Object getAdapter( Object adaptableObject, Class adapterType ) {
+ Object adapted = null;
+
+ IFile file = (IFile) adaptableObject;
+
+ if ( ISigilBundle.class.equals( adapterType ) ) {
+ adapted = adaptBundle(file);
+ }
+
+ return adapted;
+ }
+
+ private Object adaptBundle(IFile file) {
+ Object adapted = null;
+ IProject project = file.getProject();
+ try {
+ if ( SigilCore.hasProjectNature( project ) ) {
+ ISigilProjectModel sigil = SigilCore.create( project );
+ ISigilBundle bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
+ bundle.setParent( sigil );
+ adapted = bundle;
+ }
+ }
+ catch ( CoreException e ) {
+ SigilCore.error( "Failed to construct bundle", e );
+ } catch (ModelElementFactoryException e) {
+ SigilCore.error( "Failed to construct bundle", e );
+ }
+
+ return adapted;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ @SuppressWarnings("unchecked")
+ public Class[] getAdapterList() {
+ return types;
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/ProjectAdaptorFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/ProjectAdaptorFactory.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/ProjectAdaptorFactory.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/adapter/ProjectAdaptorFactory.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.adapter;
+
+import org.cauldron.sigil.SigilCore;
+import org.cauldron.sigil.model.project.ISigilProjectModel;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdapterFactory;
+
+/**
+ * @author savage
+ *
+ */
+public class ProjectAdaptorFactory implements IAdapterFactory {
+
+ private Class<?>[] types = new Class<?>[] { ISigilProjectModel.class };
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public Object getAdapter( Object adaptableObject, Class adapterType ) {
+ Object adapted = null;
+
+ IProject project = (IProject) adaptableObject;
+
+ if ( ISigilProjectModel.class.equals( adapterType ) ) {
+ adapted = adaptProject(project);
+ }
+
+ return adapted;
+ }
+
+ private Object adaptProject(IProject project) {
+ try {
+ if ( SigilCore.isSigilProject(project) ) {
+ return SigilCore.create(project);
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ @SuppressWarnings("unchecked")
+ public Class[] getAdapterList() {
+ return types;
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/BuildConsole.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/BuildConsole.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/BuildConsole.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/BuildConsole.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.builders;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+public class BuildConsole extends MessageConsole {
+
+ private static final ImageDescriptor imageDescriptor = null;
+ private MessageConsoleStream stream;
+
+ public BuildConsole() {
+ super("Sigil Build", imageDescriptor, true);
+ }
+
+ public synchronized MessageConsoleStream getMessageStream() {
+ if ( stream == null ) {
+ stream = newMessageStream();
+ }
+ return stream;
+ }
+
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/SigilIncrementalProjectBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/SigilIncrementalProjectBuilder.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/SigilIncrementalProjectBuilder.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/builders/SigilIncrementalProjectBuilder.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.builders;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.cauldron.bld.bnd.BundleBuilder;
+import org.cauldron.bld.config.IBldProject;
+import org.cauldron.sigil.SigilCore;
+import org.cauldron.sigil.model.project.ISigilProjectModel;
+import org.cauldron.sigil.model.util.JavaHelper;
+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.IWorkspaceRoot;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+public class SigilIncrementalProjectBuilder extends IncrementalProjectBuilder {
+
+ @Override
+ protected IProject[] build(int kind, @SuppressWarnings("unchecked")Map args, IProgressMonitor monitor)
+ throws CoreException {
+ IProject project = getProject();
+
+ if ( checkOk( project ) ) {
+ switch ( kind ) {
+ case CLEAN_BUILD:
+ case FULL_BUILD:
+ fullBuild( project, monitor );
+ break;
+ case AUTO_BUILD:
+ case INCREMENTAL_BUILD:
+ autoBuild( project, monitor );
+ break;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param install
+ * @param project
+ * @param monitor
+ * @throws CoreException
+ */
+ private void autoBuild(IProject project,
+ IProgressMonitor monitor) throws CoreException {
+ IResourceDelta delta = getDelta(project);
+ final boolean[] changed = new boolean[1];
+ ISigilProjectModel sigil = SigilCore.create(project);
+ final IPath bldRoot = sigil.findBundleLocation().removeLastSegments(1);
+
+ delta.accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ if ( !changed[0] ) {
+ IResource res = delta.getResource();
+ if ( res.getType() == IResource.FILE ) {
+ changed[0] = !bldRoot.isPrefixOf(res.getLocation());
+ }
+ }
+ return !changed[0];
+ }
+ });
+
+ if ( changed[0] ) {
+ doBuild(project, monitor);
+ }
+ }
+
+ /**
+ * @param install
+ * @param project
+ * @param monitor
+ * @throws CoreException
+ */
+ private void fullBuild(IProject project,
+ IProgressMonitor monitor) throws CoreException {
+ doBuild(project, monitor);
+ }
+
+ private boolean checkOk(IProject project) throws CoreException {
+ IMarker[] markers = project.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
+
+ for ( IMarker m : markers ) {
+ Integer s = (Integer) m.getAttribute(IMarker.SEVERITY);
+ if ( s != null && s.equals( IMarker.SEVERITY_ERROR ) ) {
+ SigilCore.log( "Skipping " + project.getName() + " build due to unresolved errors" );
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private void doBuild(IProject project, IProgressMonitor monitor ) throws CoreException {
+ ISigilProjectModel sigil = SigilCore.create(project);
+ IBldProject bld = sigil.getBldProject();
+
+ File[] classpath = buildClasspath(sigil, monitor);
+
+ String destPattern = buildDestPattern(sigil);
+
+ Properties env = new Properties();
+
+ BundleBuilder bb = new BundleBuilder(bld, classpath, destPattern, env);
+
+ for (IBldProject.IBldBundle bundle : bld.getBundles()) {
+ String id = bundle.getId();
+ loginfo("creating bundle: " + id);
+ int nWarn = 0;
+ int nErr = 0;
+ String msg = "";
+
+ try {
+ boolean modified = bb.createBundle(bundle, false, new BundleBuilder.Log() {
+ public void warn(String msg) {
+ logwarn(msg);
+ }
+ public void verbose(String msg) {
+ loginfo(msg);
+ }
+ });
+ nWarn = bb.warnings().size();
+ if (!modified) {
+ msg = " (not modified)";
+ }
+ } catch (Exception e) {
+ List<String> errors = bb.errors();
+ if (errors != null) {
+ nErr = errors.size();
+ for (String err : errors) {
+ logerror(err);
+ }
+ }
+ throw SigilCore.newCoreException("Failed to create: " + id + ": " + e, e);
+ } finally {
+ loginfo(id + ": " + count(nErr, "error") + ", " + count(nWarn, "warning") + msg);
+ }
+ }
+ }
+
+ private static void loginfo(String message) {
+ BuildConsole console = findConsole();
+ MessageConsoleStream stream = console.getMessageStream();
+ stream.println("INFO: " + message);
+ }
+
+ private static void logwarn(String message) {
+ BuildConsole console = findConsole();
+ MessageConsoleStream stream = console.getMessageStream();
+ stream.println("WARN: " + message);
+ }
+
+ private static void logerror(String message) {
+ BuildConsole console = findConsole();
+ MessageConsoleStream stream = console.getMessageStream();
+ stream.println("ERROR: " + message);
+ }
+
+ private static BuildConsole findConsole() {
+ BuildConsole console = null;
+
+ IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
+
+ for ( IConsole c : manager.getConsoles() ) {
+ if ( c instanceof BuildConsole ) {
+ console = (BuildConsole) c;
+ break;
+ }
+ }
+
+ if ( console == null ) {
+ console = new BuildConsole();
+ manager.addConsoles( new IConsole[] { console } );
+ }
+
+ return console;
+ }
+
+ private String buildDestPattern(ISigilProjectModel sigil) throws CoreException {
+ IPath loc = sigil.findBundleLocation().removeLastSegments(1);
+
+ loc.toFile().mkdirs();
+
+ return loc.toOSString() + File.separator + "[name].jar";
+ }
+
+ private File[] buildClasspath(ISigilProjectModel sigil, IProgressMonitor monitor) throws CoreException {
+ ArrayList<File> files = new ArrayList<File>();
+
+ buildLocalClasspath(sigil, files);
+ buildExternalClasspath(sigil, files, monitor);
+
+ return files.toArray( new File[files.size()] );
+ }
+
+ private void buildExternalClasspath(ISigilProjectModel sigil,
+ ArrayList<File> files, IProgressMonitor monitor) throws CoreException {
+ Collection<IClasspathEntry> entries = sigil.findExternalClasspath(monitor);
+ files.ensureCapacity(files.size() + entries.size());
+
+ for ( IClasspathEntry cp : entries ) {
+ convert(cp, sigil, files);
+ }
+ }
+
+ private void buildLocalClasspath(ISigilProjectModel sigil, ArrayList<File> files) throws CoreException {
+ Collection<IClasspathEntry> entries = JavaHelper.findClasspathEntries(sigil.getBundle());
+ files.ensureCapacity(files.size() + entries.size());
+ for ( IClasspathEntry cp : entries ) {
+ convert(cp, sigil, files);
+ }
+
+ if ( !sigil.getBundle().getComposites().isEmpty() ) {
+ throw new IllegalStateException("XXX-FIXME-XXX");
+ }
+ }
+
+ private void convert(IClasspathEntry cp, ISigilProjectModel sigil, ArrayList<File> files) throws CoreException {
+ switch( cp.getEntryKind() ) {
+ case IClasspathEntry.CPE_PROJECT: {
+ IProject p = findProject(cp.getPath());
+ ISigilProjectModel project = SigilCore.create(p);
+ for ( String scp : project.getBundle().getClasspathEntrys() ) {
+ IClasspathEntry jcp = project.getJavaModel().decodeClasspathEntry(scp);
+ convert( jcp, project, files );
+ }
+ break;
+ }
+ case IClasspathEntry.CPE_SOURCE : {
+ IPath path = cp.getOutputLocation() == null ? sigil.getJavaModel().getOutputLocation() : cp.getOutputLocation();
+ IFolder buildFolder = sigil.getProject().getFolder(path.removeFirstSegments(1));
+ if ( buildFolder.exists() ) {
+ files.add(buildFolder.getLocation().toFile());
+ }
+ break;
+ }
+ case IClasspathEntry.CPE_LIBRARY: {
+ IPath p = cp.getPath();
+
+ IPath ppath = sigil.getProject().getFullPath();
+
+ if ( ppath.isPrefixOf(p) ) {
+ p = sigil.getProject().getLocation().append( p.removeFirstSegments(1) );
+ }
+
+ files.add( p.toFile() );
+ break;
+ }
+ case IClasspathEntry.CPE_VARIABLE:
+ cp = JavaCore.getResolvedClasspathEntry(cp);
+ if ( cp != null ) {
+ IPath p = cp.getPath();
+ files.add( p.toFile() );
+ }
+ break;
+ }
+ }
+
+ private IProject findProject(IPath path) throws CoreException {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ for ( IProject p : root.getProjects() ) {
+ IPath projectPath = p.getFullPath();
+ if ( projectPath.equals( path ) ) {
+ return p;
+ }
+ }
+
+ throw SigilCore.newCoreException("No such project " + path, null);
+ }
+
+ private String count(int count, String msg) {
+ return count + " " + msg + (count == 1 ? "" : "s");
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/install/OSGiInstallManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/install/OSGiInstallManager.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/install/OSGiInstallManager.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/install/OSGiInstallManager.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.install;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.cauldron.sigil.SigilCore;
+import org.cauldron.sigil.install.IOSGiInstall;
+import org.cauldron.sigil.install.IOSGiInstallBuilder;
+import org.cauldron.sigil.install.IOSGiInstallManager;
+import org.cauldron.sigil.install.IOSGiInstallType;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialogWithToggle;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+
+public class OSGiInstallManager implements IOSGiInstallManager, IPropertyChangeListener {
+ private static final int NORMAL_PRIORITY = 0;
+
+ private LinkedList<IOSGiInstallBuilder> builders = new LinkedList<IOSGiInstallBuilder>();
+
+ private HashMap<IPath, IOSGiInstall> pathToinstall = new HashMap<IPath, IOSGiInstall>();
+ private HashMap<String, IOSGiInstall> idToInstall = new HashMap<String, IOSGiInstall>();
+
+ private String defaultId;
+
+ private boolean initialised;
+
+ public IOSGiInstall findInstall(String id) {
+ init();
+ return idToInstall.get(id);
+ }
+
+ public String[] getInstallIDs() {
+ init();
+ return idToInstall.keySet().toArray( new String[idToInstall.size()] );
+ }
+
+ public IOSGiInstall[] getInstalls() {
+ init();
+ return idToInstall.values().toArray( new IOSGiInstall[idToInstall.size()] );
+ }
+
+ public IOSGiInstall getDefaultInstall() {
+ init();
+ return findInstall(defaultId);
+ }
+
+ public IOSGiInstallType findInstallType(String location) {
+ IOSGiInstallType type = null;
+
+ try {
+ IOSGiInstall install = buildInstall("tmp", new Path( location ) );
+ type = install == null ? null : install.getType();
+ } catch (CoreException e) {
+ SigilCore.error( "Failed to build install", e);
+ }
+
+ return type;
+ }
+
+ public void propertyChange(PropertyChangeEvent event) {
+ synchronized( this ) {
+ if ( event.getProperty().equals(SigilCore.OSGI_INSTALLS) ) {
+ clearInstalls();
+ String val = (String) event.getNewValue();
+ addInstalls(val);
+ }
+ else if ( event.getProperty().equals( SigilCore.OSGI_DEFAULT_INSTALL_ID ) ) {
+ defaultId = (String) event.getNewValue();
+ }
+ }
+ }
+
+ private void init() {
+ boolean show = false;
+
+ IPreferenceStore prefs = getPreferenceStore();
+
+ synchronized( this ) {
+ if ( !initialised ) {
+ initialised = true;
+
+ prefs.addPropertyChangeListener(this);
+
+ String val = prefs.getString(SigilCore.OSGI_INSTALLS);
+
+ boolean noAsk = prefs.getBoolean(SigilCore.PREFERENCES_NOASK_OSGI_INSTALL);
+ if(val == null || val.trim().length() == 0) {
+ show = !noAsk;
+ }
+ else {
+ addInstalls(val);
+ defaultId = prefs.getString(SigilCore.OSGI_DEFAULT_INSTALL_ID);
+ }
+ }
+ }
+
+ if ( show ) {
+ showInstallPrefs(prefs);
+ }
+ }
+
+ private void addInstalls(String prop) {
+ if ( prop != null && prop.trim().length() > 0 ) {
+ IPreferenceStore prefs = getPreferenceStore();
+
+ for (String id : prop.split(",")) {
+ String path = prefs.getString( SigilCore.OSGI_INSTALL_PREFIX + id );
+ addInstall(id, new Path( path ) );
+ }
+ }
+ }
+
+ private IPreferenceStore getPreferenceStore() {
+ return SigilCore.getDefault().getPreferenceStore();
+ }
+
+ private void showInstallPrefs(final IPreferenceStore prefs) {
+ Runnable r = new Runnable() {
+ public void run() {
+ MessageDialogWithToggle questionDialog = MessageDialogWithToggle.openYesNoQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Sigil Configuration", "Missing OSGi installation. Open preferences to configure it now?", "Do not show this message again", false, null, null);
+ prefs.setValue(SigilCore.PREFERENCES_NOASK_OSGI_INSTALL, questionDialog.getToggleState());
+ if(questionDialog.getReturnCode() == IDialogConstants.YES_ID) {
+ PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(null, SigilCore.OSGI_INSTALLS_PREFERENCES_ID, null, null);
+ dialog.open();
+ }
+ }
+ };
+ Display d = Display.getCurrent();
+ if ( d == null ) {
+ d = Display.getDefault();
+ d.asyncExec(r);
+ }
+ else {
+ d.syncExec(r);
+ }
+ }
+
+ private IOSGiInstall addInstall(String id, IPath path) {
+ IOSGiInstall install = pathToinstall.get(path);
+
+ if ( install == null ) {
+ try {
+ install = buildInstall(id, path);
+ if ( install != null ) {
+ pathToinstall.put( path, install );
+ idToInstall.put( install.getId(), install );
+ }
+ }
+ catch (CoreException e) {
+ SigilCore.error( "Failed to build install for " + path, e);
+ }
+ }
+
+ return install;
+ }
+
+ private IOSGiInstall buildInstall(String id, IPath path) throws CoreException {
+ initBuilders();
+ IOSGiInstall install = null;
+
+ for ( IOSGiInstallBuilder b : builders ) {
+ install = b.build(id, path);
+
+ if ( install != null ) {
+ break;
+ }
+ }
+
+ return install;
+ }
+
+ private void clearInstalls() {
+ idToInstall.clear();
+ pathToinstall.clear();
+ }
+
+ private void initBuilders() {
+ synchronized( builders ) {
+ if ( builders.isEmpty() ) {
+ final HashMap<IOSGiInstallBuilder, Integer> tmp = new HashMap<IOSGiInstallBuilder, Integer>();
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint p = registry.getExtensionPoint(SigilCore.INSTALL_BUILDER_EXTENSION_POINT_ID);
+ for ( IExtension e : p.getExtensions() ) {
+ for ( IConfigurationElement c : e.getConfigurationElements() ) {
+ createBuilderFromElement(c, tmp);
+ }
+ }
+
+ builders = new LinkedList<IOSGiInstallBuilder>(tmp.keySet());
+ Collections.sort(builders, new Comparator<IOSGiInstallBuilder>() {
+ public int compare(IOSGiInstallBuilder o1, IOSGiInstallBuilder o2) {
+ int p1 = tmp.get(o1);
+ int p2 = tmp.get(o2);
+
+ if ( p1 == p2 ) {
+ return 0;
+ }
+ else if ( p1 > p2 ) {
+ return -1;
+ }
+ else {
+ return 1;
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private void createBuilderFromElement(IConfigurationElement c, Map<IOSGiInstallBuilder, Integer> builder) {
+ try {
+ IOSGiInstallBuilder b = (IOSGiInstallBuilder) c.createExecutableExtension("class");
+ int priority = parsePriority( c );
+ builder.put(b, priority);
+ } catch (CoreException e) {
+ SigilCore.error("Failed to create builder", e);
+ }
+ }
+
+ private int parsePriority(IConfigurationElement c) {
+ String str = c.getAttribute("priority");
+
+ if ( str == null ) {
+ return NORMAL_PRIORITY;
+ }
+ else {
+ return Integer.parseInt(str);
+ }
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilModelRoot.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilModelRoot.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilModelRoot.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilModelRoot.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.model.project;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.cauldron.sigil.SigilCore;
+import org.cauldron.sigil.model.IModelElement;
+import org.cauldron.sigil.model.eclipse.ILibrary;
+import org.cauldron.sigil.model.eclipse.ILibraryImport;
+import org.cauldron.sigil.model.eclipse.ISigilBundle;
+import org.cauldron.sigil.model.osgi.IPackageExport;
+import org.cauldron.sigil.model.osgi.IPackageImport;
+import org.cauldron.sigil.model.osgi.IRequiredBundle;
+import org.cauldron.sigil.model.project.ISigilModelRoot;
+import org.cauldron.sigil.model.project.ISigilProjectModel;
+import org.cauldron.sigil.repository.IBundleResolver;
+import org.cauldron.sigil.repository.IResolution;
+import org.cauldron.sigil.repository.ResolutionConfig;
+import org.cauldron.sigil.repository.ResolutionException;
+import org.cauldron.sigil.repository.ResolutionMonitorAdapter;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class SigilModelRoot implements ISigilModelRoot {
+ public List<ISigilProjectModel> getProjects() {
+ IProject[] all = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ ArrayList<ISigilProjectModel> projects = new ArrayList<ISigilProjectModel>(all.length);
+ for (IProject p : all) {
+ try {
+ if (p.isOpen() && p.hasNature(SigilCore.NATURE_ID)) {
+ ISigilProjectModel n = SigilCore.create(p);
+ projects.add(n);
+ }
+ } catch (CoreException e) {
+ SigilCore.error("Failed to build model element", e);
+ }
+ }
+
+ return projects;
+ }
+
+ public Collection<ISigilProjectModel> resolveDependentProjects(
+ ISigilProjectModel sigil, IProgressMonitor monitor) {
+ HashSet<ISigilProjectModel> dependents = new HashSet<ISigilProjectModel>();
+
+ for (ISigilProjectModel n : getProjects()) {
+ if (!sigil.equals(n)) {
+ for (IPackageExport pe : sigil.getBundle().getBundleInfo().getExports()) {
+ for (IPackageImport i : n.getBundle().getBundleInfo()
+ .getImports()) {
+ if (pe.getPackageName().equals(i.getPackageName())
+ && i.getVersions().contains(pe.getVersion())) {
+ dependents.add(n);
+ }
+ }
+
+ for (ILibraryImport l : n.getBundle().getBundleInfo().getLibraryImports()) {
+ ILibrary lib = SigilCore.getRepositoryManager(sigil).resolveLibrary(l);
+
+ if (lib != null) {
+ for (IPackageImport i : lib.getImports()) {
+ if (pe.getPackageName().equals(
+ i.getPackageName())
+ && i.getVersions().contains(
+ pe.getVersion())) {
+ dependents.add(n);
+ }
+ }
+ } else {
+ SigilCore.error("No library found for " + l);
+ }
+ }
+ }
+
+ for (IRequiredBundle r : n.getBundle().getBundleInfo().getRequiredBundles()) {
+ if (sigil.getSymbolicName().equals(r.getSymbolicName())
+ && r.getVersions().contains(sigil.getVersion())) {
+ dependents.add(n);
+ }
+ }
+ }
+ }
+
+ return dependents;
+ }
+
+ public Collection<ISigilBundle> resolveBundles(ISigilProjectModel sigil, IModelElement element, boolean includeOptional, IProgressMonitor monitor) throws CoreException {
+ int options = ResolutionConfig.INCLUDE_DEPENDENTS;
+ if ( includeOptional ) {
+ options |= ResolutionConfig.INCLUDE_OPTIONAL;
+ }
+
+ ResolutionConfig config = new ResolutionConfig(options);
+ try {
+ IBundleResolver resolver = SigilCore.getRepositoryManager(sigil).getBundleResolver();
+ IResolution resolution = resolver.resolve(element, config, new ResolutionMonitorAdapter(monitor));
+ resolution.synchronize(monitor);
+ return resolution.getBundles();
+ } catch (ResolutionException e) {
+ throw SigilCore.newCoreException(e.getMessage(), e);
+ }
+ }
+}
Added: felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilProject.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilProject.java?rev=793581&view=auto
==============================================================================
--- felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilProject.java (added)
+++ felix/trunk/sigil/org.cauldron.sigil.core/src/org/cauldron/sigil/internal/model/project/SigilProject.java Mon Jul 13 13:25:46 2009
@@ -0,0 +1,460 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.cauldron.sigil.internal.model.project;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.cauldron.bld.config.BldFactory;
+import org.cauldron.bld.config.IBldProject;
+import org.cauldron.sigil.SigilCore;
+import org.cauldron.sigil.job.ThreadProgressMonitor;
+import org.cauldron.sigil.model.AbstractCompoundModelElement;
+import org.cauldron.sigil.model.IModelElement;
+import org.cauldron.sigil.model.IModelWalker;
+import org.cauldron.sigil.model.ModelElementFactory;
+import org.cauldron.sigil.model.eclipse.ISigilBundle;
+import org.cauldron.sigil.model.osgi.IBundleModelElement;
+import org.cauldron.sigil.model.osgi.IPackageExport;
+import org.cauldron.sigil.model.osgi.IPackageImport;
+import org.cauldron.sigil.model.osgi.IRequiredBundle;
+import org.cauldron.sigil.model.project.ISigilProjectModel;
+import org.cauldron.sigil.model.util.JavaHelper;
+import org.cauldron.sigil.repository.IRepositoryManager;
+import org.cauldron.sigil.repository.IResolution;
+import org.cauldron.sigil.repository.ResolutionConfig;
+import org.cauldron.sigil.repository.ResolutionException;
+import org.cauldron.sigil.repository.ResolutionMonitorAdapter;
+import org.eclipse.core.resources.IFile;
+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.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.osgi.framework.Version;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * @author dave
+ *
+ */
+public class SigilProject extends AbstractCompoundModelElement implements ISigilProjectModel {
+
+ private static final long serialVersionUID = 1L;
+
+ private IFile bldProjectFile;
+ private IProject project;
+ private IBldProject bldProject;
+
+ private ISigilBundle bundle;
+
+ private IEclipsePreferences preferences;
+
+ public SigilProject() {
+ super( "Sigil Project" );
+ }
+
+ public SigilProject(IProject project) throws CoreException {
+ this();
+ this.project = project;
+ bldProjectFile = project.getFile( new Path( SigilCore.SIGIL_PROJECT_FILE) );
+ }
+
+ // to aid testing conversion between project file formats
+ public InputStream saveBundle(ISigilBundle b) throws CoreException {
+ setBundle(b);
+ // FIXME causes NPE in JavaHelper
+ // calculateUses();
+ return buildContents();
+ }
+
+ public void save(IProgressMonitor monitor) throws CoreException {
+ SubMonitor progress = SubMonitor.convert(monitor, 100);
+
+ calculateUses();
+
+ bldProjectFile.setContents( buildContents(), IFile.KEEP_HISTORY, progress.newChild(10));
+
+ IRepositoryManager manager = SigilCore.getRepositoryManager(this);
+ ResolutionConfig config = new ResolutionConfig(ResolutionConfig.INCLUDE_OPTIONAL);
+
+ try {
+ IResolution res = manager.getBundleResolver().resolve(this, config, new ResolutionMonitorAdapter(progress.newChild(10)));
+ if ( !res.isSynchronized() ) {
+ res.synchronize(progress.newChild(60));
+ }
+ } catch (ResolutionException e) {
+ throw SigilCore.newCoreException("Failed to synchronize dependencies", e);
+ }
+
+
+ progress.setWorkRemaining(40);
+
+ SigilCore.rebuildBundleDependencies( this, progress.newChild(20) );
+ }
+
+ /**
+ * Returns the project custom preference pool.
+ * Project preferences may include custom encoding.
+ * @return IEclipsePreferences or <code>null</code> if the project
+ * does not have a java nature.
+ */
+ public Preferences getPreferences(){
+ synchronized(this) {
+ if ( preferences == null ) {
+ preferences = loadPreferences();
+ }
+
+ return preferences;
+ }
+ }
+
+
+ /**
+ * @return
+ */
+ private synchronized IEclipsePreferences loadPreferences() {
+ IScopeContext context = new ProjectScope(getProject());
+ final IEclipsePreferences eclipsePreferences = context.getNode(SigilCore.PLUGIN_ID);
+
+ // Listen to node removal from parent in order to reset cache
+ INodeChangeListener nodeListener = new IEclipsePreferences.INodeChangeListener() {
+ public void added(IEclipsePreferences.NodeChangeEvent event) {
+ // do nothing
+ }
+
+ public void removed(IEclipsePreferences.NodeChangeEvent event) {
+ if (event.getChild() == eclipsePreferences) {
+ synchronized( SigilProject.this ) {
+ preferences = null;
+ }
+ ((IEclipsePreferences) eclipsePreferences.parent()).removeNodeChangeListener(this);
+ }
+ }
+ };
+
+ ((IEclipsePreferences) eclipsePreferences.parent()).addNodeChangeListener(nodeListener);
+
+ return eclipsePreferences;
+ }
+
+ public Collection<IClasspathEntry> findExternalClasspath(IProgressMonitor monitor) throws CoreException {
+ return JavaHelper.resolveClasspathEntrys(this, monitor);
+ }
+
+ private void calculateUses() {
+ visit( new IModelWalker() {
+ public boolean visit(IModelElement element) {
+ if ( element instanceof IPackageExport ) {
+ IPackageExport pe = (IPackageExport) element;
+ try {
+ pe.setUses( Arrays.asList( JavaHelper.findUses(pe.getPackageName(), SigilProject.this ) ) );
+ } catch (CoreException e) {
+ SigilCore.error( "Failed to build uses list for " + pe, e );
+ }
+ }
+ return true;
+ }
+ } );
+ }
+
+ public Collection<ISigilProjectModel> findDependentProjects(IProgressMonitor monitor) {
+ return SigilCore.getRoot().resolveDependentProjects(this, monitor);
+ }
+
+ public Version getVersion() {
+ ISigilBundle bundle = getBundle();
+ return bundle == null ? null : bundle.getBundleInfo() == null ? null : bundle.getBundleInfo().getVersion();
+ }
+
+ public String getSymbolicName() {
+ ISigilBundle bundle = getBundle();
+ return bundle == null ? null : bundle.getBundleInfo() == null ? null : bundle.getBundleInfo().getSymbolicName();
+ }
+
+ public IProject getProject() {
+ return project;
+ }
+
+ public ISigilBundle getBundle() {
+ if ( bundle == null && bldProjectFile != null ) {
+ synchronized( bldProjectFile ) {
+ try {
+ if ( bldProjectFile.getLocation().toFile().exists() ) {
+ bundle = parseContents(bldProjectFile);
+ }
+ else {
+ bundle = setupDefaults();
+ NullProgressMonitor npm = new NullProgressMonitor();
+ bldProjectFile.create( buildContents(), true /* force */, npm);
+ project.refreshLocal( IResource.DEPTH_INFINITE, npm );
+ }
+ } catch (CoreException e) {
+ SigilCore.error( "Failed to build bundle", e);
+ }
+ }
+ }
+ return bundle;
+ }
+
+ public void setBundle(ISigilBundle bundle) {
+ this.bundle = bundle;
+ }
+
+ public IJavaProject getJavaModel() {
+ return JavaCore.create( project );
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( obj == null ) return false;
+
+ if ( obj == this ) return true;
+
+ try {
+ SigilProject p = (SigilProject) obj;
+ return getSymbolicName().equals( p.getSymbolicName() ) && (getVersion() == null ? p.getVersion() == null : getVersion().equals( p.getVersion() ));
+ }
+ catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ // TODO Auto-generated method stub
+ return super.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "SigilProject[" + getSymbolicName() + ":" + getVersion() + "]";
+ }
+
+ public void resetClasspath(IProgressMonitor monitor) throws CoreException {
+ Path containerPath = new Path( SigilCore.CLASSPATH_CONTAINER_PATH );
+ IJavaProject java = getJavaModel();
+ ClasspathContainerInitializer init = JavaCore.getClasspathContainerInitializer(SigilCore.CLASSPATH_CONTAINER_PATH);
+ ThreadProgressMonitor.setProgressMonitor(monitor);
+ try {
+ init.requestClasspathContainerUpdate(containerPath, java, null);
+ }
+ finally {
+ ThreadProgressMonitor.setProgressMonitor(null);
+ }
+ }
+
+ public IPath findBundleLocation() throws CoreException {
+ IPath p = getBundle().getLocation();
+ if ( p == null ) {
+ p = SigilCore.getDefault().findDefaultBundleLocation(this);
+ }
+ return p;
+ }
+
+ public IModelElement findImport(final String packageName, final IProgressMonitor monitor) {
+ final IModelElement[] found = new IModelElement[1];
+
+ visit( new IModelWalker() {
+ public boolean visit(IModelElement element) {
+ if ( element instanceof IPackageImport ) {
+ IPackageImport pi = (IPackageImport) element;
+ if ( pi.getPackageName().equals( packageName ) ) {
+ found[0] = pi;
+ return false;
+ }
+ }
+ else if ( element instanceof IRequiredBundle ) {
+ IRequiredBundle rb = (IRequiredBundle) element;
+ try {
+ IRepositoryManager manager = SigilCore.getRepositoryManager(SigilProject.this);
+ ResolutionConfig config = new ResolutionConfig(ResolutionConfig.IGNORE_ERRORS);
+ IResolution res = manager.getBundleResolver().resolve(rb, config, new ResolutionMonitorAdapter(monitor));
+ ISigilBundle b = res.getProvider(rb);
+ for ( IPackageExport pe : b.getBundleInfo().getExports() ) {
+ if ( pe.getPackageName().equals( packageName ) ) {
+ found[0] = rb;
+ return false;
+ }
+ }
+ } catch (ResolutionException e) {
+ SigilCore.error( "Failed to resolve " + rb, e );
+ }
+ }
+ return true;
+ }
+
+ });
+
+ return found[0];
+ }
+
+ public boolean isInClasspath(String packageName, IProgressMonitor monitor) throws CoreException {
+ if ( findImport(packageName, monitor) != null ) {
+ return true;
+ }
+
+ for ( String path : getBundle().getClasspathEntrys() ) {
+ IClasspathEntry cp = getJavaModel().decodeClasspathEntry(path);
+ for ( IPackageFragmentRoot root : getJavaModel().findPackageFragmentRoots(cp) ) {
+ if ( findPackage( packageName, root ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean isInClasspath(ISigilBundle bundle) {
+ for ( String path : getBundle().getClasspathEntrys() ) {
+ IClasspathEntry cp = getJavaModel().decodeClasspathEntry(path);
+ switch ( cp.getEntryKind() ) {
+ case IClasspathEntry.CPE_PROJECT:
+ ISigilProjectModel p = bundle.getAncestor(ISigilProjectModel.class);
+ return p != null && cp.getPath().equals(p.getProject().getFullPath());
+ case IClasspathEntry.CPE_LIBRARY:
+ return cp.getPath().equals(bundle.getLocation());
+ }
+ }
+
+ return false;
+ }
+
+ private boolean findPackage(String packageName, IParent parent) throws JavaModelException {
+ for ( IJavaElement e : parent.getChildren() ) {
+ if ( e.getElementType() == IJavaElement.PACKAGE_FRAGMENT ) {
+ return e.getElementName().equals( packageName );
+ }
+
+ if ( e instanceof IParent ) {
+ if ( findPackage(packageName, (IParent) e) ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private ISigilBundle setupDefaults() {
+ ISigilBundle bundle = ModelElementFactory.getInstance().newModelElement(ISigilBundle.class);
+ IBundleModelElement info = ModelElementFactory.getInstance().newModelElement( IBundleModelElement.class );
+ info.setSymbolicName(project.getName());
+ bundle.setBundleInfo(info);
+ bundle.setParent(this);
+ return bundle;
+ }
+
+
+ private ISigilBundle parseContents(IFile projectFile) throws CoreException {
+ /*if ( !projectFile.isSynchronized(IResource.DEPTH_ONE) ) {
+ projectFile.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
+ }*/
+
+ if ( projectFile.getName().equals( SigilCore.SIGIL_PROJECT_FILE) ) {
+ return parseBldContents(projectFile.getLocationURI());
+ }
+ else {
+ throw SigilCore.newCoreException("Unexpected project file: " + projectFile.getName(), null );
+ }
+ }
+
+ private ISigilBundle parseBldContents(URI uri) throws CoreException {
+ try {
+ bldProject = BldFactory.getProject(uri, true);
+ ISigilBundle bundle = bldProject.getDefaultBundle();
+ bundle.setParent(this);
+ return bundle;
+ } catch (IOException e) {
+ throw SigilCore.newCoreException( "Failed to parse " + uri, e);
+ }
+ }
+
+ private InputStream buildContents() throws CoreException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ try {
+ if (bldProject == null) {
+ bldProject = BldFactory.newProject(bldProjectFile.getLocationURI(), null);
+ }
+ bldProject.setDefaultBundle(getBundle());
+ bldProject.saveTo(buf);
+ } catch (IOException e) {
+ throw SigilCore.newCoreException("Failed to save project file", e);
+ }
+ return new ByteArrayInputStream(buf.toByteArray());
+ }
+
+// private InputStream buildXMLContents() throws CoreException {
+// Serializer serializer = SigilCore.getDefault().getDescriptorSerializer();
+//
+// ByteArrayOutputStream buf = new ByteArrayOutputStream();
+//
+// try {
+// serializer.serialize(getBundle(), buf);
+// } catch (SerializingException e) {
+// throw SigilCore.newCoreException("Failed to serialize " + this, e);
+// }
+//
+// return new ByteArrayInputStream(buf.toByteArray());
+// }
+
+ public String getName() {
+ return getProject().getName();
+ }
+
+ public IPath findOutputLocation() throws CoreException {
+ return getProject().getLocation().append(
+ getJavaModel().getOutputLocation()
+ .removeFirstSegments(1));
+ }
+
+ public IBldProject getBldProject() throws CoreException {
+ try {
+ return BldFactory.getProject(project.getFile(IBldProject.PROJECT_FILE).getLocationURI());
+ } catch (IOException e) {
+ throw SigilCore.newCoreException("Failed to get project file: ",e);
+ }
+ }
+
+ public boolean isInBundleClasspath(IPackageFragmentRoot root) throws JavaModelException {
+ String enc = getJavaModel().encodeClasspathEntry(root.getRawClasspathEntry());
+ return getBundle().getClasspathEntrys().contains( enc.trim() );
+ }
+}