org.eclipse.jst.j2ee.internal.web.operations.WebPropertiesUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.j2ee.internal.web.operations.WebPropertiesUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2007 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
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.web.operations;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
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.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
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.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.project.ProjectSupportResourceHandler;
import org.eclipse.jst.j2ee.internal.web.plugin.WebPlugin;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;

import com.ibm.icu.text.UTF16;
import com.ibm.icu.util.StringTokenizer;

public class WebPropertiesUtil {
    // private static final char[] BAD_CHARS = {'/', '\\', ':'};
    private static final char[] BAD_CHARS = { ':' };
    public static final String DEFAULT_JAVA_SOURCE_NAME = "Java Source"; //$NON-NLS-1$
    //TODO Port to flexible structure

    /**
     * Update the Web Content folder to a new value if it is different. This applies to both Static
     * and J2EE Web Projects. In the case of a J2EE Project, the library classpath entries will be
     * modifies to reflect the new location.
     * 
     * @param project
     *            The Web Project to update
     * @param webContentName
     *            The new name given to the Web Project's Web Content folder
     * @param progressMonitor
     *            Indicates progress of the update operation
     * @return True if the web content rename was actually renamed, false if unneeded.
     * @throws CoreException
     *             The exception that occured during renaming of the the project's web content
     *             folder
     */
    public static boolean updateWebContentNameAndProperties(IProject project, String webContentName,
            IProgressMonitor progressMonitor) throws CoreException {
        boolean success = false;
        if (project.exists() && project.isOpen()) {

            /*
             * IBaseWebNature webNature = J2EEWebNatureRuntimeUtilities.getRuntime(project); if
             * (webContentName == null) { if (webNature.isStatic()) { webContentName =
             * J2EEWebNatureRuntimeUtilities.getDefaultStaticWebContentName(); } else {
             * webContentName = J2EEWebNatureRuntimeUtilities.getDefaultJ2EEWebContentName(); } }
             */

            IPath newPath = new Path(webContentName);
            if (getModuleServerRoot(project).getProjectRelativePath().equals(newPath))
                return false;
            if (project.exists(newPath)) {
                IStatus status = new Status(IStatus.ERROR, "org.eclipse.jst.j2ee", IStatus.OK, //$NON-NLS-1$
                        ProjectSupportResourceHandler.getString(
                                ProjectSupportResourceHandler.Could_not_rename_____2,
                                new Object[] { webContentName }),
                        null);
                throw new CoreException(status);
            }

            moveWebContentFolder(project, webContentName, progressMonitor);
            updateWebContentNamePropertiesOnly(project, webContentName, progressMonitor);
            success = true;
        }
        return success;
    }

    /**
     * Update the classpath entries and Server Root Name for this web project only.
     * 
     * @param project
     * @param webContentName
     * @return
     */
    public static void updateWebContentNamePropertiesOnly(IProject project, String webContentName,
            IProgressMonitor progressMonitor) throws CoreException {
        IPath newPath = new Path(webContentName);
        if (getModuleServerRoot(project).equals(newPath))
            return;

        if (!getModuleServerRoot(project).equals(webContentName)) {

            // if (webModuleArtifact.isJ2EE) {
            // Update the library references
            IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);

            IClasspathEntry[] classpath = javaProject.getRawClasspath();
            IClasspathEntry[] newClasspath = new IClasspathEntry[classpath.length];

            for (int i = 0; i < classpath.length; i++) {
                if (classpath[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                    IClasspathEntry library = classpath[i];
                    IPath libpath = library.getPath();
                    IPath modServerRootPath = getModuleServerRoot(project).getFullPath();
                    if (modServerRootPath.isPrefixOf(libpath)) {
                        IPath prunedPath = libpath.removeFirstSegments(modServerRootPath.segmentCount());
                        IPath relWebContentPath = new Path(webContentName + "/" + prunedPath.toString()); //$NON-NLS-1$
                        IResource absWebContentPath = project.getFile(relWebContentPath);

                        IPath srcAttachmentPath = library.getSourceAttachmentPath();
                        if (null != srcAttachmentPath) {
                            prunedPath = srcAttachmentPath.removeFirstSegments(modServerRootPath.segmentCount());
                        }
                        IResource absWebContentSrcAttachmentPath = project.getFile(relWebContentPath);

                        newClasspath[i] = JavaCore.newLibraryEntry(absWebContentPath.getFullPath(),
                                absWebContentSrcAttachmentPath.getFullPath(), library.getSourceAttachmentRootPath(),
                                library.isExported());

                    } else {
                        newClasspath[i] = classpath[i];
                    }

                } else {
                    newClasspath[i] = classpath[i];
                }
                // }

                // Set the java output folder
                IFolder outputFolder = project.getFolder(getModuleServerRoot(project).getFullPath());
                javaProject.setRawClasspath(newClasspath, outputFolder.getFullPath(),
                        new SubProgressMonitor(progressMonitor, 1));
            }
            // update websettings
            // TODO add to WebArtifactEdit
            // webNature.setModuleServerRootName(webContentName);
        }
    }

    /**
     * Moves the web content folder to the name indicated only if that path doesn't already exist in
     * the project.
     * 
     * @param project
     *            The web project to be updated.
     * @param webContentName
     *            The new web content name
     * @param progressMonitor
     *            Indicates progress
     * @throws CoreException
     *             The exception that occured during move operation
     */
    public static void moveWebContentFolder(IProject project, String webContentName,
            IProgressMonitor progressMonitor) throws CoreException {
        IPath newPath = new Path(webContentName);
        if (!project.exists(newPath)) {
            if (newPath.segmentCount() > 1) {
                for (int i = newPath.segmentCount() - 1; i > 0; i--) {
                    IPath tempPath = newPath.removeLastSegments(i);
                    IFolder tempFolder = project.getFolder(tempPath);
                    if (!tempFolder.exists()) {
                        tempFolder.create(true, true, null);
                    }
                }
            }
            newPath = project.getFullPath().append(newPath);
            IContainer webContentRoot = getModuleServerRoot(project);
            IPath oldPath = webContentRoot.getProjectRelativePath();
            webContentRoot.move(newPath, IResource.FORCE | IResource.KEEP_HISTORY,
                    new SubProgressMonitor(progressMonitor, 1));
            for (int i = 0; i < oldPath.segmentCount(); i++) {
                IPath tempPath = oldPath.removeLastSegments(i);
                IFolder tempFolder = project.getFolder(tempPath);
                if (tempFolder.exists() && tempFolder.members().length == 0) {
                    tempFolder.delete(true, true, null);
                }
            }
        }
    }

    /**
     * Synchonizies the class path and the lib directories to catch any changes from the last use
     * Creation date: (4/17/01 11:48:12 AM)
     */
    protected static void synch(IProject project, IProgressMonitor monitor) {
        IProgressMonitor localMonitor = monitor;
        try {
            if (localMonitor == null) {
                localMonitor = new NullProgressMonitor();
            }
            localMonitor.beginTask(ProjectSupportResourceHandler.Sychronize_Class_Path_UI_, 4);
            //$NON-NLS-1$ = "Sychronize Class Path"

            IContainer lib_folder = getWebLibFolder(project);
            // Nothing to do if the lib folder does not exist.
            if (lib_folder == null || !lib_folder.isAccessible())
                return;
            IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);
            IPath lib_path = lib_folder.getProjectRelativePath();
            IPath lib_full_path = lib_folder.getFullPath();

            IClasspathEntry[] cp = javaProject.getRawClasspath();

            boolean needsToBeModified = false;
            // Create a map of the lib projects in the current project
            Hashtable lib_jars = new Hashtable();
            IResource[] children = lib_folder.members();
            localMonitor.subTask(ProjectSupportResourceHandler.Catalog_Lib_Directory__UI_);
            //$NON-NLS-1$ = "Catalog Lib Directory:"
            for (int j = 0; j < children.length; j++) {
                IResource child = children[j];
                // monitor.setTaskName(ResourceHandler.getString("Catalog_Lib_Directory__UI_") +
                // child); //$NON-NLS-1$ = "Catalog Lib Directory:"
                // Make sure it is a zip or a jar file
                if (child.getType() == IResource.FILE
                        && (child.getFullPath().toString().toLowerCase().endsWith(IJ2EEModuleConstants.JAR_EXT)
                                || child.getFullPath().toString().toLowerCase().endsWith(".zip"))) { //$NON-NLS-1$
                    lib_jars.put(child.getFullPath(), child);
                }

            }

            localMonitor.worked(1);
            localMonitor.subTask(ProjectSupportResourceHandler.Update_ClassPath__UI_);
            //$NON-NLS-1$ = "Update ClassPath:"
            // Loop through all the classpath dirs looking for ones that may have
            // been deleted
            Vector newClassPathVector = new Vector();
            for (int j = 0; j < cp.length; j++) {

                // If it is a lib_path
                if (cp[j].getPath().toString().startsWith(lib_path.toString())
                        || cp[j].getPath().toString().startsWith(lib_full_path.toString())) {
                    // It was already in the class path
                    if (lib_jars.get(cp[j].getPath()) != null) {
                        newClassPathVector.add(cp[j]);
                        // Remove it from the hash table of paths to add back
                        // monitor.setTaskName(ResourceHandler.getString("Catalog_Lib_Directory__UI_")
                        // + cp[j].getPath()); //$NON-NLS-1$ = "Catalog Lib Directory:"
                        lib_jars.remove(cp[j].getPath());

                    } else {
                        // You have removed something form the class path you
                        // will need to re-build
                        // monitor.setTaskName(ResourceHandler.getString("Catalog_Lib_Directory_Remo_UI_")
                        // + cp[j].getPath()); //$NON-NLS-1$ = "Catalog Lib Directory:Remove "
                        needsToBeModified = true;
                    }
                } else {
                    localMonitor
                            .subTask(ProjectSupportResourceHandler.Catalog_Lib_Directory__UI_ + cp[j].getPath());
                    //$NON-NLS-1$ = "Catalog Lib Directory:"
                    newClassPathVector.add(cp[j]);
                }
            }
            localMonitor.worked(1);
            localMonitor.subTask(ProjectSupportResourceHandler.Update_ClassPath__UI_);
            //$NON-NLS-1$ = "Update ClassPath:"

            // Add any entries not already found
            Enumeration aenum = lib_jars.keys();
            while (aenum.hasMoreElements()) {
                IPath path = (IPath) aenum.nextElement();
                newClassPathVector.add(JavaCore.newLibraryEntry(path, null, null));
                // You have added something form the class path you
                // will need to re-build
                // monitor.setTaskName(ResourceHandler.getString("23concat_UI_", (new Object[] {
                // path }))); //$NON-NLS-1$ = "Catalog Lib Directory:Add {0}"
                needsToBeModified = true;
            }

            localMonitor.worked(1);
            localMonitor.subTask(ProjectSupportResourceHandler.Set_ClassPath__UI_);
            //$NON-NLS-1$ = "Set ClassPath:"

            // Tansfer the vector to an array
            IClasspathEntry[] newClassPathArray = new IClasspathEntry[newClassPathVector.size()];

            for (int j = 0; j < newClassPathArray.length; j++) {
                newClassPathArray[j] = (IClasspathEntry) newClassPathVector.get(j);
            }

            // Only change the class path if there has been a modification
            if (needsToBeModified) {

                try {
                    javaProject.setRawClasspath(newClassPathArray, localMonitor);
                } catch (Exception e) {
                    WebPlugin.logError(e);
                }
            }

        } catch (ClassCastException ex) {
            WebPlugin.logError(ex);
        } catch (CoreException ex) {
            WebPlugin.logError(ex);
        } finally {
            localMonitor.done();
        }
    }

    public static void updateContextRoot(IProject project, String contextRoot) {

    }

    /**
     * @param project
     *            org.eclipse.core.resources.IProject
     */
    /**
     * Returns a error message that states whether a context root is valid or not returns null if
     * context root is fine
     * 
     * @return java.lang.String
     * @param contextRoot
     *            java.lang.String
     */
    public static String validateContextRoot(String contextRoot) {

        if (contextRoot == null)
            return null;

        String errorMessage = null;

        String name = contextRoot;
        if (name.equals("")) { //$NON-NLS-1$
            // this was added because the error message shouldnt be shown initially. It should be
            // shown only if context root field is edited to
            errorMessage = ProjectSupportResourceHandler.Context_Root_cannot_be_empty_2;
            return errorMessage;
        }

        /*******************************************************************************************
         * // JZ - fix to defect 204264, "/" is valid in context root if (name.indexOf("//") != -1) {
         * //$NON-NLS-1$ errorMessage = "// are invalid characters in a resource name"; return
         * errorMessage; }
         ******************************************************************************************/

        if (name.trim().equals(name)) {
            StringTokenizer stok = new StringTokenizer(name, "."); //$NON-NLS-1$
            outer: while (stok.hasMoreTokens()) {
                String token = stok.nextToken();
                int cp;
                for (int i = 0; i < token.length(); i += UTF16.getCharCount(cp)) {
                    cp = UTF16.charAt(token, i);
                    if (!(token.charAt(i) == '_') && !(token.charAt(i) == '-') && !(token.charAt(i) == '/')
                            && Character.isLetterOrDigit(token.charAt(i)) == false) {
                        if (Character.isWhitespace(token.charAt(i))) {
                            // Removed because context roots can contain white space
                            // errorMessage =
                            // ResourceHandler.getString("_Context_root_cannot_conta_UI_");//$NON-NLS-1$
                            // = " Context root cannot contain whitespaces."
                        } else {
                            String invalidCharString = null;
                            if (UTF16.getCharCount(cp) > 1) {
                                invalidCharString = UTF16.valueOf(cp);
                            } else {
                                invalidCharString = (new Character(token.charAt(i))).toString();
                            }
                            Object[] invalidChar = new Object[] { invalidCharString };
                            errorMessage = ProjectSupportResourceHandler.getString(
                                    ProjectSupportResourceHandler.The_character_is_invalid_in_a_context_root,
                                    invalidChar);
                            break outer;
                        }
                    }
                }
            }
        } // en/ end of if(name.trim
        else
            errorMessage = ProjectSupportResourceHandler.Names_cannot_begin_or_end_with_whitespace_5;

        return errorMessage;
    }

    /**
     * Return true if the string contains any of the characters in the array.
     */
    private static boolean contains(String str, char[] chars) {
        for (int i = 0; i < chars.length; i++) {
            if (str.indexOf(chars[i]) != -1)
                return true;
        }
        return false;
    }

    public static String validateFolderName(String folderName) {
        if (folderName.length() == 0)
            return ProjectSupportResourceHandler.Folder_name_cannot_be_empty_2;

        if (contains(folderName, BAD_CHARS))
            return ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.Folder_name_is_not_valid,
                    new Object[] { folderName });

        return null;
    }

    public static String validateWebContentName(String webContentName, IProject project, String javaSourceName) {

        String msg = validateFolderName(webContentName);
        if (msg != null)
            return msg;

        if (javaSourceName != null && webContentName.equals(javaSourceName))
            return ProjectSupportResourceHandler.Folder_names_cannot_be_equal_4;

        // If given a java project, check to make sure current package fragment
        // root folders do not overlap with new web content name
        if (project != null) {
            IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);
            if (javaProject != null) {
                try {
                    IPackageFragmentRoot roots[] = javaProject.getPackageFragmentRoots();
                    for (int i = 0; i < roots.length; i++) {
                        IPackageFragmentRoot root = roots[i];
                        if (!root.isArchive()) {
                            IResource resource = root.getCorrespondingResource();
                            if (resource.getType() == IResource.FOLDER) {
                                IPath path = resource.getFullPath();
                                String rootFolder = path.segment(1);
                                if (webContentName.equals(rootFolder)) {
                                    if (root.getKind() == IPackageFragmentRoot.K_SOURCE)
                                        return ProjectSupportResourceHandler.Folder_name_cannot_be_the_same_as_Java_source_folder_5;

                                    return ProjectSupportResourceHandler.Folder_name_cannot_be_the_same_as_Java_class_folder_6;
                                }
                            }
                        }
                    }
                } catch (JavaModelException e) {
                    return null;
                }
            }
        }

        return null;
    }

    /**
     * Update given web nature to the current version if necessary.
     * 
     * @param webNature
     *            The web Nature that should be examined.
     * @return True if successful, false if unnecessary.
     * @throws CoreException
     *             The exception that occured during the version change operation.
     */
    /*
     * static public boolean updateNatureToCurrentVersion(J2EEWebNatureRuntime webNature) throws
     * CoreException {
     * 
     * boolean success = false;
     * 
     * if (webNature.getVersion() != WEB.CURRENT_VERSION) {
     * webNature.setVersion(J2EESettings.CURRENT_VERSION); success = true; }
     * ((J2EEModuleWorkbenchURIConverterImpl)
     * webNature.getResourceSet().getURIConverter()).recomputeContainersIfNecessary();
     * 
     * return success; }
     */

    /**
     * Move the old source folder to the new default folder.
     * 
     * @param project
     *            The Web Project we are working with.
     * @param oldSourceFolder
     *            The old "Java Source" folder that will be moved.
     * @param javaSourceName
     *            The new name of the "Java Source" folder, or null for default.
     * @return The location of the new folder, or null if no move was necessary.
     * @throws CoreException
     *             The exception that occured during the move operation.
     */
    static public IContainer updateJavaSourceName(IProject project, IContainer oldSourceFolder,
            String javaSourceName, IProgressMonitor progressMonitor) throws CoreException {
        IContainer newSourceFolder = null;
        if (oldSourceFolder != null) {
            IPath newPath;
            if (javaSourceName == null)
                newPath = new Path(DEFAULT_JAVA_SOURCE_NAME);
            else
                newPath = new Path(javaSourceName);

            // Make sure new path is different form old path
            if (!project.getFolder(newPath).getFullPath().equals(oldSourceFolder.getFullPath())) {
                oldSourceFolder.move(newPath, IResource.FORCE | IResource.KEEP_HISTORY,
                        new SubProgressMonitor(progressMonitor, 1));
                JemProjectUtilities.removeFromJavaClassPath(project, oldSourceFolder);
                newSourceFolder = project.getFolder(newPath);
                JemProjectUtilities.appendJavaClassPath(project,
                        JavaCore.newSourceEntry(project.getFolder(newPath).getFullPath()));
            }
        }
        return newSourceFolder;
    }

    /**
     * Get the source folder that should be used for migration.
     * 
     * @param project
     *            The Web Project to examine.
     * @return The source folder to use in migration, or null if it should be skipped.
     */
    static public IContainer getJavaSourceFolder(IProject project) {
        List sourceRoots = JemProjectUtilities.getSourceContainers(project);
        IContainer oldSourceFolder = null;

        if (sourceRoots != null) {
            if (sourceRoots.size() == 1) {
                IContainer sourceFolder = (IContainer) sourceRoots.get(0);
                if (sourceFolder instanceof IFolder) {
                    oldSourceFolder = sourceFolder;
                }
            }
        }
        return oldSourceFolder;
    }

    public static IFolder getModuleServerRoot(IProject project) {
        // TODO need to implement module server root properly
        IPath compRootPath = ComponentCore.createComponent(project).getRootFolder().getUnderlyingFolder()
                .getProjectRelativePath();
        return project.getFolder(compRootPath);
        //return project.getFolder("WebContent");

    }

    public static IVirtualFolder getWebLibFolder(IVirtualComponent webComponent) {
        IPath path = new Path(J2EEConstants.WEB_INF + "/" + "lib"); //$NON-NLS-1$//$NON-NLS-2$
        IVirtualFolder libFolder = webComponent.getRootFolder().getFolder(path);
        return libFolder;
    }

    //TODO delete jsholl
    /**
     * @deprecated use getWebLibFolder(IVirtualComponent webComponent)
     * @param project
     * @return
     */
    public static IContainer getWebLibFolder(IProject project) {
        return getWebLibFolder(ComponentCore.createComponent(project)).getUnderlyingFolder();
    }

    //   
    // static public boolean isImportedClassesJARFileInLibDir(IResource resource) {
    // if (resource == null || !resource.exists())
    // return false;
    // return resource.getType() == resource.FILE &&
    // resource.getName().endsWith(IWebNatureConstants.IMPORTED_CLASSES_SUFFIX) && isZip(resource);
    // }
    //   
    // static public boolean isLibDirJARFile(IResource resource) {
    // if (resource == null || !resource.exists())
    // return false;
    // return resource.getType() == resource.FILE && isZip(resource);
    // }
    //   
    // static public boolean isZip(IResource resource) {
    // String path = resource.getLocation().toOSString();
    // ZipFile zip = null;
    //
    // try {
    // zip = new ZipFile(path);
    // } catch (IOException notAZip) {
    // return false;
    // } finally {
    // if (zip != null) {
    // try {
    // zip.close();
    // } catch (IOException ex) {}
    // }
    // }
    // return zip != null;
    // }

}