/* Copyright (C) 2013 Mobile Sorcery AB This program is free software; you can redistribute it and/or modify it under the terms of the Eclipse Public License v1.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for more details. You should have received a copy of the Eclipse Public License v1.0 along with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html */ package com.mobilesorcery.sdk.core.build; import java.text.MessageFormat; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import com.mobilesorcery.sdk.core.CoreMoSyncPlugin; import com.mobilesorcery.sdk.core.IBuildResult; import com.mobilesorcery.sdk.core.IBuildSession; import com.mobilesorcery.sdk.core.IBuildState; import com.mobilesorcery.sdk.core.IBuildVariant; import com.mobilesorcery.sdk.core.IFilter; import com.mobilesorcery.sdk.core.IPackager; import com.mobilesorcery.sdk.core.IProcessConsole; import com.mobilesorcery.sdk.core.IPropertyOwner; import com.mobilesorcery.sdk.core.MoSyncBuilder; import com.mobilesorcery.sdk.core.ParameterResolver; import com.mobilesorcery.sdk.core.LineReader.ILineHandler; import com.mobilesorcery.sdk.core.MoSyncProject; import com.mobilesorcery.sdk.core.Util; import com.mobilesorcery.sdk.core.security.IApplicationPermissions; import com.mobilesorcery.sdk.internal.PipeTool; import com.mobilesorcery.sdk.internal.dependencies.DependencyManager; import com.mobilesorcery.sdk.internal.dependencies.IDependencyProvider; import com.mobilesorcery.sdk.profiles.IProfile; public abstract class AbstractBuildStep implements IBuildStep { /** * A constant that build steps may use to indicate to * subsequent build steps that another set of permissions * should be used for building. * This should be added to a {@link IBuildSession}'s * properties and must be of type {@link IApplicationPermissions}. */ public static final String MODIFIED_PERMISSIONS = CoreMoSyncPlugin.PLUGIN_ID + "mod.perm"; private IProcessConsole console; private IPropertyOwner buildProperties; private IBuildState buildState; private PipeTool pipeTool; private ILineHandler defaultLineHandler; private IDependencyProvider<IResource> dependencyProvider; private String id; private String name; private ParameterResolver resolver; private IFilter<IResource> resourceFilter; public String getId() { return id; } protected void setId(String id) { this.id = id; } public String getName() { return name; } protected void setName(String name) { this.name = name; } @Override public void initConsole(IProcessConsole console) { this.console = console; } protected IProcessConsole getConsole() { return console; } @Override public void initBuildProperties(IPropertyOwner buildProperties) { this.buildProperties = buildProperties; } protected IPropertyOwner getBuildProperties() { return buildProperties; } @Override public void initBuildState(IBuildState buildState) { this.buildState = buildState; } protected IBuildState getBuildState() { return buildState; } public void initPipeTool(PipeTool pipeTool) { this.pipeTool = pipeTool; } protected PipeTool getPipeTool() { return pipeTool; } public void initDefaultLineHandler(ILineHandler defaultLineHandler) { this.defaultLineHandler = defaultLineHandler; } protected ILineHandler getDefaultLineHandler() { return defaultLineHandler; } public void initDependencyProvider(IDependencyProvider<IResource> dependencyProvider) { this.dependencyProvider = dependencyProvider; } protected IDependencyProvider<IResource> getDependencyProvider() { return dependencyProvider; } @Override public void initResourceFilter(IFilter<IResource> resourceFilter) { this.resourceFilter = resourceFilter; } protected IFilter<IResource> getResourceFilter() { return resourceFilter; } public void initParameterResolver(ParameterResolver resolver) { this.resolver = resolver; } public ParameterResolver getParameterResolver() { return resolver; } /** * The default implementation returns <code>true</code> if * the current build has no errors from previous build steps * and if this step should be added (as per {@link #shouldAdd(IBuildSession)}) */ @Override public boolean shouldBuild(MoSyncProject project, IBuildSession session, IBuildResult buildResult) { return shouldAdd(session) && buildResult.getErrors().isEmpty(); } @Override public boolean shouldAdd(IBuildSession session) { return true; } @Override public String[] getDependees() { return null; } protected Set<IProject> computeProjectDependencies(IProgressMonitor monitor, MoSyncProject mosyncProject, IBuildState buildState, IResource[] allAffectedResources) { IProject project = mosyncProject.getWrappedProject(); monitor.setTaskName(MessageFormat.format("Computing project dependencies for {0}", project.getName())); DependencyManager<IProject> projectDependencies = CoreMoSyncPlugin.getDefault().getProjectDependencyManager(ResourcesPlugin.getWorkspace()); projectDependencies.clearDependencies(project); HashSet<IProject> allProjectDependencies = new HashSet<IProject>(); Set<IResource> dependencies = buildState.getDependencyManager().getDependenciesOf(Arrays.asList(allAffectedResources)); for (IResource resourceDependency : dependencies) { if (resourceDependency.getType() != IResource.ROOT) { allProjectDependencies.add(resourceDependency.getProject()); } } // No deps on self allProjectDependencies.remove(project); if (CoreMoSyncPlugin.getDefault().isDebugging()) { CoreMoSyncPlugin .trace(MessageFormat.format("Computed project dependencies. Project {0} depends on {1}", project.getName(), allProjectDependencies)); } return allProjectDependencies; } public String toString() { return getId(); } /** * Returns {@code true} if the <b>resolved</b> output type equals * a certain value. * @see {@link #getResolvedOutputType()} * @param project * @param variant * @param outputType * @return A boolean indicating whether this is, in fact, the requested * output type. */ public boolean isOutputType(MoSyncProject project, IBuildVariant variant, String outputType) { return Util.equals(outputType, getOutputType(project, variant)); } /** * Returns the <b>resolved</b> output type to use. Does not necessarily correspond to * the project property ({@link MoSyncBuilder#OUTPUT_TYPE()}, since not all platforms * support them. * @return */ protected String getOutputType(MoSyncProject project, IBuildVariant variant) { String rawOutputType = project.getProperty(MoSyncBuilder.OUTPUT_TYPE); IProfile profile = variant.getProfile(); IPackager platform = profile.getPackager(); if (platform == null) { return rawOutputType; } else { return platform.getOutputType(project); } } }