de.ovgu.featureide.core.builder.ComposerExtensionClass.java Source code

Java tutorial

Introduction

Here is the source code for de.ovgu.featureide.core.builder.ComposerExtensionClass.java

Source

/* FeatureIDE - An IDE to support feature-oriented software development
 * Copyright (C) 2005-2012  FeatureIDE team, University of Magdeburg
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 *
 * See http://www.fosd.de/featureide/ for further information.
 */
package de.ovgu.featureide.core.builder;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Vector;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.core.JavaProject;

import de.ovgu.featureide.core.CorePlugin;
import de.ovgu.featureide.core.IFeatureProject;
import de.ovgu.featureide.core.fstmodel.preprocessor.FSTDirective;
import de.ovgu.featureide.fm.core.configuration.Configuration;
import de.ovgu.featureide.fm.core.configuration.ConfigurationWriter;

/**
 * Abstract class for FeatureIDE composer extensions with default values.
 * 
 * @author Jens Meinicke
 */
@SuppressWarnings("restriction")
public abstract class ComposerExtensionClass implements IComposerExtensionClass {

    protected static final String JAVA_NATURE = "org.eclipse.jdt.core.javanature";
    public static final IPath JRE_CONTAINER = new Path("org.eclipse.jdt.launching.JRE_CONTAINER");
    protected IFeatureProject featureProject = null;

    protected final static String[] JAVA_TEMPLATE = new String[] { "Java", "java", PACKAGE_PATTERN
            + "/**\r\n * TODO description\r\n */\r\npublic class " + CLASS_NAME_PATTERN + " {\n\n}" };

    public boolean initialize(IFeatureProject project) {

        assert (project != null) : "Invalid project given";
        featureProject = project;
        return true;
    }

    public boolean clean() {
        return true;
    }

    public void copyNotComposedFiles(IFile config, IFolder destination) {
        ArrayList<String> selectedFeatures = getSelectedFeatures(config);
        if (selectedFeatures != null)
            for (String feature : selectedFeatures) {
                IFolder folder = featureProject.getSourceFolder().getFolder(feature);
                try {
                    copy(folder, destination);
                } catch (CoreException e) {
                    CorePlugin.getDefault().logError(e);
                }
            }
    }

    private void copy(IFolder featureFolder, IFolder buildFolder) throws CoreException {
        if (!featureFolder.exists()) {
            return;
        }

        for (IResource res : featureFolder.members()) {
            if (res instanceof IFolder) {
                IFolder folder = buildFolder.getFolder(res.getName());
                if (!folder.exists()) {
                    folder.create(false, true, null);
                }
                copy((IFolder) res, folder);
            } else if (res instanceof IFile) {
                if (!extensions().contains(res.getFileExtension())) {
                    IFile file = buildFolder.getFile(res.getName());
                    if (!file.exists()) {
                        res.copy(file.getFullPath(), true, null);
                    }
                }
            }
        }
    }

    // TODO #460 this should be done with a ConfigurationReader
    private ArrayList<String> getSelectedFeatures(IFile config) {
        File configFile = config.getRawLocation().toFile();
        return getTokenListFromFile(configFile);
    }

    /**
     * returns a List of the tokens in file+
     * this method is public for testing purposes 
     * 
     * @param file
     * @return List of tokens
     */
    public static ArrayList<String> getTokenListFromFile(File file) {
        ArrayList<String> list = null;
        Scanner scanner = null;

        try {
            scanner = new Scanner(file, "UTF-8");

            if (scanner.hasNext()) {
                list = new ArrayList<String>();
                while (scanner.hasNext()) {
                    list.add(scanner.next());
                }

            }

        } catch (FileNotFoundException e) {
            CorePlugin.getDefault().logError(e);
        } finally {
            if (scanner != null)
                scanner.close();
        }
        return list;
    }

    public LinkedHashSet<String> extensions() {
        return new LinkedHashSet<String>(0);
    }

    public boolean postAddNature(IFolder source, IFolder destination) {
        return false;
    }

    public void addCompiler(IProject project, String sourcePath, String configPath, String buildPath) {
        addNature(project);
        addClasspathFile(project, buildPath);
    }

    private void addClasspathFile(IProject project, String buildPath) {
        try {
            JavaProject javaProject = new JavaProject(project, null);
            IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
            boolean sourceAdded = false;
            boolean containerAdded = false;
            /** check if entries already exist **/
            for (int i = 0; i < oldEntries.length; i++) {
                if (!sourceAdded && oldEntries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    /** correct the source entry **/
                    // XXX the source entry should be equivalent to the build path, 
                    // but e.g. at FeatureHouse the real build path is src/config -> Builder problems
                    // -> is it necessary to correct the path?
                    if (oldEntries[i].getPath().toString().equals("/" + project.getName())) {
                        /** necessary after creating a new FeatureIDE project **/
                        oldEntries[i] = setSourceEntry(buildPath, oldEntries[i]);
                    }
                    /** find source entry **/
                    sourceAdded = true;
                } else if (!containerAdded && oldEntries[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
                    /** check the container entries **/
                    if (oldEntries[i].getPath().equals(JRE_CONTAINER)) {
                        containerAdded = true;
                    }
                }
            }
            /** case: no new entries **/
            if (sourceAdded && containerAdded) {
                javaProject.setRawClasspath(oldEntries, null);
                return;
            }

            /** add the new entries **/
            IClasspathEntry[] entries = new IClasspathEntry[(sourceAdded ? 0 : 1) + (containerAdded ? 0 : 1)
                    + oldEntries.length];
            System.arraycopy(oldEntries, 0, entries, 0, oldEntries.length);

            if (!sourceAdded) {
                entries[oldEntries.length] = getSourceEntry(buildPath);
            }
            if (!containerAdded) {
                int position = (sourceAdded ? 0 : 1) + oldEntries.length;
                entries[position] = getContainerEntry();
            }

            javaProject.setRawClasspath(entries, null);
        } catch (JavaModelException e) {
            CorePlugin.getDefault().logError(e);
        }
    }

    /**
     * Set the source path of the given <code>ClasspathEntry</code>
     * @param buildPath The new build path
     * @param e The entry to set
     * @return The entry with the new source path
     */
    public IClasspathEntry setSourceEntry(String buildPath, IClasspathEntry e) {
        return new ClasspathEntry(e.getContentKind(), e.getEntryKind(), new Path(buildPath),
                e.getInclusionPatterns(), e.getExclusionPatterns(), e.getSourceAttachmentPath(),
                e.getSourceAttachmentRootPath(), null, e.isExported(), e.getAccessRules(), e.combineAccessRules(),
                e.getExtraAttributes());
    }

    /**
     * @return A default JRE container entry
     */
    public IClasspathEntry getContainerEntry() {
        return new ClasspathEntry(IPackageFragmentRoot.K_SOURCE, IClasspathEntry.CPE_CONTAINER, JRE_CONTAINER,
                new IPath[0], new IPath[0], null, null, null, false, null, false, new IClasspathAttribute[0]);
    }

    /**
     * @param path The source path
     * @return A default source entry with the given path
     */
    public IClasspathEntry getSourceEntry(String path) {
        return new ClasspathEntry(IPackageFragmentRoot.K_SOURCE, IClasspathEntry.CPE_SOURCE, new Path(path),
                new IPath[0], new IPath[0], null, null, null, false, null, false, new IClasspathAttribute[0]);
    }

    private void addNature(IProject project) {
        try {
            if (!project.isAccessible() || project.hasNature(JAVA_NATURE))
                return;

            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] = JAVA_NATURE;
            description.setNatureIds(newNatures);
            project.setDescription(description, null);

        } catch (CoreException e) {
            CorePlugin.getDefault().logError(e);
        }
    }

    public void buildFSTModel() {

    }

    public ArrayList<String[]> getTemplates() {
        return null;
    }

    public String replaceMarker(String text, List<String> list, String packageName) {
        if (packageName.equals("")) {
            return text.replace(PACKAGE_PATTERN, "");
        } else {
            return text.replace(PACKAGE_PATTERN, "package " + packageName + ";\r\n\r\n");
        }
    }

    @SuppressWarnings("deprecation")
    public void postCompile(IResourceDelta delta, IFile buildFile) {
        try {
            buildFile.setDerived(true);
        } catch (CoreException e) {
            CorePlugin.getDefault().logError(e);
        }
    }

    public int getDefaultTemplateIndex() {
        return 0;
    }

    public boolean refines() {
        return false;
    }

    public void postModelChanged() {

    }

    public boolean hasFeatureFolder() {
        return true;
    }

    public boolean hasFeatureFolders() {
        return true;
    }

    public boolean hasCustomFilename() {
        return false;
    }

    public String getConfigurationExtension() {
        return CorePlugin.getDefault().getConfigurationExtensions().getFirst();
    }

    /* (non-Javadoc)
     * @see de.ovgu.featureide.core.builder.IComposerExtensionClass#buildConfiguration(org.eclipse.core.resources.IFolder, de.ovgu.featureide.fm.core.configuration.Configuration)
     */
    /**
     * Creates a configuration file at the given folder
     */
    public void buildConfiguration(IFolder folder, Configuration configuration, String congurationName) {
        try {
            if (!folder.exists()) {
                folder.create(true, false, null);
            }
            IFile configurationFile = folder.getFile(congurationName + "." + getConfigurationExtension());
            ConfigurationWriter writer = new ConfigurationWriter(configuration);
            writer.saveToFile(configurationFile);
            copyNotComposedFiles(configurationFile, folder);
        } catch (CoreException e) {
            CorePlugin.getDefault().logError(e);
        }
    }

    public boolean hasSourceFolder() {
        return true;
    }

    public boolean canGeneratInParallelJobs() {
        return true;
    }

    public boolean showContextFieldsAndMethods() {
        return true;
    }

    public LinkedList<FSTDirective> buildModelDirectivesForFile(Vector<String> lines) {
        return null;
    }

    public boolean needColor() {
        return false;
    }

    public boolean hasContractComposition() {
        return false;
    }
}