/******************************************************************************* * Copyright (c) 2004, 2006 * Thomas Hallgren, Kenneth Olwing, Mitch Sonies * Pontus Rydin, Nils Unden, Peer Torngren * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the individual * copyright holders listed above, as Initial Contributors under such license. * The text of such license is available at www.eclipse.org. *******************************************************************************/ package org.eclipse.buckminster.core.build; import java.lang.reflect.Method; import java.text.Format; import java.text.MessageFormat; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.eclipse.buckminster.core.RMContext; import org.eclipse.buckminster.core.cspec.IComponentIdentifier; import org.eclipse.buckminster.core.cspec.QualifiedDependency; import org.eclipse.buckminster.core.cspec.model.CSpec; import org.eclipse.buckminster.core.cspec.model.ComponentIdentifier; import org.eclipse.buckminster.core.metadata.MissingComponentException; import org.eclipse.buckminster.core.metadata.ModelCache; import org.eclipse.buckminster.core.metadata.WorkspaceInfo; import org.eclipse.buckminster.core.metadata.model.IModelCache; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; /** * A Builder that emits the location of all components that are contained in, or * referenced by, the current project. * * @author Thomas Hallgren */ public class LocationEmitter extends PropertiesEmitter { public static final String ARG_PURPOSE = "purpose"; //$NON-NLS-1$ public static final String ARG_FORMAT_LOCATION = "format.location"; //$NON-NLS-1$ public static final String ARG_FORMAT_ARTIFACTS = "format.artifacts"; //$NON-NLS-1$ public static final Format FORMAT_LOCATION = new MessageFormat("bm.location.{0}"); //$NON-NLS-1$ public static final Format FORMAT_LOCATION_ARTIFACT = new MessageFormat("bm.artifacts.{0}.{1}"); //$NON-NLS-1$ private static boolean stateKnown = false; private static Method getDefaultOutputFolder; public static IPath getDefaultOutputFolder(IProject project) throws CoreException { if (!isJDTPresent()) return null; try { return (IPath) getDefaultOutputFolder.invoke(null, new Object[] { project }); } catch (Exception e) { throw BuckminsterException.wrap(e); } } public static synchronized boolean isJDTPresent() { if (!stateKnown) { Bundle bundle = Platform.getBundle("org.eclipse.buckminster.jdt"); //$NON-NLS-1$ if (bundle == null) { stateKnown = true; return false; } try { Class<?> classpathEmitterClass = bundle.loadClass("org.eclipse.buckminster.jdt.internal.ClasspathEmitter"); //$NON-NLS-1$ getDefaultOutputFolder = classpathEmitterClass.getMethod("getDefaultOutputFolder", //$NON-NLS-1$ new Class[] { IProject.class }); } catch (Exception e) { } stateKnown = true; } return getDefaultOutputFolder != null; } @Override protected void addFormatters() { addFormat(ARG_FORMAT_LOCATION, FORMAT_LOCATION); addFormat(ARG_FORMAT_ARTIFACTS, FORMAT_LOCATION_ARTIFACT); } @Override protected void appendProperties() throws CoreException { try { IModelCache cache = new ModelCache(); CSpec cspec = WorkspaceInfo.getCSpec(getProject()); String attr = getArgument(ARG_PURPOSE); Set<String> attrs = attr == null ? Collections.<String> emptySet() : Collections.singleton(attr); appendComponentProperties(cspec, attrs, cache, new HashSet<ComponentIdentifier>()); } catch (MissingComponentException e) { } } private void appendComponentProperties(CSpec cspec, Set<String> attributes, IModelCache cache, HashSet<ComponentIdentifier> seenIds) throws CoreException { IComponentIdentifier cid = cspec.getComponentIdentifier(); if (seenIds.contains(cid)) return; IPath location = cspec.getComponentLocation(); String componentName = cspec.getName(); if (location.toFile().isFile()) { addProperty(ARG_FORMAT_LOCATION, new String[] { componentName }, formatPath(location.removeLastSegments(1))); addProperty(ARG_FORMAT_ARTIFACTS, new String[] { componentName, "default" }, location.lastSegment()); //$NON-NLS-1$ } else { IProject project = WorkspaceInfo.getProject(cid); if (project != null) { // If this is a java project with a default output folder, then // emitt that as a default // artifact. // IPath dfltOutput = getDefaultOutputFolder(project); if (dfltOutput != null) addProperty(ARG_FORMAT_ARTIFACTS, new String[] { componentName, "default" }, dfltOutput //$NON-NLS-1$ .toOSString()); } addProperty(ARG_FORMAT_LOCATION, new String[] { componentName }, formatPath(location)); } // Emit properties of all dependencies // cspec = cspec.prune(null, RMContext.getGlobalPropertyAdditions(), false, attributes); for (QualifiedDependency dep : cspec.getQualifiedDependencies(false)) { CSpec childSpec = cache.findCSpec(cspec, dep.getRequest()); appendComponentProperties(childSpec, dep.getAttributeNames(), cache, seenIds); } } }