org.deved.antlride.integration.jdt.AntlrJavaTargetService.java Source code

Java tutorial

Introduction

Here is the source code for org.deved.antlride.integration.jdt.AntlrJavaTargetService.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2008 Edgar Espina.
 * 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
 *
     
 *******************************************************************************/
package org.deved.antlride.integration.jdt;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.deved.antlride.core.AntlrCore;
import org.deved.antlride.core.AntlrLanguageTargetName;
import org.deved.antlride.core.build.AntlrBuildUnit;
import org.deved.antlride.core.integration.AntlrLanguageTargetService;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

public class AntlrJavaTargetService implements AntlrLanguageTargetService {

    private static class Version {
        private String version;
    }

    public Map<String, Object> getClasspathInformation(IProgressMonitor monitor, AntlrBuildUnit unit)
            throws CoreException {

        final IJavaProject javaProject = JavaCore.create(unit.getFile().getProject());

        if (javaProject == null || !javaProject.exists()) {
            return Collections.emptyMap();
        }

        IRuntimeClasspathEntry[] runtimeClassPath = computeDefaultRuntimeClassPath(javaProject);
        Version v = new Version();
        runtimeClassPath = mergeClasspath(v, monitor, unit, runtimeClassPath);

        String[] classpath = getLocationClassPath(runtimeClassPath);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("classpath", classpath);
        map.put("description", v.version);
        return map;
    }

    public static String[] getMementoClassPath(IRuntimeClasspathEntry[] entries) throws CoreException {
        String[] classpath = new String[entries.length];

        for (int i = 0; i < entries.length; i++) {
            classpath[i] = entries[i].getMemento();
            System.out.println(classpath[i]);
        }

        return classpath;
    }

    public static String[] getLocationClassPath(IRuntimeClasspathEntry[] entries) throws CoreException {
        String[] classpath = new String[entries.length];

        for (int i = 0; i < entries.length; i++) {
            classpath[i] = entries[i].getLocation();
        }

        return classpath;
    }

    public static IRuntimeClasspathEntry[] mergeClasspath(IProgressMonitor monitor, AntlrBuildUnit unit,
            IRuntimeClasspathEntry[] runtimeClassPath) throws CoreException {
        return mergeClasspath(new Version(), monitor, unit, runtimeClassPath);
    }

    public static IRuntimeClasspathEntry[] mergeClasspath(Version version, IProgressMonitor monitor,
            AntlrBuildUnit unit, IRuntimeClasspathEntry[] runtimeClassPath) throws CoreException {
        monitor.subTask("Checking classpath");
        String[] classpath = getLocationClassPath(runtimeClassPath);
        Collection<URL> urls = new LinkedHashSet<URL>();
        for (int i = 0; i < classpath.length; i++) {
            try {
                URL url = new File(classpath[i]).toURI().toURL();
                urls.add(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
        if (urls.size() > 0) {
            URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), null);
            boolean valid = true;
            String[] classes = { "org.antlr.runtime.Token", "org.antlr.Tool", "antlr.Tool" };
            String prefix = "ANTLR Parser Generator ";
            for (String classname : classes) {
                try {
                    // check the antlr runtime
                    Class<?> clazz = classLoader.loadClass(classname);
                    if (clazz.getName().equals("org.antlr.Tool")) {
                        // try 3.1.3+ or higher
                        InputStream in = clazz.getResourceAsStream("antlr.properties");
                        if (in != null) {
                            try {
                                Properties prop = new Properties();
                                prop.load(in);
                                version.version = prefix + prop.getProperty("antlr.version");
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        } else {
                            // 3.1.2 or minor
                            try {
                                Field vField = clazz.getDeclaredField("VERSION");
                                version.version = prefix + vField.get(null);
                            } catch (Throwable e) {
                                e.printStackTrace();
                            }
                        }
                    }
                } catch (ClassNotFoundException e) {
                    valid = false;
                    break;
                }
            }
            if (!valid) {
                classpath = unit.getPackageClasspath().split(File.pathSeparator);
                Collection<IRuntimeClasspathEntry> entries = new ArrayList<IRuntimeClasspathEntry>();
                for (String jarLocation : classpath) {
                    IRuntimeClasspathEntry runtimeEntry = JavaRuntime
                            .newArchiveRuntimeClasspathEntry(Path.fromOSString(jarLocation));
                    runtimeEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
                    entries.add(runtimeEntry);
                }
                entries.addAll(Arrays.asList(runtimeClassPath));
                return entries.toArray(new IRuntimeClasspathEntry[entries.size()]);
            }
        }
        return runtimeClassPath;
    }

    public static IRuntimeClasspathEntry[] computeDefaultRuntimeClassPath(IJavaProject jproject)
            throws CoreException {
        IRuntimeClasspathEntry[] unresolved = JavaRuntime.computeUnresolvedRuntimeClasspath(jproject);
        // 1. remove bootpath entries
        // 2. resolve & translate to local file system paths
        List<IRuntimeClasspathEntry> resolved = new ArrayList<IRuntimeClasspathEntry>(unresolved.length);
        for (int i = 0; i < unresolved.length; i++) {
            IRuntimeClasspathEntry entry = unresolved[i];
            if (entry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
                IRuntimeClasspathEntry[] entries = JavaRuntime.resolveRuntimeClasspathEntry(entry, jproject);
                for (int j = 0; j < entries.length; j++) {
                    String location = entries[j].getLocation();
                    if (location != null) {
                        resolved.add(entries[j]);
                    }
                }
            }
        }
        return resolved.toArray(new IRuntimeClasspathEntry[resolved.size()]);
    }

    public boolean accept(IResource resource) {
        boolean accept = false;
        try {
            IProject project = resource.getProject();
            IJavaProject javaProject = JavaCore.create(project);
            if (javaProject.exists()) {
                IPath resourcePath = new Path(project.getName()).append(resource.getProjectRelativePath());
                IPath outputLocation = javaProject.getOutputLocation();
                if (resourcePath.segmentCount() >= outputLocation.segmentCount()) {
                    for (int segmentIndex = 0; segmentIndex < outputLocation.segmentCount(); segmentIndex++) {
                        if (!outputLocation.segment(segmentIndex).equals(resourcePath.segment(segmentIndex))) {
                            accept = true;
                            break;
                        }
                    }
                }
            } else {
                accept = true;
            }
        } catch (JavaModelException e) {
            e.printStackTrace();
        }
        // if (!accept) {
        // System.out.println("Excluding " + resource);
        // }
        return accept;
    }

    public String format(String source) {
        try {
            @SuppressWarnings("unchecked")
            Map<Object, Object> options = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
            // initialize the compiler settings to be able to format 1.5 code
            options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
            options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
            options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);

            final CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(options);
            final int[] K = { CodeFormatter.K_STATEMENTS, CodeFormatter.K_CLASS_BODY_DECLARATIONS,
                    CodeFormatter.K_EXPRESSION };
            TextEdit edit = null;

            for (int i = 0; i < K.length; i++) {
                edit = codeFormatter.format(K[i], source, 0, source.length(), 0,
                        System.getProperty("line.separator"));
                if (edit != null) {
                    // found
                    break;
                }
            }
            if (edit != null) {
                IDocument document = new Document(source);
                edit.apply(document);
                return document.get();
            }
        } catch (MalformedTreeException ex) {
            AntlrCore.error(ex);
        } catch (BadLocationException ex) {
            AntlrCore.error(ex);
        }
        return source;
    }

    public AntlrLanguageTargetName getName() {
        return AntlrLanguageTargetName.Java;
    }
}