org.apache.easyant4e.natures.EasyAntNature.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.easyant4e.natures.EasyAntNature.java

Source

/*
 *  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.apache.easyant4e.natures;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.easyant.core.descriptor.PropertyDescriptor;
import org.apache.easyant4e.Activator;
import org.apache.easyant4e.services.EasyantProjectService;
import org.apache.ivyde.eclipse.cp.IvyClasspathContainer;
import org.apache.ivyde.eclipse.cp.IvyClasspathContainerHelper;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;

import com.google.inject.Inject;

/**
 * The EastAnt nature.
 */
public class EasyAntNature implements IProjectNature {

    public static final String NATURE_ID = "org.apache.easyant4e.EasyAntNature";

    public static final String BUILDER_ID = "org.apache.easyant4e.EasyAntBuilder";

    public EasyAntNature() {
        Activator.getEasyAntPlugin().injectMembers(this);
    }

    /**
     * The project to which this project nature applies.
     */
    private IProject project = null;

    private EasyantProjectService easyantProjectService;

    @Inject
    public void setEasyantProjectService(EasyantProjectService easyantProjectService) {
        this.easyantProjectService = easyantProjectService;
    }

    public void configure() throws CoreException {
        //TODO maybe add an extension point to delegate this step for java, scala, ...
        //Configurer.configure(IProject, EasyAntModuleDescriptor);      
        //Add Java Nature
        //TODO add checkbox or list of configurer (reuse by skeleton) in import and new project wizard to add JavaNature, ScalaNature, GroovyNature ...
        //or use a dedicated eclipse plugin ?
        if (!project.hasNature(JavaCore.NATURE_ID)) {
            IProjectDescription desc = project.getDescription();
            List<String> natures = new ArrayList<String>();
            natures.addAll(Arrays.asList(desc.getNatureIds()));
            natures.add(JavaCore.NATURE_ID);
            desc.setNatureIds(natures.toArray(new String[natures.size()]));
            project.setDescription(desc, null);
        }

        if (project.hasNature(JavaCore.NATURE_ID)) {
            IJavaProject javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
            //flush classpath
            javaProject.setRawClasspath(new IClasspathEntry[0], null);
            addSourceFolders(javaProject);
            addDefaultJREContainer(javaProject);
            addIvyClasspathContainer();
            addBuilder(BUILDER_ID);
        }
    }

    private void addIvyClasspathContainer() {
        /*
        IPath projectRelativePath = new Path("module.ivy");
        IJavaProject javaProject = JavaCore.create(project);
        IClasspathEntry newEntry = JavaCore.newContainerEntry(new Path(
        IvyClasspathContainer.CONTAINER_ID).append(projectRelativePath).append(confs));
        */
        IJavaProject javaProject = JavaCore.create(project);
        //Configure project preferences
        StringBuffer projectConf = new StringBuffer();
        //TODO search *.ivy file
        projectConf.append("?ivyXmlPath=module.ivy");
        try {
            appendConfProp(projectConf, "confs", "*");
            appendConfProp(projectConf, "resolveInWorkspace", Boolean.TRUE.toString());
            String projectIvySettings = easyantProjectService
                    .getProperty(javaProject.getProject(), "project.ivy.settings.url").getValue();
            if (projectIvySettings == null) {
                projectIvySettings = easyantProjectService
                        .getProperty(javaProject.getProject(), "project.ivy.settings.file").getValue();
                if (projectIvySettings != null) {
                    projectIvySettings = "file://" + resolveRelativePath(projectIvySettings);
                }
            }
            if (projectIvySettings != null) {
                appendConfProp(projectConf, "ivySettingsPath", projectIvySettings);
            }
        } catch (UnsupportedEncodingException e) {
            Activator.getEasyAntPlugin().log(IStatus.ERROR, e.getMessage(), e);
        }

        // add the classpath entry
        IPath path = new Path(IvyClasspathContainer.ID).append(projectConf.toString());
        IClasspathEntry newEntry = JavaCore.newContainerEntry(path);
        addClassPathEntry(javaProject, newEntry);
    }

    private String resolveRelativePath(String path) {
        if (path != null && path.startsWith(".")) {
            String projectPath = project.getLocation().toPortableString();
            path = new File(projectPath + "/" + path).getAbsolutePath();
        }
        return path;
    }

    private void appendConfProp(StringBuffer path, String name, String value) throws UnsupportedEncodingException {
        path.append('&');
        path.append(name);
        path.append('=');
        path.append(URLEncoder.encode(value, "UTF-8"));
    }

    //FIXME with scala project or others
    private void addSourceFolders(IJavaProject javaProject) throws CoreException {
        PropertyDescriptor srcMainJavaProp = easyantProjectService.getProperty(project, "src.main.java");
        String srcMainJava = removeBaseDirVar(srcMainJavaProp.getValue());
        PropertyDescriptor srcMainResourcesProp = easyantProjectService.getProperty(project, "src.main.resources");
        String srcMainResources = removeBaseDirVar(srcMainResourcesProp.getValue());
        PropertyDescriptor srcTestJavaProp = easyantProjectService.getProperty(project, "src.test.java");
        String srcTestJava = removeBaseDirVar(srcTestJavaProp.getValue());
        PropertyDescriptor srcTestResourcesProp = easyantProjectService.getProperty(project, "src.test.resources");
        String srcTestResources = removeBaseDirVar(srcTestResourcesProp.getValue());
        addSourceFolders(javaProject, srcMainJava, srcMainResources, srcTestJava, srcTestResources);
    }

    private String removeBaseDirVar(String s) {
        String baseDirVar = "${basedir}";
        if (s != null && s.contains(baseDirVar)) {
            return s.substring(s.indexOf(baseDirVar) + baseDirVar.length() + 1);
        } else {
            return s;
        }
    }

    public void deconfigure() throws CoreException {
        if (project.hasNature(JavaCore.NATURE_ID)) {
            removeBuilder(BUILDER_ID);
            removeIvyClasspathContainer();
        }
    }

    public IProject getProject() {
        return project;
    }

    public void setProject(IProject project) {
        this.project = project;

    }

    private void addDefaultJREContainer(IJavaProject javaProject) throws JavaModelException {
        List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
        entries.addAll(Arrays.asList(javaProject.getRawClasspath()));
        entries.add(JavaRuntime.getDefaultJREContainerEntry());
        javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), null);

    }

    private void addSourceFolders(IJavaProject javaProject, String... path) throws JavaModelException {
        List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
        entries.addAll(Arrays.asList(javaProject.getRawClasspath()));
        IResource outputLocation = javaProject.getProject().findMember("target");
        if (outputLocation == null) {
            outputLocation = createSourceFolder(javaProject.getProject(), "target");
        }
        javaProject.setOutputLocation(outputLocation.getFullPath(), null);
        for (String p : path) {
            IResource sourceFolder = javaProject.getProject().findMember(p);
            if (sourceFolder == null) {
                sourceFolder = createSourceFolder(javaProject.getProject(), p);
            }
            if (sourceFolder != null) {
                IPath[] exclusionPatterns = new IPath[] { outputLocation.getFullPath() };
                IClasspathEntry srcEntry = JavaCore.newSourceEntry(sourceFolder.getFullPath(), exclusionPatterns,
                        outputLocation.getFullPath());
                entries.add(srcEntry);
            }
        }
        javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), null);
    }

    private IResource createSourceFolder(IProject project, String sourcefolder) {
        IPath path = new Path(sourcefolder);
        IContainer container = project;
        try {
            for (int i = 1; i <= path.segmentCount(); i++) {
                IFolder newSourceFolder = project.getFolder(path.uptoSegment(i));
                if (!newSourceFolder.exists()) {
                    newSourceFolder.create(true, true, null);
                }
                container = newSourceFolder;
            }
            return container;
        } catch (CoreException e) {
            Activator.getEasyAntPlugin().log(e);
            return null;
        }
    }

    private void addClassPathEntry(IJavaProject javaProject, IClasspathEntry newEntry) {
        try {
            IClasspathEntry[] entries = javaProject.getRawClasspath();
            List newEntries = new ArrayList(Arrays.asList(entries));
            newEntries.add(newEntry);
            entries = (IClasspathEntry[]) newEntries.toArray(new IClasspathEntry[newEntries.size()]);

            javaProject.setRawClasspath(entries, javaProject.getOutputLocation(), null);
        } catch (CoreException e) {
            // unless there are issues with the JDT, this should never happen
            Activator.getEasyAntPlugin().log(IStatus.ERROR, "Cannot add ClassPath entry", e);
        }
    }

    private void removeIvyClasspathContainer() {
        IJavaProject javaProject = JavaCore.create(project);
        ArrayList<IClasspathEntry> newEntries = new ArrayList<IClasspathEntry>();
        //FIXME call IvyDE command
        try {
            IClasspathEntry[] entries = javaProject.getRawClasspath();
            for (int i = 0; i < entries.length; i++) {
                IClasspathEntry entry = entries[i];
                if (entry != null && entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
                    IPath path = entry.getPath();
                    if (IvyClasspathContainerHelper.isIvyClasspathContainer(path)) {
                        continue;
                    }
                }
                newEntries.add(entry);
            }
            // TODO add progress monitor
            IClasspathEntry[] newClasspathEntries = newEntries.toArray(new IClasspathEntry[newEntries.size()]);
            javaProject.setRawClasspath(newClasspathEntries, null);
        } catch (JavaModelException e) {
            Activator.getEasyAntPlugin().log(IStatus.ERROR, "Cannot remove Ivy ClassPath container", e);
        }
    }

    private void addBuilder(String builderID) throws CoreException {
        if (!isBuilderApplied(builderID)) {
            IProjectDescription description = getProject().getDescription();
            ICommand[] commands = description.getBuildSpec();
            ICommand command = description.newCommand();
            command.setBuilderName(builderID);
            ICommand[] newCommands = new ICommand[commands.length + 1];
            System.arraycopy(commands, 0, newCommands, 0, commands.length);
            newCommands[commands.length] = command;
            description.setBuildSpec(newCommands);
            getProject().setDescription(description, null);
        }
    }

    private void removeBuilder(String builderID) throws CoreException {
        if (isBuilderApplied(builderID)) {
            IProjectDescription description = getProject().getDescription();
            ICommand[] commands = description.getBuildSpec();
            ICommand[] newCommands = new ICommand[commands.length - 1];
            int i = 0;
            for (ICommand command : commands) {
                if (!command.getBuilderName().equals(builderID)) {
                    // Remove the given builder
                    newCommands[i] = command;
                    i++;
                }
            }
            description.setBuildSpec(newCommands);
            getProject().setDescription(description, null);
        }
    }

    private boolean isBuilderApplied(String builderID) throws CoreException {
        IProjectDescription description = getProject().getDescription();
        for (ICommand cmd : description.getBuildSpec()) {
            if (cmd.getBuilderName().equals(builderID)) {
                return true;
            }
        }
        return false;
    }

}