interactivespaces.workbench.project.ProjectTaskContext.java Source code

Java tutorial

Introduction

Here is the source code for interactivespaces.workbench.project.ProjectTaskContext.java

Source

/*
 * Copyright (C) 2012 Google Inc.
 *
 * Licensed 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 interactivespaces.workbench.project;

import interactivespaces.configuration.Configuration;
import interactivespaces.util.io.FileSupport;
import interactivespaces.util.io.FileSupportImpl;
import interactivespaces.workbench.project.activity.type.ProjectType;
import interactivespaces.workbench.project.builder.ProjectBuilder;
import interactivespaces.workbench.project.constituent.ContentProjectConstituent;
import interactivespaces.workbench.project.constituent.ProjectConstituent;
import interactivespaces.workbench.tasks.DependencyWorkbenchTask;
import interactivespaces.workbench.tasks.WorkbenchTaskContext;
import interactivespaces.workbench.tasks.WorkbenchTaskModifiers;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import org.apache.commons.logging.Log;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A context for building and packaging activities.
 *
 * @author Keith M. Hughes
 */
public class ProjectTaskContext implements ProjectContext {

    /**
     * Where things are being built.
     */
    public static final String BUILD_DIRECTORY = "build";

    /**
     * Subdirectory of build folder which contains the staged components of the build.
     */
    public static final String BUILD_STAGING_DIRECTORY = "staging";

    /**
     * Extension for creating temp build directories.
     */
    public static final String TEMP_DIRECTORY_EXTENSION = ".dir";

    /**
     * Sub-directory in which to put temp build files.
     */
    public static final String BUILD_TEMP_DIRECTORY = "tmp";

    /**
     * The project being built.
     */
    private final Project project;

    /**
     * The task context for building.
     */
    private final WorkbenchTaskContext taskContext;

    /**
     * Files to include in the project.
     */
    private final List<File> artifactsToInclude = Lists.newArrayList();

    /**
     * Files generated by the project.
     */
    private final List<File> generatedArtifacts = Lists.newArrayList();

    /**
     * The directory where the project will be built.
     */
    private final File buildDirectory;

    /**
     * The staging directory for artifacts.
     */
    private final File stagingDirectory;

    /**
     * The project type of the project.
     */
    private final ProjectType projectType;

    /**
     * The collection of tasks for the project indexed by task name.
     *
     * TODO(keith): Should this be a multimap?
     */
    private final Map<String, DependencyWorkbenchTask> tasksForProject = Maps.newHashMap();

    /**
     * Project task contexts for projects which this project is dependent on.
     */
    private final Set<ProjectTaskContext> dynamicProjectDependencyContexts = Sets.newHashSet();

    /**
     * The name of the current task being run, can be {@code null}.
     */
    private String currentTaskName;

    /**
     * Collection of dest to src file mappings, constructed during the build process.
     */
    private final Map<File, File> sourceMap = Maps.newHashMap();

    /**
     * The file support to use.
     */
    private FileSupport fileSupport = FileSupportImpl.INSTANCE;

    /**
     * Construct a new build context.
     *
     * @param projectType
     *          the type of the project
     * @param project
     *          project object
     * @param taskContext
     *          workbench instance
     */
    public ProjectTaskContext(ProjectType projectType, Project project, WorkbenchTaskContext taskContext) {
        this.projectType = projectType;
        this.project = project;
        this.taskContext = taskContext;

        buildDirectory = fileSupport.newFile(project.getBaseDirectory(), BUILD_DIRECTORY);
        stagingDirectory = fileSupport.newFile(buildDirectory, BUILD_STAGING_DIRECTORY);

        prepareProjectConfiguration();
    }

    @Override
    public <T extends Project> T getProject() {
        return (T) project;
    }

    @Override
    public WorkbenchTaskContext getWorkbenchTaskContext() {
        return taskContext;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T extends ProjectType> T getProjectType() {
        return (T) projectType;
    }

    /**
     * Add anything needed to the project configuration.
     */
    private void prepareProjectConfiguration() {
        Configuration configuration = project.getConfiguration();
        configuration.setValue(ProjectBuilder.CONFIGURATION_PROPERTY_PROJECT_HOME,
                project.getBaseDirectory().getAbsolutePath());
        configuration.setValue(ProjectBuilder.CONFIGURATION_PROPERTY_PROJECT_GENERATED_RESOURCE,
                fileSupport.newFile(buildDirectory, ProjectType.GENERATED_SOURCE_ROOT).getAbsolutePath());
    }

    @Override
    public File getProjectTarget(File rootDirectory, String target) {
        String targetPath = project.getConfiguration().evaluate(target);
        File targetFile = new File(targetPath);
        if (targetFile.isAbsolute()) {
            return targetFile;
        }
        return new File(rootDirectory, targetPath);
    }

    @Override
    public Map<File, File> getResourceSourceMap() {
        return sourceMap;
    }

    /**
     * Get the root build directory.
     *
     * @return the root of the build directory
     */
    public File getBuildDirectory() {
        return buildDirectory;
    }

    /**
     * Get the root staging directory.
     *
     * @return the root of the staging directory
     */
    public File getStagingDirectory() {
        return stagingDirectory;
    }

    /**
     * Get a unique temporary build directory.
     *
     * @return a temporary build directory
     */
    public File getTempBuildDirectory() {
        File tempDirectory = new File(buildDirectory, BUILD_TEMP_DIRECTORY);
        fileSupport.mkdir(tempDirectory);
        File tempFile = fileSupport.createTempFile(tempDirectory);
        return new File(tempDirectory, tempFile.getName() + TEMP_DIRECTORY_EXTENSION);
    }

    /**
     * Add a new artifact to go in the file.
     *
     * @param artifact
     *          artifact to add to context
     */
    public void addArtifactToInclude(File artifact) {
        artifactsToInclude.add(artifact);
    }

    /**
     * Get the list of artifacts to add to the project.
     *
     * @return the list of artifacts to add to the project
     */
    public List<File> getArtifactsToInclude() {
        return artifactsToInclude;
    }

    /**
     * Add a new generated artifact.
     *
     * @param artifact
     *          the generated artifact
     */
    public void addGeneratedArtifact(File artifact) {
        generatedArtifacts.add(artifact);
    }

    /**
     * Get the list of artifacts generated.
     *
     * <p>
     * Only valid after a build.
     *
     * @return the list of generated artifacts
     */
    public List<File> getGeneratedArtifacts() {
        return generatedArtifacts;
    }

    /**
     * Add in tasks that has been created for this project.
     *
     * <p>
     * The tasks will also be added to the workbench task context.
     *
     * @param tasks
     *          the tasks to add
     *
     * @return this context
     */
    public ProjectTaskContext addProjectTasks(DependencyWorkbenchTask... tasks) {
        if (tasks != null) {
            for (DependencyWorkbenchTask task : tasks) {
                if (tasksForProject.put(task.getName(), task) != null) {
                    getLog().warn(String.format("There was a previous task with name %s which has been dropped",
                            task.getName()));
                }
            }

            taskContext.addTasks(tasks);
        }

        return this;
    }

    /**
     * Modify the project tasks associated with this context with the provided modifiers.
     *
     * @param modifiersCollection
     *          the modifiers to be applied
     *
     * @return this context
     */
    public ProjectTaskContext modifyProjectTasks(Collection<WorkbenchTaskModifiers> modifiersCollection) {
        for (WorkbenchTaskModifiers modifiers : modifiersCollection) {
            DependencyWorkbenchTask task = tasksForProject.get(modifiers.getTaskName());
            if (task != null) {
                task.applyTaskModifiers(modifiers);
            } else {
                getLog().warn(String.format("Task modifier found for missing task %s", modifiers.getTaskName()));
            }
        }

        return this;
    }

    /**
     * Add a task context for a dynamic project dependency.
     *
     * @param dependencyTaskContext
     *          the dependency task context to add
     *
     * @return this context
     */
    public ProjectTaskContext addDynamicProjectDependencyContext(ProjectTaskContext dependencyTaskContext) {
        dynamicProjectDependencyContexts.add(dependencyTaskContext);

        return this;
    }

    /**
     * Add a task context for a dynamic project dependency.
     *
     * @param dependencyTaskContexts
     *          the dependency task contexts to add
     *
     * @return this context
     */
    public ProjectTaskContext addDynamicProjectDependencyContexts(
            Collection<ProjectTaskContext> dependencyTaskContexts) {
        dynamicProjectDependencyContexts.addAll(dependencyTaskContexts);

        return this;
    }

    /**
     * Get the project task contexts for all dynamic project dependencies.
     *
     * @return the dependency project task contexts
     */
    public Set<ProjectTaskContext> getDynamicProjectDependencyContexts() {
        return dynamicProjectDependencyContexts;
    }

    /**
     * Process the extra constituents for the project.
     */
    public void processExtraConstituents() {
        List<ProjectConstituent> constituents = project.getExtraConstituents();
        if (constituents != null) {
            for (ProjectConstituent constituent : constituents) {
                constituent.processConstituent(project, this);
            }
        }
    }

    /**
     * Process any generated resources for the project.
     *
     * @param stagingDirectory
     *          the directory where the processed content should go
     */
    public void processGeneratedResources(File stagingDirectory) {
        File generatedResources = fileSupport.newFile(getBuildDirectory(),
                ProjectType.SOURCE_GENERATED_MAIN_RESOURCES);
        if (fileSupport.isDirectory(generatedResources)) {
            fileSupport.copyDirectory(generatedResources, stagingDirectory, true);
        }
    }

    /**
     * Process the needed resources for the project.
     *
     * @param stagingDirectory
     *          the directory where the processed content should go
     */
    public void processResources(File stagingDirectory) {
        processContentConstituents(project.getResources(), stagingDirectory);
    }

    /**
     * Process the needed sources for the project.
     *
     * @param stagingDirectory
     *          the directory where the processed content should go
     */
    public void processSources(File stagingDirectory) {
        processContentConstituents(project.getSources(), stagingDirectory);
    }

    /**
     * Process the list of constituents for the project.
     *
     * @param constituents
     *          constituents to process
     * @param stagingDirectory
     *          the directory where the processed content should go
     */
    private void processContentConstituents(List<ContentProjectConstituent> constituents, File stagingDirectory) {
        if (constituents == null) {
            return;
        }

        for (ContentProjectConstituent constituent : constituents) {
            constituent.processConstituent(project, stagingDirectory, this);
        }
    }

    /**
     * Get the current task name for this context.
     *
     * <p>
     * It will be {@code null} when tasks are not running against the context.
     *
     * @return the current task name
     */
    public String getCurrentTaskName() {
        return currentTaskName;
    }

    /**
     * Set the current task name for this context.
     *
     * <p>
     * It should be {@code null} when tasks are not running against the context.
     *
     * @param currentTaskName
     *          the current task name
     */
    public void setCurrentTaskName(String currentTaskName) {
        this.currentTaskName = currentTaskName;
    }

    /**
     * Get the context log.
     *
     * @return the log
     */
    public Log getLog() {
        return getWorkbenchTaskContext().getLog();
    }
}