blob: 15e5373801e668a18f8066b259b1a966db9ea646 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2005 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.StringTokenizer;
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.util.logger.proxy.Logger;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
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$ //$NON-NLS-2$
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) {
try {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
monitor.beginTask(ProjectSupportResourceHandler.Sychronize_Class_Path_UI_, 4); //$NON-NLS-1$
//$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();
monitor.subTask(ProjectSupportResourceHandler.Catalog_Lib_Directory__UI_); //$NON-NLS-1$
//$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(".jar") //$NON-NLS-1$
|| child.getFullPath().toString().toLowerCase().endsWith(".zip"))) { //$NON-NLS-1$
lib_jars.put(child.getFullPath(), child);
}
}
monitor.worked(1);
monitor.subTask(ProjectSupportResourceHandler.Update_ClassPath__UI_); //$NON-NLS-1$
//$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 {
monitor.subTask(ProjectSupportResourceHandler.Catalog_Lib_Directory__UI_ + cp[j].getPath()); //$NON-NLS-1$
//$NON-NLS-1$ = "Catalog Lib Directory:"
newClassPathVector.add(cp[j]);
}
}
monitor.worked(1);
monitor.subTask(ProjectSupportResourceHandler.Update_ClassPath__UI_); //$NON-NLS-1$
//$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;
}
monitor.worked(1);
monitor.subTask(ProjectSupportResourceHandler.Set_ClassPath__UI_); //$NON-NLS-1$
//$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, monitor);
} catch (Exception e) {
Logger.getLogger().log(e);
}
}
} catch (ClassCastException ex) {
Logger.getLogger().log(ex);
} catch (CoreException ex) {
Logger.getLogger().log(ex);
} finally {
monitor.done();
}
}
public static void updateContextRoot(IProject project, String contextRoot) {
if (project.exists() && project.isOpen()) {
WebArtifactEdit webEdit = null;
try {
// TODO migrate to flex projects
// webEdit = (WebArtifactEdit) StructureEdit.getFirstArtifactEditForRead(project);
if (webEdit != null)
webEdit.setServerContextRoot(contextRoot);
} finally {
if (webEdit != null)
webEdit.dispose();
}
}
}
/**
* @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("") || name == null) { //$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; //$NON-NLS-1$
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();
for (int i = 0; i < token.length(); 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 {
errorMessage = ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.The_character_is_invalid_in_a_context_root, new Object[]{(new Character(token.charAt(i))).toString()}); //$NON-NLS-1$
break outer;
}
}
}
}
} // en/ end of if(name.trim
else
errorMessage = ProjectSupportResourceHandler.Names_cannot_begin_or_end_with_whitespace_5; //$NON-NLS-1$
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; //$NON-NLS-1$
if (contains(folderName, BAD_CHARS))
return ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.Folder_name_is_not_valid, new Object[]{folderName}); //$NON-NLS-1$
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; //$NON-NLS-1$
// 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; //$NON-NLS-1$
return ProjectSupportResourceHandler.Folder_name_cannot_be_the_same_as_Java_class_folder_6; //$NON-NLS-1$
}
}
}
}
} 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
return project.getFolder("WebContent");
}
public static IVirtualFolder getWebLibFolder(IVirtualComponent webComponent) {
IPath path = new Path(J2EEConstants.WEB_INF + "/" + "lib");
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;
// }
}