package com.sysdeo.eclipse.tomcat;
/*
* (c) Copyright Sysdeo SA 2001, 2002.
* All Rights Reserved.
*/
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import com.sysdeo.eclipse.tomcat.editors.ProjectListElement;
public class TomcatProject extends PlatformObject implements IProjectNature {
// Persistence properties of projects
private static final String PROPERTIES_FILENAME = ".tomcatplugin";
private static final String KEY_WEBPATH = "webPath";
private static final String KEY_UPDATEXML = "updateXml";
private static final String KEY_EXPORTSOURCE = "exportSource";
private static final String KEY_RELOADABLE="reloadable";
private static final String KEY_REDIRECTLOGGER="redirectLogger";
private static final String KEY_WARLOCATION = "warLocation";
private static final String KEY_ROOTDIR = "rootDir";
private static final String KEY_EXTRAINFO = "extraInfo";
private static final String KEY_WEBCLASSPATH = WebClassPathEntries.TAG_NAME;
private static final String extraBeginTag = "<!-- Extra info begin -->";
private static final String extraEndTag = "<!-- Extra info end -->";
// private static final QualifiedName QN_WEBPATH = new QualifiedName("TomcatProject", KEY_WEBPATH);
// private static final QualifiedName QN_UPDATEXML = new QualifiedName("TomcatProject", KEY_UPDATEXML);
// private static final QualifiedName QN_EXPORTSOURCE = new QualifiedName("TomcatProject", KEY_EXPORTSOURCE);
// private static final QualifiedName QN_RELOADABLE = new QualifiedName("TomcatProject", KEY_RELOADABLE);
// private static final QualifiedName QN_REDIRECTLOGGER = new QualifiedName("TomcatProject", KEY_REDIRECTLOGGER);
// private static final QualifiedName QN_WARLOCATION = new QualifiedName("TomcatProject", KEY_WARLOCATION);
// private static final QualifiedName QN_ROOTDIR = new QualifiedName("TomcatProject", KEY_ROOTDIR);
/**
* The platform project this <code>TomcatProject</code> is based on
*/
protected IProject project;
protected IJavaProject javaProject;
protected String webPath = "";
protected String warLocation = "";
protected String rootDir = "";
protected String extraInfo = "";
protected boolean updateXml;
protected boolean exportSource;
protected boolean reloadable = true;
protected boolean redirectLogger = false;
protected WebClassPathEntries webClassPathEntries;
protected IFolder rootDirFolder;
/**
* Gets the project.
* @return Returns a IProject
*/
public IProject getProject() {
return project;
}
/**
* Sets the project.
* @param project The project to set
*/
public void setProject(IProject project) {
this.project = project;
}
/*
* @see IProjectNature#configure()
*/
public void configure() throws CoreException {
}
/*
* @see IProjectNature#deconfigure()
*/
public void deconfigure() throws CoreException {
}
/*
* @see IProjectNature#getProject()
*/
public IJavaProject getJavaProject() {
return javaProject;
}
/*
* @see IProjectNature#setProject(IProject)
*/
public void setJavaProject(IJavaProject javaProject) {
this.javaProject = javaProject;
this.setProject(javaProject.getProject());
}
static public void addTomcatNature(IJavaProject project) {
try {
JDTUtil.addNatureToProject(project.getProject(), TomcatLauncherPlugin.NATURE_ID);
} catch(CoreException ex) {
TomcatLauncherPlugin.log(ex.getMessage());
}
}
static public void removeTomcatNature(IJavaProject project) {
try {
JDTUtil.removeNatureToProject(project.getProject(), TomcatLauncherPlugin.NATURE_ID);
} catch(CoreException ex) {
TomcatLauncherPlugin.log(ex.getMessage());
}
}
/**
* Return a TomcatProject if this javaProject has the tomcat nature
* Return null if Project has not tomcat nature
*/
static public TomcatProject create(IJavaProject javaProject) {
TomcatProject result = null;
try {
result = (TomcatProject)javaProject.getProject().getNature(TomcatLauncherPlugin.NATURE_ID);
if(result != null)
result.setJavaProject(javaProject);
} catch(CoreException ex) {
TomcatLauncherPlugin.log(ex.getMessage());
}
return result;
}
/**
* Return a TomcatProject if this Project has the tomcat nature
* Return null if Project has not tomcat nature
*/
static public TomcatProject create(IProject project) {
IJavaProject javaProject = JavaCore.create(project);
if(javaProject != null) {
return TomcatProject.create(javaProject);
} else {
return null;
}
}
private File getPropertiesFile() {
return (this.getProject().getLocation().append(PROPERTIES_FILENAME).toFile());
}
private String readProperty(String key) {
String result = null;
try {
result = FileUtil.readPropertyInXMLFile(getPropertiesFile(), key);
} catch (IOException e) {
try {
result = getJavaProject().getCorrespondingResource().getPersistentProperty(new QualifiedName("TomcatProject", key));
} catch (Exception e2) {
TomcatLauncherPlugin.log(e2);
}
}
if(result == null) {
result = "";
}
return result;
}
/**
* Gets the rootDir.
* @return Returns a String
*/
public String getRootDir() {
return this.readProperty(KEY_ROOTDIR);
}
/**
* Sets the rootDir.
* @param rootDir The rootDir to set
*/
public void setRootDir(String rd) {
this.rootDir = rd;
this.rootDirFolder = null;
}
/**
* Gets the webpath.
* @return Returns a String
*/
public String getWebPath() {
return this.readProperty(KEY_WEBPATH);
}
/**
* Sets the webpath.
* @param webpath The webpath to set
*/
public void setWebPath(String wp) {
this.webPath = wp;
}
public void updateWebPath(String newWebPath) throws Exception {
setWebPath(newWebPath);
if(!newWebPath.equals(this.getWebPath())) {
if(getUpdateXml()) {
removeContext();
}
}
}
/**
* Gets the warfile.
* @return Returns a String
*/
public String getWarLocation() {
return this.readProperty(KEY_WARLOCATION);
}
/**
* Sets the warfile
* @param warfile The warfile to set
*/
public void setWarLocation(String wl) {
this.warLocation = wl;
}
/**
* Gets the updateXml.
* @return Returns a boolean
*/
public boolean getUpdateXml() {
return new Boolean(this.readProperty(KEY_UPDATEXML)).booleanValue();
}
/**
* Sets the updateXml.
* @param updateXml The updateXml to set
*/
public void setUpdateXml(boolean updateXml) {
this.updateXml = updateXml;
}
/**
* Gets the updateXml.
* @return Returns a boolean
*/
public boolean getExportSource() {
return new Boolean(this.readProperty(KEY_EXPORTSOURCE)).booleanValue();
}
/**
* Sets the exportSource.
* @param exportSource The exportSource to set
*/
public void setExportSource(boolean exportSource) {
this.exportSource = exportSource;
}
/**
* Gets the reloadable
* @return Returns a boolean
*/
public boolean getReloadable(){
String reloadableProperty = this.readProperty(KEY_RELOADABLE);
// Set default value to true
if(reloadableProperty.equals("")) {
reloadableProperty = "true";
}
return new Boolean(reloadableProperty).booleanValue();
}
/**
* Sets the reloadable
* @param reloadable The reloadable to set
*/
public void setReloadable(boolean reloadable){
this.reloadable = reloadable;
}
/**
* Gets the reloadable
* @return Returns a boolean
*/
public boolean getRedirectLogger(){
String redirectLoggerProperty = this.readProperty(KEY_REDIRECTLOGGER);
// Set default value to false
if(redirectLoggerProperty.equals("")) {
redirectLoggerProperty = "false";
}
return new Boolean(redirectLoggerProperty).booleanValue();
}
/**
* Sets the reloadable
* @param reloadable The reloadable to set
*/
public void setRedirectLogger(boolean redirectLogger){
this.redirectLogger = redirectLogger;
}
/**
* Gets the warfile.
* @return Returns a String
*/
public String getExtraInfo() {
return URLDecoder.decode(this.readProperty(KEY_EXTRAINFO));
}
/**
* Sets the warfile
* @param warfile The warfile to set
*/
public void setExtraInfo(String extra) {
this.extraInfo = extra;
}
/**
* set the classpath entries which shall be loaded by the webclassloader
* @param entries List of WebClasspathEntry objects
*/
public void setWebClassPathEntries(WebClassPathEntries entries) {
webClassPathEntries = entries;
}
/**
* return the webclasspath entries
*/
public WebClassPathEntries getWebClassPathEntries() {
try {
return WebClassPathEntries.xmlUnmarshal(FileUtil.readTextFile(getPropertiesFile()));
} catch(IOException ioEx) {
return null;
}
}
/*
* Store exportSource in project persistent properties
*/
public void saveProperties() {
try {
StringBuffer fileContent = new StringBuffer();
fileContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fileContent.append("<tomcatProjectProperties>\n");
fileContent.append(" <rootDir>" + rootDir + "</rootDir>\n");
fileContent.append(" <exportSource>" + exportSource + "</exportSource>\n");
fileContent.append(" <reloadable>" + reloadable + "</reloadable>\n");
fileContent.append(" <redirectLogger>" + redirectLogger + "</redirectLogger>\n");
fileContent.append(" <updateXml>" + updateXml + "</updateXml>\n");
fileContent.append(" <warLocation>" + warLocation + "</warLocation>\n");
fileContent.append(" <extraInfo>" + URLEncoder.encode(extraInfo) + "</extraInfo>\n");
fileContent.append(" <webPath>" + webPath + "</webPath>\n");
if (webClassPathEntries != null) {
fileContent.append(webClassPathEntries.xmlMarshal(4));
}
fileContent.append("</tomcatProjectProperties>\n");
FileUtil.toTextFile(getPropertiesFile(), fileContent.toString());
// refresh the project files.
project.refreshLocal(IResource.DEPTH_ONE, null);
//Notification for VCM (Team plug-in)
IFile propertiesIFile = this.getProject().getFile(PROPERTIES_FILENAME);
ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{propertiesIFile}, null);
} catch (Exception ex) {
TomcatLauncherPlugin.log(ex.getMessage());
}
}
/**
* Run all the steps to configure a JavaProject as a TomcatProject
*/
public void fullConfiguration() throws CoreException, IOException {
if(!rootDir.equals("")) {
this.initRootDirFolder(true);
}
this.addProjectToSourcePathPref();
this.createWEBINFFolder();
this.createWEBINFSrcFolder();
this.createWorkFolder();
this.addTomcatJarToProjectClasspath();
this.addWEBINFLibJarFilesToProjectClasspath();
this.clearDefaultSourceEntries();
this.setClassesAsOutputFolder();
if(classesContainsJavaFiles()) {
this.setClassesAsSourceFolder();
}
this.setSrcAsSourceFolder();
this.setWEBINFSrcAsSourceFolder();
this.setWorkAsSourceFolder();
this.updateContext();
}
public void clearDefaultSourceEntries() throws CoreException {
IClasspathEntry[] entries = javaProject.getRawClasspath();
List cp= new ArrayList(entries.length + 1);
for(int i=0; i<entries.length; i++) {
if(entries[i].getEntryKind() != IClasspathEntry.CPE_SOURCE) {
cp.add(entries[i]);
}
}
javaProject.setRawClasspath((IClasspathEntry[])cp.toArray(new IClasspathEntry[cp.size()]), null);
}
/*
* Add servlet.jar and jasper.jar to project classpath
*/
public void addTomcatJarToProjectClasspath() throws CoreException {
TomcatBootstrap tb = TomcatLauncherPlugin.getDefault().getTomcatBootstrap();
IClasspathEntry[] entries = javaProject.getRawClasspath();
List cp = new ArrayList(entries.length + 1);
for (int i = 0; i < entries.length; i++) {
IClasspathEntry entry = entries[i];
if(!((entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) &&
(entry.getPath().toOSString().startsWith(TomcatLauncherPlugin.getDefault().getTomcatIPath().toOSString())))) {
cp.add(entry);
}
}
cp.addAll(tb.getTomcatJars());
javaProject.setRawClasspath((IClasspathEntry[])cp.toArray(new IClasspathEntry[cp.size()]), null);
}
/*
* Add all jar in WEB-INF/lib to project classpath
*/
public void addWEBINFLibJarFilesToProjectClasspath() throws CoreException {
IFolder libFolder = this.getWebInfFolder().getFolder("lib");
IResource[] libFiles = libFolder.members();
IClasspathEntry[] entries = javaProject.getRawClasspath();
List cp= new ArrayList(entries.length + 1);
cp.addAll(Arrays.asList(entries));
for(int i=0; i<libFiles.length; i++) {
if((libFiles[i].getType() == IResource.FILE) && (libFiles[i].getFileExtension().equalsIgnoreCase("jar"))) {
cp.add(JavaCore.newLibraryEntry(libFiles[i].getFullPath(), null, null));
}
}
javaProject.setRawClasspath((IClasspathEntry[])cp.toArray(new IClasspathEntry[cp.size()]), null);
}
public IFolder getWebInfFolder() {
if (getRootDirFolder() == null) {
return project.getFolder("WEB-INF");
} else {
return getRootDirFolder().getFolder("WEB-INF");
}
}
public IFolder getWorkFolder() {
// if (getRootDirFolder() == null) {
// return project.getFolder("work");
// } else {
// return getRootDirFolder().getFolder("work");
// }
return project.getFolder("work");
}
public IFolder getRootDirFolder() {
if (rootDirFolder == null) {
this.initRootDirFolder(false);
}
return rootDirFolder;
}
private void initRootDirFolder(boolean create) {
StringTokenizer tokenizer = new StringTokenizer(this.getRootDir(), "/\\:");
IFolder folder = null;
try {
while (tokenizer.hasMoreTokens()) {
String each = tokenizer.nextToken();
if (folder == null) {
folder = project.getFolder(each);
} else {
folder = folder.getFolder(each);
}
if (create) {
this.createFolder(folder);
}
}
} catch (CoreException ex) {
TomcatLauncherPlugin.log(ex);
folder = null;
setRootDir("/");
}
this.rootDirFolder = folder;
}
public void createWEBINFFolder() throws CoreException {
IFolder webinfFolder = this.getWebInfFolder();
this.createFolder(webinfFolder);
this.createFolder(webinfFolder.getFolder("classes"));
this.createFolder(webinfFolder.getFolder("lib"));
// Create .cvsignore for classes
this.createFile(webinfFolder.getFile(".cvsignore"), "classes");
}
public void createWEBINFSrcFolder() throws CoreException {
this.createFolder(this.getWebInfFolder().getFolder("src"));
}
public void createWorkFolder() throws CoreException {
IFolder folderHandle = this.getWorkFolder();
this.createFolder(folderHandle);
String tomcatVersion = TomcatLauncherPlugin.getDefault().getTomcatVersion();
if(tomcatVersion.equals(TomcatLauncherPlugin.TOMCAT_VERSION4)
|| tomcatVersion.equals(TomcatLauncherPlugin.TOMCAT_VERSION41)) {
folderHandle = folderHandle.getFolder("org");
this.createFolder(folderHandle);
folderHandle = folderHandle.getFolder("apache");
this.createFolder(folderHandle);
folderHandle = folderHandle.getFolder("jsp");
this.createFolder(folderHandle);
}
// Add a .cvsignore file in work directory
this.createFile(project.getFile(".cvsignore") , "work");
}
public void setSrcAsSourceFolder() throws CoreException {
// this.setFolderAsSourceEntry(project.getFolder("src"));
}
public void setWEBINFSrcAsSourceFolder() throws CoreException {
this.setFolderAsSourceEntry(this.getWebInfFolder().getFolder("src"), null);
}
public void setClassesAsOutputFolder() throws CoreException {
IFolder classesFolder = this.getWebInfFolder().getFolder("classes");
javaProject.setOutputLocation(classesFolder.getFullPath(),null);
}
public void setClassesAsSourceFolder() throws CoreException {
IFolder classesFolder = this.getWebInfFolder().getFolder("classes");
this.setFolderAsSourceEntry(classesFolder, null);
}
public void setWorkAsSourceFolder() throws CoreException {
this.setFolderAsSourceEntry(this.getWorkFolder(), this.getWorkFolder());
}
private void createFolder(IFolder folderHandle) throws CoreException {
try {
// Create the folder resource in the workspace
folderHandle.create(false, true, null); //new SubProgressMonitor(monitor, 500));
}
catch (CoreException e) {
// If the folder already existed locally, just refresh to get contents
if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
folderHandle.refreshLocal(IResource.DEPTH_INFINITE, null); //new SubProgressMonitor(monitor, 500));
else
throw e;
}
}
private void createFile(IFile fileHandle, String content) throws CoreException {
try {
fileHandle.create(new ByteArrayInputStream(content.getBytes()), 0, null);
}
catch (CoreException e) {
// If the file already existed locally, just refresh to get contents
if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
fileHandle.refreshLocal(IResource.DEPTH_INFINITE, null); //new SubProgressMonitor(monitor, 500));
else
throw e;
}
}
/*
* ouput could be null (project default output will be used)
*/
private void setFolderAsSourceEntry(IFolder folderHandle, IFolder output) throws CoreException {
IClasspathEntry[] entries= javaProject.getRawClasspath();
IClasspathEntry[] newEntries= new IClasspathEntry[entries.length + 1];
System.arraycopy(entries,0, newEntries,0, entries.length);
IPath outputPath = null;
if(output != null) outputPath = output.getFullPath();
IPath[] emptyPath = {};
newEntries[entries.length] = JavaCore.newSourceEntry(folderHandle.getFullPath(), emptyPath, outputPath);
javaProject.setRawClasspath(newEntries, null);
}
/**
* Add or update a Context definition
*/
public void updateContext() throws CoreException, IOException {
if(TomcatLauncherPlugin.getDefault().getConfigMode().equals(TomcatLauncherPlugin.SERVERXML_MODE)) {
this.updateServerXML();
} else {
this.updateContextFile();
}
}
/*
* Add or update a Context entry on Tomcat server.xml file
*/
private void updateServerXML() throws CoreException, IOException {
if(getUpdateXml()) {
this.backupServerXML();
String xml = FileUtil.readTextFile(getServerXML());
if(!contextExistsInXML(xml)) {
this.addContextToServerXML();
} else {
this.updateContextDefinitionInFile(getServerXML());
}
}
}
/*
* create or update a Context file
*/
private void updateContextFile() throws CoreException, IOException {
if(getUpdateXml()) {
File contextFile = this.getContextFile();
if(!contextFile.exists()) {
FileUtil.toTextFile(contextFile, this.createContextDefinition());
} else {
updateContextDefinitionInFile(contextFile);
}
}
}
private File getContextFile() {
File contextFile = new File(TomcatLauncherPlugin.getDefault().getContextsDir() +
File.separator + getContextFileName());
return contextFile;
}
private String getContextFileName() {
String contextFileName = this.getWebPath();
if(contextFileName.startsWith("/")) {
contextFileName = contextFileName.substring(1);
}
// Tomcat 5 converts / to # in context file name
contextFileName = contextFileName.replace('/', '#');
return contextFileName + ".xml";
}
public void removeContext() throws CoreException, IOException {
// Always call removeContext file because Tomcat create it automatically when using server.xml
this.removeContextFile();
if(TomcatLauncherPlugin.getDefault().getConfigMode().equals(TomcatLauncherPlugin.SERVERXML_MODE)) {
this.removeContextInServerXML();
}
}
private void removeContextFile() {
this.getContextFile().delete();
}
private void removeContextInServerXML() throws CoreException, IOException {
this.backupServerXML();
String xml = FileUtil.readTextFile(getServerXML());
if(contextExistsInXML(xml)) {
int contextTagIdx = this.getContextTagIndex(xml);
int endTagIndex = xml.indexOf("</Context>", contextTagIdx);
boolean hasNoBody = false;
if (endTagIndex < 0) {
endTagIndex = xml.indexOf('>', contextTagIdx);
hasNoBody = true;
}
else
endTagIndex+= "</Context>".length();
StringBuffer out = null;
out = new StringBuffer(xml.substring(0, contextTagIdx));
out.append(xml.substring(endTagIndex+1, xml.length()));
if (out != null) FileUtil.toTextFile(getServerXML(), out.toString());
}
}
/**
* Backup Tomcat server.xml file using the following algorithm :
* - Initial server.xml is backuped to server.xml.backup
* - Before updating server.xml create a copy named server.xml.old
*/
public void backupServerXML() throws CoreException, IOException {
String backup = getServerXMLLocation() + ".backup";
String old = getServerXMLLocation() + ".old";
if(!getServerXML().exists()) {
String msg = "Tomcat server.xml file is not found in " + getServerXML().getAbsolutePath();
Status status = new Status(IStatus.ERROR, TomcatLauncherPlugin.getDefault().getDescriptor().getUniqueIdentifier(), IStatus.ERROR, msg, null);
throw new CoreException(status);
}
File backupFile = new File(backup);
if(!backupFile.exists()) {
FileUtil.copy(getServerXML(), backupFile);
}
FileUtil.copy(getServerXML(), new File(old));
}
private File getServerXML() {
return new File(getServerXMLLocation());
}
private String getServerXMLLocation() {
return TomcatLauncherPlugin.getDefault().getConfigFile();
}
/**
* Quick and dirty implementations : using an XML Parser would be better
*/
private boolean contextExistsInXML(String xml) throws IOException {
return (getContextTagIndex(xml) != -1);
}
private int getContextTagIndex(String xml) throws IOException {
int pathIndex = xml.indexOf(getContextPath());
if(pathIndex == -1)
return -1;
int tagIndex = (xml.substring(0, pathIndex)).lastIndexOf('<');
String tag = xml.substring(tagIndex, tagIndex + 8);
if(!tag.equalsIgnoreCase(getContextStartTag()))
return -1;
return tagIndex;
}
private void addContextToServerXML() throws IOException {
String xml = FileUtil.readTextFile(getServerXML());
String tag = TomcatLauncherPlugin.getDefault().getTomcatBootstrap().getXMLTagAfterContextDefinition();
int tagIndex = xml.indexOf(tag);
int insertIndex = (xml.substring(0, tagIndex)).lastIndexOf('\n');
StringBuffer out = new StringBuffer(xml.substring(0, insertIndex));
out.append(this.createContextDefinition());
out.append(xml.substring(insertIndex, xml.length()));
FileUtil.toTextFile(getServerXML(), out.toString());
}
private String createContextDefinition() {
StringBuffer contextBuffer = new StringBuffer();
contextBuffer.append(getContextStartTag());
contextBuffer.append(' ');
contextBuffer.append(getContextPath());
contextBuffer.append(' ');
contextBuffer.append(getContextReloadable());
contextBuffer.append(' ');
contextBuffer.append(getContextDocBase());
contextBuffer.append(' ');
contextBuffer.append(getContextWorkDir());
contextBuffer.append(" />\n");
String context = contextBuffer.toString();
if (getWebClassPathEntries() != null) {
context = this.addLoaderToContext(context);
}
if(getRedirectLogger()) {
context = this.addLoggerToContext(context);
}
if(!(getExtraInfo().equals(""))) {
context = this.addExtraInfoToContext(context);
}
return context;
}
private String updateContextDefinition(String context) {
// if reloadable param not set
int reloadableIndex = context.indexOf("reloadable");
if(reloadableIndex == -1) {
context = this.addReloadableToContext(context);
} else {
context = this.updateReloadableInContext(context);
}
// update docBase if set
int docBaseIndex = context.indexOf("docBase");
if(docBaseIndex == -1) {
context = this.addDocBaseToContext(context);
} else {
context = this.updateDocBaseInContext(context);
}
// if work param not set
int workIndex = context.indexOf("workDir");
if(workIndex == -1) {
context = this.addWorkToContext(context);
} else {
context = this.updateWorkInContext(context);
}
// if loader not set
int loaderIndex = context.indexOf("<Loader");
if((loaderIndex == -1) && (getWebClassPathEntries() != null)) {
context = this.addLoaderToContext(context);
}
if((loaderIndex != -1) && (getWebClassPathEntries() == null)) {
context = this.removeLoaderInContext(context);
}
if((loaderIndex != -1) && (getWebClassPathEntries() != null)) {
context = this.updateLoaderInContext(context);
}
// if logger not set
int loggerIndex = context.indexOf("<Logger");
if((loggerIndex == -1) && getRedirectLogger()) {
context = this.addLoggerToContext(context);
}
if((loggerIndex != -1) && !getRedirectLogger()) {
context = this.removeLoggerInContext(context);
}
if((loggerIndex != -1) && getRedirectLogger()) {
context = this.updateLoggerInContext(context);
}
// Extra info
int extraInfoIndex = context.indexOf(extraBeginTag);
if((extraInfoIndex == -1) && !(getExtraInfo().equals(""))) {
context = this.addExtraInfoToContext(context);
}
if((extraInfoIndex != -1) && getExtraInfo().equals("")) {
context = this.removeExtraInfoInContext(context);
}
if((extraInfoIndex != -1) && !(getExtraInfo().equals(""))) {
context = this.updateExtraInfoInContext(context);
}
return context;
}
private void updateContextDefinitionInFile(File xmlFile) throws IOException {
String xml = FileUtil.readTextFile(xmlFile);
int contextTagIndex = this.getContextTagIndex(xml);
// If context doesn't exist do nothing
if( contextTagIndex == -1) {
return;
}
// Get context
int endContextTagIndex = xml.indexOf(">",contextTagIndex);
if(xml.charAt(endContextTagIndex-1) != '/') {
endContextTagIndex = xml.indexOf(this.getContextEndTag(), contextTagIndex) + this.getContextEndTag().length() -1;
}
String context = xml.substring(contextTagIndex, endContextTagIndex+1);
StringBuffer out = new StringBuffer(xml.substring(0, contextTagIndex));
out.append(this.updateContextDefinition(context));
out.append(xml.substring(endContextTagIndex+1));
FileUtil.toTextFile(xmlFile, out.toString());
}
private String addDocBaseToContext(String context) {
int reloadableIndex = context.indexOf(getContextReloadable());
int firstDoubleQuoteIndex = context.indexOf('"', reloadableIndex) + 1;
int docBaseIndex = context.indexOf('"',firstDoubleQuoteIndex) + 1;
StringBuffer out = new StringBuffer(context.substring(0, docBaseIndex));
out.append(' ');
out.append(getContextDocBase());
out.append(' ');
out.append(context.substring(docBaseIndex, context.length()));
return out.toString();
}
private String updateDocBaseInContext(String context) {
int docBaseIndex = context.indexOf("docBase");
int startIndex = context.indexOf('"', docBaseIndex);
int endIndex = context.indexOf('"',startIndex+1);
StringBuffer out = new StringBuffer(context.substring(0, docBaseIndex));
out.append(getContextDocBase());
out.append(context.substring(endIndex+1, context.length()));
return out.toString();
}
private String getContextReloadable(){
return ("reloadable=" + '"' + getReloadable() + '"');
}
private String addReloadableToContext(String context) {
int pathIndex = context.indexOf(getContextPath());
int firstDoubleQuoteIndex = context.indexOf('"', pathIndex) + 1;
int reloadableIndex = context.indexOf('"',firstDoubleQuoteIndex) + 1;
StringBuffer out = new StringBuffer(context.substring(0, reloadableIndex));
out.append(' ');
out.append(getContextReloadable());
out.append(' ');
out.append(context.substring(reloadableIndex, context.length()));
return out.toString();
}
private String updateReloadableInContext(String context){
int reloadableIndex = context.indexOf("reloadable");
int startIndex = context.indexOf('"',reloadableIndex);
int endIndex = context.indexOf('"',startIndex+1);
StringBuffer out = new StringBuffer(context.substring(0,reloadableIndex));
out.append(getContextReloadable());
out.append(context.substring(endIndex+1,context.length()));
return out.toString();
}
private String addWorkToContext(String context) {
int docBaseIndex = context.indexOf("docBase");
int firstDoubleQuoteIndex = context.indexOf('"',docBaseIndex) + 1;
int workIndex = context.indexOf('"', firstDoubleQuoteIndex) + 1;
StringBuffer out = new StringBuffer(context.substring(0, workIndex));
out.append(' ');
out.append(getContextWorkDir());
out.append(' ');
out.append(context.substring(workIndex, context.length()));
return out.toString();
}
private String updateWorkInContext(String context) {
int workDirIndex = context.indexOf("workDir");
int startIndex = context.indexOf('"', workDirIndex);
int endIndex = context.indexOf('"',startIndex+1);
StringBuffer out = new StringBuffer(context.substring(0, workDirIndex));
out.append(getContextWorkDir());
out.append(context.substring(endIndex+1, context.length()));
return out.toString();
}
// Add </Context> instead of />, and \n if needed
private String formatContextEndTag(String context) {
int endContextStartTagIndex = context.indexOf(">");
StringBuffer newContext = new StringBuffer();
if(context.charAt(endContextStartTagIndex-1) == '/') {
newContext.append(context.substring(0, endContextStartTagIndex-1));
newContext.append(">");
newContext.append("\n");
newContext.append(getContextEndTag());
newContext.append("\n");
context = newContext.toString();
endContextStartTagIndex--;
} else {
int endContextTagIndex = context.indexOf(getContextEndTag());
if(context.charAt(endContextTagIndex-1) != '\n') {
newContext.append(context.substring(0,endContextTagIndex));
newContext.append("\n");
newContext.append(context.substring(endContextTagIndex));
} else {
return context;
}
}
return newContext.toString();
}
private String addLoaderToContext(String context) {
context = this.formatContextEndTag(context);
int endContextStartTagIndex = context.indexOf(">");
int loaderIndex = endContextStartTagIndex + 1;
StringBuffer out = new StringBuffer(context.substring(0, loaderIndex));
out.append(getContextWebAppClassLoader());
out.append(context.substring(loaderIndex, context.length()));
return out.toString();
}
private String updateLoaderInContext(String context) {
context = this.formatContextEndTag(context);
int endContextStartTagIndex = context.indexOf(">");
int startIndex = context.indexOf("<Loader", endContextStartTagIndex);
if(context.charAt(startIndex-1) == '\t') startIndex--;
if(context.charAt(startIndex-1) == '\n') startIndex--;
int endIndex = context.indexOf("/>",startIndex+1)+1;
StringBuffer out = new StringBuffer(context.substring(0, startIndex));
out.append(getContextWebAppClassLoader());
out.append(context.substring(endIndex+1, context.length()));
return out.toString();
}
private String removeLoaderInContext(String context) {
int endContextStartTagIndex = context.indexOf(">");
int startIndex = context.indexOf("<Loader", endContextStartTagIndex);
if(context.charAt(startIndex-1) == '\t') startIndex--;
if(context.charAt(startIndex-1) == '\n') startIndex--;
int endIndex = context.indexOf("/>",startIndex+1)+1;
StringBuffer out = new StringBuffer(context.substring(0, startIndex));
out.append(context.substring(endIndex+1, context.length()));
return out.toString();
}
private String addLoggerToContext(String context) {
context = this.formatContextEndTag(context);
int endContextStartTagIndex = context.indexOf(">");
int loggerIndex = endContextStartTagIndex + 1;
StringBuffer out = new StringBuffer(context.substring(0, loggerIndex));
out.append(getContextLogger());
out.append(context.substring(loggerIndex, context.length()));
return out.toString();
}
private String updateLoggerInContext(String context) {
int endContextStartTagIndex = context.indexOf(">");
int startIndex = context.indexOf("<Logger", endContextStartTagIndex);
if(context.charAt(startIndex-1) == '\t') startIndex--;
if(context.charAt(startIndex-1) == '\n') startIndex--;
int endIndex = context.indexOf("/>",startIndex)+1;
StringBuffer out = new StringBuffer(context.substring(0, startIndex));
out.append(getContextLogger());
out.append(context.substring(endIndex+1, context.length()));
return out.toString();
}
private String removeLoggerInContext(String context) {
int endContextStartTagIndex = context.indexOf(">");
int startIndex = context.indexOf("<Logger", endContextStartTagIndex);
if(context.charAt(startIndex-1) == '\t') startIndex--;
if(context.charAt(startIndex-1) == '\n') startIndex--;
int endIndex = context.indexOf("/>",startIndex)+1;
StringBuffer out = new StringBuffer(context.substring(0, startIndex));
out.append(context.substring(endIndex+1, context.length()));
return out.toString();
}
private String addExtraInfoToContext(String context) {
context = this.formatContextEndTag(context);
int endContextStartTagIndex = context.indexOf(">");
int extraInfoIndex = endContextStartTagIndex + 1;
StringBuffer out = new StringBuffer(context.substring(0, extraInfoIndex));
out.append('\n');
out.append(extraBeginTag);
out.append('\n');
out.append(getExtraInfo());
out.append('\n');
out.append(extraEndTag);
out.append(context.substring(extraInfoIndex, context.length()));
return out.toString();
}
private String updateExtraInfoInContext(String context) {
int endContextStartTagIndex = context.indexOf(">");
int startIndex = context.indexOf(extraBeginTag, endContextStartTagIndex);
if(context.charAt(startIndex-1) == '\t') startIndex--;
if(context.charAt(startIndex-1) == '\n') startIndex--;
int extraEndTagStartIndex = context.indexOf(extraEndTag,startIndex);
StringBuffer out = new StringBuffer(context.substring(0, startIndex));
out.append('\n');
out.append(extraBeginTag);
out.append('\n');
out.append(getExtraInfo());
out.append('\n');
out.append(context.substring(extraEndTagStartIndex, context.length()));
return out.toString();
}
private String removeExtraInfoInContext(String context) {
int endContextStartTagIndex = context.indexOf(">");
int startIndex = context.indexOf(extraBeginTag, endContextStartTagIndex);
if(context.charAt(startIndex-1) == '\t') startIndex--;
if(context.charAt(startIndex-1) == '\n') startIndex--;
int extraEndTagStartIndex = context.indexOf(extraEndTag,startIndex);
StringBuffer out = new StringBuffer(context.substring(0, startIndex));
int endIndex = extraEndTagStartIndex + extraEndTag.length();
out.append(context.substring(endIndex, context.length()));
return out.toString();
}
private String getContextStartTag() {
return ("<Context");
}
private String getContextPath() {
return ("path=" + '"' + getWebPath() + '"');
}
private String getContextDocBase() {
String docBaseLocation = "";
if(getRootDirFolder() == null) {
docBaseLocation = project.getLocation().toOSString();
} else {
docBaseLocation = this.getRootDirFolder().getLocation().toOSString();
}
return ("docBase=" + '"' + docBaseLocation + '"');
}
private String getContextWorkDir() {
String workFolderLocation = this.getWorkFolder().getLocation().toOSString();
return (TomcatLauncherPlugin.getDefault().getTomcatBootstrap().getContextWorkDir(workFolderLocation));
}
private String getContextWebAppClassLoader() {
return "\n\t<Loader className=\"org.apache.catalina.loader.DevLoader\" reloadable=\"true\" debug=\"1\" useSystemClassLoaderAsParent=\"false\" />";
}
private String getContextLogger() {
return "\n\t<Logger className=\"org.apache.catalina.logger.SystemOutLogger\" verbosity=\"4\" timestamp=\"true\"/>";
}
private String getContextEndTag() {
return "</Context>";
}
public void exportToWar() throws IOException {
File warFile = new File(this.getWarLocation());
File directory = null;
if(getRootDirFolder() == null) {
directory = this.getProject().getLocation().toFile();
} else {
directory = this.getRootDirFolder().getLocation().toFile();
}
Zipper zipper = new TomcatProjectZipper(warFile, directory, getExportSource());
zipper.zip();
}
/*
* if WEB-INF classes contains Java files add it to source folders
* Otherwise Eclipse will delete all those files
*/
private boolean classesContainsJavaFiles() {
IFolder webinfFolder = this.getWebInfFolder();
IFolder classesFolder = webinfFolder.getFolder("classes");
File f = classesFolder.getLocation().toFile();
if (!f.exists()) return false;
if (!f.isDirectory()) return false;
return FileUtil.dirContainsFiles(f, "java", true);
}
/*
* A new Tomcat project should be checked by default in source path preference page
*/
private void addProjectToSourcePathPref() {
List projects = TomcatLauncherPlugin.getDefault().getProjectsInSourcePath();
ProjectListElement ple = new ProjectListElement(getProject());
if(!projects.contains(ple)) {
projects.add(ple);
TomcatLauncherPlugin.getDefault().setProjectsInSourcePath(projects);
}
}
}