com.javadude.antxr.eclipse.smapinstaller.SMapInstallerBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.javadude.antxr.eclipse.smapinstaller.SMapInstallerBuilder.java

Source

/*******************************************************************************
 * Copyright (c) 2008 Scott Stanchfield, based on ANTLR-Eclipse plugin
 *   by Torsten Juergeleit.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors
 *    Torsten Juergeleit - original ANTLR Eclipse plugin
 *    Scott Stanchfield - modifications for ANTXR
 *******************************************************************************/
package com.javadude.antxr.eclipse.smapinstaller;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
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 com.javadude.antxr.eclipse.core.builder.AntxrBuilder;

/**
 * A custom builder for Java files in Eclipse that removes trailing spaces and
 *   converts leading tabs into spaces. This builder is intended to be
 *   used whenever a java file is saved, and only acts upon files that are
 *   open in the editor.
 */
public class SMapInstallerBuilder extends IncrementalProjectBuilder {
    /** the builder id for the smap installer */
    public static final String BUILDER_ID = "com.javadude.antxr.eclipse.core.smapbuilder";

    /**
     * A delta visitor that will execute against a change made on some
     *   resources. This visitor simply calls spaceConvert when a resource
     *   has changed.
     * Note that delta visitors are called for incremental compilations,
     *   not full builds of the system.
     */
    private IResourceDeltaVisitor deltaVisitor = new IResourceDeltaVisitor() {
        public boolean visit(IResourceDelta delta) throws CoreException {
            if (delta.getKind() == IResourceDelta.CHANGED) {
                installSmap(delta.getResource());
            }
            return true;
        }
    };

    /**
     * A visitor that will execute when the project is rebuilt. This visitor
     *   simply calls spaceConvert against each resource.
     */
    private IResourceVisitor visitor = new IResourceVisitor() {
        public boolean visit(IResource resource) {
            try {
                installSmap(resource);
            } catch (JavaModelException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return true;
        }
    };

    /**
     * Installs the modified smap into a generated classfile
     * @param resource
     * @throws JavaModelException
     */
    protected void installSmap(IResource resource) throws JavaModelException {
        // We only work on smap files -- skip everything else
        if (!(resource instanceof IFile)) {
            return;
        }
        IFile smapIFile = (IFile) resource;
        if (!"smap".equalsIgnoreCase(smapIFile.getFileExtension())) {
            return;
        }
        IJavaProject javaProject = JavaCore.create(smapIFile.getProject());

        // get the name of the corresponding java source file
        IPath smapPath = smapIFile.getFullPath();

        IClasspathEntry[] classpathEntries = javaProject.getResolvedClasspath(true);
        for (IClasspathEntry entry : classpathEntries) {
            if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
                continue;
            }
            if (!entry.getPath().isPrefixOf(smapPath)) {
                continue;
            }

            // found the right source container
            IPath outputLocation = entry.getOutputLocation();
            if (outputLocation == null) {
                outputLocation = javaProject.getOutputLocation();
            }
            // strip the source dir and .smap suffix
            String sourceDir = entry.getPath().toString();
            String smapName = smapPath.toString();
            String javaSourceName = smapName.substring(0, smapName.length() - 5) + ".java";
            String className = smapName.substring(sourceDir.length(), smapName.length() - 5) + ".class";
            IPath path = outputLocation.append(className);
            IPath workspaceLoc = ResourcesPlugin.getWorkspace().getRoot().getLocation();
            IPath classFileLocation = workspaceLoc.append(path);
            IResource classResource = ResourcesPlugin.getWorkspace().getRoot().findMember(javaSourceName);

            File classFile = classFileLocation.toFile();
            File smapFile = smapIFile.getLocation().toFile();
            try {
                String installSmap = classResource.getPersistentProperty(AntxrBuilder.INSTALL_SMAP);
                if ("true".equals(installSmap)) {
                    SDEInstaller.install(classFile, smapFile);
                }
            } catch (CoreException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** {@inheritDoc} */
    protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
        // split the build via incremental or full, and pass the
        //   right visitor to the delta
        if (kind == IncrementalProjectBuilder.FULL_BUILD) {
            getProject().accept(visitor);
        } else {
            IResourceDelta delta = getDelta(getProject());
            if (delta == null) {
                getProject().accept(visitor);
            } else {
                delta.accept(deltaVisitor);
            }
        }
        return null;
    }
}