org.eclipse.jst.j2ee.internal.project.WTPJETEmitter.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.j2ee.internal.project.WTPJETEmitter.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * 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:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 * Created on Mar 17, 2004
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.eclipse.jst.j2ee.internal.project;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.emf.codegen.CodeGenPlugin;
import org.eclipse.emf.codegen.jet.JETCompiler;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPluginResourceHandler;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.service.prefs.BackingStoreException;

/**
 * @author schacher, mdelder
 * 
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class WTPJETEmitter extends JETEmitter {

    public static final String PROJECT_NAME = ".JETEmitters"; //$NON-NLS-1$
    private Map variables;

    private boolean intelligentLinkingEnabled = false;

    private JETCompiler jetCompiler;

    /**
     * @param templateURI
     */
    public WTPJETEmitter(String templateURI) {
        super(templateURI);
    }

    /**
     * @param templateURIPath
     * @param relativeTemplateURI
     */
    public WTPJETEmitter(String[] templateURIPath, String relativeTemplateURI) {
        super(templateURIPath, relativeTemplateURI);
    }

    /**
     * @param templateURI
     * @param classLoader
     */
    public WTPJETEmitter(String templateURI, ClassLoader classLoader) {
        super(templateURI, classLoader);
        try {
            initialize(new NullProgressMonitor());
        } catch (JETException e) {
            J2EEPlugin.logError(e);
        }
    }

    /**
     * @param templateURIPath
     * @param relativeTemplateURI
     * @param classLoader
     */
    public WTPJETEmitter(String[] templateURIPath, String relativeTemplateURI, ClassLoader classLoader) {
        super(templateURIPath, relativeTemplateURI, classLoader);
    }

    /**
     * @param templateURIPath
     * @param relativeTemplateURI
     * @param classLoader
     * @param encoding
     */
    public WTPJETEmitter(String[] templateURIPath, String relativeTemplateURI, ClassLoader classLoader,
            String encoding) {
        super(templateURIPath, relativeTemplateURI, classLoader, encoding);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.emf.codegen.jet.JETEmitter#initialize(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    public void initialize(IProgressMonitor progressMonitor) throws JETException {

        progressMonitor.beginTask("", 10); //$NON-NLS-1$
        progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_GeneratingJETEmitterFor_message", //$NON-NLS-1$
                new Object[] { templateURI }));

        try {
            // This ensures that the JRE variables are initialized.
            try {
                JavaRuntime.getDefaultVMInstall();
            } catch (Throwable throwable) {
                // This is kind of nasty to come here.
                URL jreURL = Platform.find(Platform.getBundle("org.eclipse.emf.codegen"), new Path("plugin.xml")); //$NON-NLS-1$ //$NON-NLS-2$
                IPath jrePath = new Path(Platform.asLocalURL(jreURL).getFile());
                jrePath = jrePath.removeLastSegments(1).append(new Path("../../jre/lib/rt.jar")); //$NON-NLS-1$
                if (!jrePath.equals(JavaCore.getClasspathVariable(JavaRuntime.JRELIB_VARIABLE))) {
                    JavaCore.setClasspathVariable(JavaRuntime.JRELIB_VARIABLE, jrePath, null);
                }
            }

            /*
             * final JETCompiler jetCompiler = templateURIPath == null ? new
             * MyJETCompiler(templateURI, encoding) :
             */

            getJetCompiler();

            progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETParsing_message", //$NON-NLS-1$
                    new Object[] { jetCompiler.getResolvedTemplateURI() }));
            jetCompiler.parse();
            progressMonitor.worked(1);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            jetCompiler.generate(outputStream);
            final InputStream contents = new ByteArrayInputStream(outputStream.toByteArray());

            final IWorkspace workspace = ResourcesPlugin.getWorkspace();
            IJavaModel javaModel = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
            if (!javaModel.isOpen()) {
                javaModel.open(new SubProgressMonitor(progressMonitor, 1));
            } else {
                progressMonitor.worked(1);
            }

            final IProject project = workspace.getRoot().getProject(getProjectName());
            progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETPreparingProject_message", //$NON-NLS-1$
                    new Object[] { project.getName() }));

            IJavaProject javaProject;
            if (!project.exists()) {
                javaProject = createJavaProject(progressMonitor, workspace, project);

                initializeJavaProject(progressMonitor, project, javaProject);

                javaProject.close();
            } else {
                project.open(new SubProgressMonitor(progressMonitor, 5));
                javaProject = JavaCore.create(project);
                List rawClassPath = Arrays.asList(javaProject.getRawClasspath());
                for (int i = 0; i < rawClassPath.size(); i++) {
                    IClasspathEntry entry = (IClasspathEntry) rawClassPath.get(i);
                    if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY)
                        classpathEntries.add(entry);
                }
            }

            IPackageFragmentRoot sourcePackageFragmentRoot = openJavaProjectIfNecessary(progressMonitor, project,
                    javaProject);

            String packageName = jetCompiler.getSkeleton().getPackageName();
            StringTokenizer stringTokenizer = new StringTokenizer(packageName, "."); //$NON-NLS-1$
            IProgressMonitor subProgressMonitor = new SubProgressMonitor(progressMonitor, 1);
            subProgressMonitor.beginTask("", stringTokenizer.countTokens() + 4); //$NON-NLS-1$
            subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_CreateTargetFile_message")); //$NON-NLS-1$
            IContainer sourceContainer = (IContainer) sourcePackageFragmentRoot.getCorrespondingResource();
            while (stringTokenizer.hasMoreElements()) {
                String folderName = stringTokenizer.nextToken();
                sourceContainer = sourceContainer.getFolder(new Path(folderName));
                if (!sourceContainer.exists()) {
                    ((IFolder) sourceContainer).create(false, true, new SubProgressMonitor(subProgressMonitor, 1));
                }
            }
            IFile targetFile = sourceContainer
                    .getFile(new Path(jetCompiler.getSkeleton().getClassName() + ".java")); //$NON-NLS-1$
            if (!targetFile.exists()) {
                subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETCreating_message", //$NON-NLS-1$
                        new Object[] { targetFile.getFullPath() }));
                targetFile.create(contents, true, new SubProgressMonitor(subProgressMonitor, 1));
            } else {
                subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETUpdating_message", //$NON-NLS-1$
                        new Object[] { targetFile.getFullPath() }));
                targetFile.setContents(contents, true, true, new SubProgressMonitor(subProgressMonitor, 1));
            }

            boolean errors = performBuild(project, subProgressMonitor, targetFile);

            if (!errors) {
                loadClass(workspace, project, javaProject, packageName, subProgressMonitor);
            }

            subProgressMonitor.done();
        } catch (CoreException exception) {
            throw new JETException(exception);
        } catch (Exception exception) {
            throw new JETException(exception);
        } finally {
            progressMonitor.done();
        }

    }

    /**
     * @param progressMonitor
     * @param project
     * @param javaProject
     * @return
     * @throws JavaModelException
     */
    protected IPackageFragmentRoot openJavaProjectIfNecessary(IProgressMonitor progressMonitor,
            final IProject project, IJavaProject javaProject) throws JavaModelException {
        progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETOpeningJavaProject_message", //$NON-NLS-1$
                new Object[] { project.getName() }));
        javaProject.open(new SubProgressMonitor(progressMonitor, 1));

        IPackageFragmentRoot[] packageFragmentRoots = javaProject.getPackageFragmentRoots();
        IPackageFragmentRoot sourcePackageFragmentRoot = null;
        for (int j = 0; j < packageFragmentRoots.length; ++j) {
            IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[j];
            if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
                sourcePackageFragmentRoot = packageFragmentRoot;
                break;
            }
        }
        return sourcePackageFragmentRoot;
    }

    /**
     * @param progressMonitor
     * @param project
     * @param javaProject
     * @throws CoreException
     * @throws JavaModelException
     * @throws BackingStoreException 
     */
    protected void initializeJavaProject(IProgressMonitor progressMonitor, final IProject project,
            IJavaProject javaProject) throws CoreException, JavaModelException, BackingStoreException {
        progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETInitializingProject_message", //$NON-NLS-1$
                new Object[] { project.getName() }));
        IClasspathEntry classpathEntry = JavaCore.newSourceEntry(new Path("/" + project.getName() + "/src")); //$NON-NLS-1$ //$NON-NLS-2$

        //IClasspathEntry jreClasspathEntry = JavaCore.newVariableEntry(new Path(JavaRuntime.JRELIB_VARIABLE), new Path(JavaRuntime.JRESRC_VARIABLE), new Path(JavaRuntime.JRESRCROOT_VARIABLE));
        IClasspathEntry jreClasspathEntry = JavaRuntime.getDefaultJREContainerEntry();

        List classpath = new ArrayList();
        classpath.add(classpathEntry);
        classpath.add(jreClasspathEntry);
        classpath.addAll(classpathEntries);

        IFolder sourceFolder = project.getFolder(new Path("src")); //$NON-NLS-1$
        if (!sourceFolder.exists()) {
            sourceFolder.create(false, true, new SubProgressMonitor(progressMonitor, 1));
        }
        IFolder runtimeFolder = project.getFolder(new Path("runtime")); //$NON-NLS-1$
        if (!runtimeFolder.exists()) {
            runtimeFolder.create(false, true, new SubProgressMonitor(progressMonitor, 1));
        }

        IClasspathEntry[] classpathEntryArray = (IClasspathEntry[]) classpath
                .toArray(new IClasspathEntry[classpath.size()]);

        javaProject.setRawClasspath(classpathEntryArray, new SubProgressMonitor(progressMonitor, 1));

        javaProject.setOutputLocation(new Path("/" + project.getName() + "/runtime"), //$NON-NLS-1$//$NON-NLS-2$
                new SubProgressMonitor(progressMonitor, 1));

        // appended from previous implementation
        createClasspathEntries(project);

        IScopeContext context = new ProjectScope(project);
        IEclipsePreferences prefs = context.getNode(JavaCore.PLUGIN_ID);
        prefs.put(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE, JavaCore.IGNORE);
        prefs.put(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION, JavaCore.IGNORE);

        // set Java compiler compliance level to 1.5
        prefs.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
        prefs.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
        prefs.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
        prefs.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
        prefs.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);

        // set Javadoc validation to the default ignore level
        prefs.put(JavaCore.COMPILER_PB_INVALID_JAVADOC, JavaCore.IGNORE);
        prefs.put(JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS, JavaCore.DISABLED);
        prefs.put(JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS__DEPRECATED_REF, JavaCore.DISABLED);
        prefs.put(JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS__NOT_VISIBLE_REF, JavaCore.DISABLED);
        prefs.put(JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY, JavaCore.PUBLIC);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION,
                JavaCore.COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_RETURN_TAG);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS, JavaCore.IGNORE);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_VISIBILITY, JavaCore.PUBLIC);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_OVERRIDING, JavaCore.DISABLED);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS, JavaCore.IGNORE);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY, JavaCore.PUBLIC);
        prefs.put(JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING, JavaCore.DISABLED);

        // store changed properties permanently
        prefs.flush();
    }

    /**
     * @param progressMonitor
     * @param workspace
     * @param project
     * @return
     * @throws CoreException
     */
    private IJavaProject createJavaProject(IProgressMonitor progressMonitor, final IWorkspace workspace,
            final IProject project) throws CoreException {
        IJavaProject javaProject;
        progressMonitor.subTask("JET creating project " + project.getName()); //$NON-NLS-1$
        project.create(new SubProgressMonitor(progressMonitor, 1));
        progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETCreatingProject_message", //$NON-NLS-1$
                new Object[] { project.getName() }));
        IProjectDescription description = workspace.newProjectDescription(project.getName());
        description.setNatureIds(new String[] { JavaCore.NATURE_ID });
        description.setLocation(null);
        project.open(new SubProgressMonitor(progressMonitor, 1));
        project.setDescription(description, new SubProgressMonitor(progressMonitor, 1));

        javaProject = JavaCore.create(project);
        return javaProject;
    }

    /**
     * @param workspace
     * @param project
     * @param javaProject
     * @param packageName
     * @param subProgressMonitor
     * @throws JavaModelException
     * @throws MalformedURLException
     * @throws ClassNotFoundException
     * @throws SecurityException
     */
    protected void loadClass(final IWorkspace workspace, final IProject project, IJavaProject javaProject,
            String packageName, IProgressMonitor subProgressMonitor)
            throws JavaModelException, MalformedURLException, ClassNotFoundException, SecurityException {
        //IContainer targetContainer =
        // workspace.getRoot().getFolder(javaProject.getOutputLocation());

        subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETLoadingClass_message", //$NON-NLS-1$
                new Object[] { jetCompiler.getSkeleton().getClassName() + ".class" })); //$NON-NLS-1$

        // Construct a proper URL for relative lookup.
        //
        URL url = new File(
                project.getLocation() + "/" + javaProject.getOutputLocation().removeFirstSegments(1) + "/").toURL(); //$NON-NLS-1$ //$NON-NLS-2$
        URLClassLoader theClassLoader = new URLClassLoader(new URL[] { url }, classLoader);
        Class theClass = theClassLoader.loadClass(
                (packageName.length() == 0 ? "" : packageName + ".") + jetCompiler.getSkeleton().getClassName()); //$NON-NLS-1$ //$NON-NLS-2$
        String methodName = jetCompiler.getSkeleton().getMethodName();
        Method[] methods = theClass.getDeclaredMethods();
        for (int i = 0; i < methods.length; ++i) {
            if (methods[i].getName().equals(methodName)) {
                setMethod(methods[i]);
                break;
            }
        }
    }

    /**
     * @param project
     * @param subProgressMonitor
     * @param targetFile
     * @return
     * @throws CoreException
     */
    protected boolean performBuild(final IProject project, IProgressMonitor subProgressMonitor, IFile targetFile)
            throws CoreException {
        subProgressMonitor.subTask(
                CodeGenPlugin.getPlugin().getString("_UI_JETBuilding_message", new Object[] { project.getName() })); //$NON-NLS-1$
        project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(subProgressMonitor, 1));

        IMarker[] markers = targetFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
        boolean errors = false;
        for (int i = 0; i < markers.length; ++i) {
            IMarker marker = markers[i];
            if (marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) == IMarker.SEVERITY_ERROR) {
                errors = true;
                subProgressMonitor.subTask(marker.getAttribute(IMarker.MESSAGE) + " : " //$NON-NLS-1$
                        + (CodeGenPlugin.getPlugin().getString("jet.mark.file.line", new Object[] { //$NON-NLS-1$
                                targetFile.getLocation(), marker.getAttribute(IMarker.LINE_NUMBER) })));
            }
        }
        return errors;
    }

    /**
     * Create the correct classpath entries for the given project
     * 
     * @param project
     */
    protected void createClasspathEntries(IProject project) {
        Assert.isNotNull(project, "A valid project is required in order to append to a classpath"); //$NON-NLS-1$
        String variableName = null;
        String pluginId = null;
        for (Iterator variablesKeyIterator = getVariables().keySet().iterator(); variablesKeyIterator.hasNext();) {
            variableName = (String) variablesKeyIterator.next();
            pluginId = (String) getVariables().get(variableName);
            if (hasOutputDirectory(pluginId))
                addLinkedFolderAsLibrary(project, variableName, pluginId);
            else
                addRuntimeJarsAsLibrary(project, pluginId);
        }
    }

    /**
     * @param pluginId
     * @return
     */
    protected boolean hasOutputDirectory(String pluginId) {
        Bundle bundle = Platform.getBundle(pluginId);
        URL outputDirectory = Platform.find(bundle, new Path("bin")); //$NON-NLS-1$
        if (outputDirectory == null)
            return false;
        URL installLocation = null;
        try {
            installLocation = Platform.asLocalURL(outputDirectory);
            File outputDirectoryFile = new File(installLocation.getPath());// new File(location);
            return outputDirectoryFile.canRead() && outputDirectoryFile.isDirectory()
                    && outputDirectoryFile.listFiles().length > 0;
        } catch (IOException e) {
            J2EEPlugin.logWarning(
                    J2EEPluginResourceHandler.getString("Install_Location_Error_", new Object[] { installLocation }) //$NON-NLS-1$
                            + e);
        }
        return false;

    }

    /**
     * @param project
     * @param variableName
     * @param pluginId
     */
    protected void addRuntimeJarsAsLibrary(IProject project, String pluginId) {
        ManifestElement[] elements = null;
        Bundle bundle = Platform.getBundle(pluginId);
        try {
            String requires = bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
            elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, requires);
        } catch (Exception e) {
            J2EEPlugin.logError(e);
            elements = new ManifestElement[0];
        }
        IPath runtimeLibFullPath = null;
        URL fullurl = null;
        if (elements == null) {
            if (bundle.getLocation().endsWith(IJ2EEModuleConstants.JAR_EXT))
                try {
                    runtimeLibFullPath = getJarredPluginPath(bundle);
                } catch (IOException e) {
                    J2EEPlugin.logError(e);
                }
            appendToClassPath(runtimeLibFullPath, project);
            return;
        }
        for (int i = 0; i < elements.length; i++) {
            String value = elements[i].getValue();
            if (".".equals(value)) //$NON-NLS-1$
                value = "/"; //$NON-NLS-1$
            fullurl = Platform.getBundle(pluginId).getEntry(value);
            // fix the problem with leading slash that caused dup classpath entries
            if (fullurl == null)
                continue;
            try {
                runtimeLibFullPath = new Path(Platform.asLocalURL(fullurl).getPath());
            } catch (Exception e) {
                J2EEPlugin.logError(e);
            }
            //TODO handle jar'ed plugins, this is a hack for now, need to find proper bundle API
            if (bundle.getLocation().endsWith(IJ2EEModuleConstants.JAR_EXT))
                try {
                    runtimeLibFullPath = getJarredPluginPath(bundle);
                } catch (IOException e) {
                    J2EEPlugin.logError(e);
                }

            if (runtimeLibFullPath != null && !"jar".equals(runtimeLibFullPath.getFileExtension()) //$NON-NLS-1$
                    && !"zip".equals(runtimeLibFullPath.getFileExtension())) //$NON-NLS-1$
                continue;
            appendToClassPath(runtimeLibFullPath, project);
        }
    }

    private void appendToClassPath(IPath runtimeLibFullPath, IProject project) {
        IClasspathEntry entry = null;
        entry = JavaCore.newLibraryEntry(runtimeLibFullPath, null, null, null, new IClasspathAttribute[] {}, false);
        try {
            if (!classpathEntries.contains(entry))
                classpathEntries.add(entry);
            //J2EEProjectUtilities.appendJavaClassPath(project, entry);
        } catch (Exception e) {
            J2EEPlugin.logError("Problem appending \"" + entry.getPath() + "\" to classpath of Project \"" //$NON-NLS-1$//$NON-NLS-2$
                    + project.getName() + "\"."); //$NON-NLS-1$
            J2EEPlugin.logError(e);
        }
    }

    private IPath getJarredPluginPath(Bundle bundle) throws IOException {
        Path runtimeLibFullPath = null;
        String jarPluginLocation = FileLocator.getBundleFile(bundle).getPath();
        Path jarPluginPath = new Path(jarPluginLocation);
        // handle case where jars are installed outside of eclipse installation
        if (jarPluginPath.isAbsolute())
            runtimeLibFullPath = jarPluginPath;
        // handle normal case where all plugins under eclipse install
        else {
            String installPath = Platform.getInstallLocation().getURL().getPath();
            runtimeLibFullPath = new Path(installPath + "/" + jarPluginLocation); //$NON-NLS-1$
        }
        return runtimeLibFullPath;
    }

    /**
     * @param progressMonitor
     */
    protected void updateProgress(IProgressMonitor progressMonitor, String key) {
        progressMonitor.subTask(getMessage(key));
    }

    /**
     * @param progressMonitor
     */
    protected void updateProgress(IProgressMonitor progressMonitor, String key, Object[] args) {
        progressMonitor.subTask(getMessage(key, args));
    }

    protected String getMessage(String key) {
        return CodeGenPlugin.getPlugin().getString(key);
    }

    protected String getMessage(String key, Object[] args) {
        return CodeGenPlugin.getPlugin().getString(key, args);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.emf.codegen.jet.JETEmitter#addVariable(java.lang.String, java.lang.String)
     */
    @Override
    public void addVariable(String variableName, String pluginID) throws JETException {
        if (!isIntelligentLinkingEnabled())
            super.addVariable(variableName, pluginID);
        else {
            getVariables().put(variableName, pluginID);
            IWorkspace workspace = ResourcesPlugin.getWorkspace();
            IProject project = workspace.getRoot().getProject(getProjectName());
            if (project != null && project.exists())
                createClasspathEntries(project);
        }

    }

    /**
     * @return
     */
    private boolean isIntelligentLinkingEnabled() {
        return intelligentLinkingEnabled;
    }

    /**
     * @return
     */
    private Map getVariables() {
        if (variables == null)
            variables = new HashMap();
        return variables;
    }

    protected void addLinkedFolderAsLibrary(IProject project, String variableName, String pluginID) {
        try {
            URL outputDirectory = Platform.find(Platform.getBundle(pluginID), new Path("bin")); //$NON-NLS-1$
            //         IPluginDescriptor pluginDescriptor = Platform.getPlugin(pluginID).getDescriptor();
            //         URL outputDirectory = pluginDescriptor.find(new Path("bin")); //$NON-NLS-1$
            String pathString = Platform.asLocalURL(outputDirectory).getPath();
            if (pathString.endsWith("/")) //$NON-NLS-1$
                pathString = pathString.substring(0, pathString.length() - 1);
            if (pathString.startsWith("/")) //$NON-NLS-1$
                pathString = pathString.substring(1, pathString.length());
            IPath path = new Path(pathString).makeAbsolute();

            String binDirectoryVariable = variableName + "_BIN"; //$NON-NLS-1$
            IFolder linkedDirectory = project.getFolder(binDirectoryVariable);
            if (!linkedDirectory.exists()) {
                linkedDirectory.createLink(path, IResource.ALLOW_MISSING_LOCAL, null);
                linkedDirectory.setDerived(true);
                project.refreshLocal(IResource.DEPTH_INFINITE, null);
            }
            IClasspathEntry entry = JavaCore.newLibraryEntry(linkedDirectory.getFullPath(), null, null, null,
                    new IClasspathAttribute[] {}, false);

            if (!classpathEntries.contains(entry))
                classpathEntries.add(entry);
            //J2EEProjectUtilities.appendJavaClassPath(project, entry);

        } catch (Exception e) {
            J2EEPlugin.logError(e);
        }
    }

    /**
     * @param intelligentLinkingEnabled
     *            The intelligentLinkingEnabled to set.
     */
    public void setIntelligentLinkingEnabled(boolean intelligentLinkingEnabled) {
        this.intelligentLinkingEnabled = intelligentLinkingEnabled;
    }

    protected JETCompiler getJetCompiler() {
        try {
            if (jetCompiler == null) {
                jetCompiler = templateURIPath == null ? new MyJETCompiler(templateURI, encoding)
                        : new MyJETCompiler(templateURIPath, templateURI, encoding);
            }
        } catch (JETException e) {
            J2EEPlugin.logError(e);
        }
        return jetCompiler;
    }
}