| /******************************************************************************* |
| * 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, ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.Could_not_rename_____2, new Object[]{webContentName}), null); //$NON-NLS-1$ |
| 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; |
| // } |
| |
| |
| } |