package com.sysdeo.eclipse.tomcat;
/*
* (c) Copyright Martin Kahr, Sysdeo SA 2001, 2002.
* All Rights Reserved.
*/
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.CheckedListDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
/**
* This class adds a selection list to the tomcat plugin project configuration.
*
* the selection is read and written to the file ".webclasspath" in the
* root of the project.
*
* A special WebAppClassLoader implementation for tomcat 4.x loads the
* generated file during startup of the webapplication.
*
* @version 1.0
* @author Martin Kahr (martin.kahr@brainment.com)
*/
public class TomcatProjectWebclasspathPropertyPage {
private static final String WEBAPP_CLASSPATH_FILENAME = ".webclasspath";
private CheckedListDialogField cpList;
private Button webClassPathCheck;
private WebClassPathEntries entries;
private ArrayList visitedProjects = new ArrayList();
private TomcatProjectPropertyPage page;
public TomcatProjectWebclasspathPropertyPage(TomcatProjectPropertyPage page) {
this.page = page;
}
public IJavaProject getJavaProject() {
try {
return page.getJavaProject();
} catch (CoreException e) {
TomcatLauncherPlugin.log(e);
return null;
}
}
/** okay has been pressed */
public boolean performOk() {
java.util.List newSelection = cpList.getCheckedElements();
try {
if (webClassPathCheck.getSelection()==true) {
page.getTomcatProject().setWebClassPathEntries(new WebClassPathEntries(newSelection));
} else {
page.getTomcatProject().setWebClassPathEntries(null);
}
page.getTomcatProject().saveProperties();
} catch(Exception ex) {
TomcatLauncherPlugin.log(ex);
return false;
}
return true;
}
public Control getControl(Composite ctrl) {
boolean activated = isActive();
Composite group = new Composite(ctrl, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
group.setLayout(layout);
webClassPathCheck = new Button(group, SWT.CHECK | SWT.LEFT);
webClassPathCheck.setText(TomcatPluginResources.PROPERTIES_PAGE_PROJECT_ACTIVATE_DEVLOADER_LABEL);
webClassPathCheck.setEnabled(true);
webClassPathCheck.setSelection(activated);
webClassPathCheck.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent ev) {
if (webClassPathCheck.getSelection()) {
entries = new WebClassPathEntries();
cpList.setEnabled(true);
} else {
entries = null;
cpList.setEnabled(false);
}
}
});
cpList = new CheckedListDialogField(null, new String[]{"Check All", "Uncheck All"},new LabelProvider(){});
cpList.setEnabled(activated);
cpList.setCheckAllButtonIndex(0);
cpList.setUncheckAllButtonIndex(1);
ArrayList classPathEntries = new ArrayList();
getClassPathEntries(getJavaProject(), classPathEntries);
java.util.List selected = null;
if (entries != null)
{
selected = entries.getList();
// check for entries which are still in the list but no more in classpath entries list and remove them
for (Iterator it = selected.iterator(); it.hasNext();) {
String sel = (String) it.next();
if (classPathEntries.contains(sel) == false)
{
it.remove();
}
}
}
// sort the entries
Collections.sort(classPathEntries);
/* Quick hack :
* Using reflection for compatability with Eclipse 2.1 and 3.0 M9
*
* Old code :
* cpList.setElements(classPathEntries);
* if (entries != null) {
* cpList.setCheckedElements(entries.getList());
* }
*/
this.invokeForCompatibility("setElements", classPathEntries);
if (entries != null) {
this.invokeForCompatibility("setCheckedElements", entries.getList());
}
cpList.doFillIntoGrid(group, 3);
LayoutUtil.setHorizontalGrabbing(cpList.getListControl(null));
return group;
}
public void getClassPathEntries(IJavaProject prj, ArrayList data) {
IClasspathEntry[] entries = null;
IPath outputPath = null;
try {
outputPath = prj.getOutputLocation();
add(data, prj.getOutputLocation());
entries = prj.getRawClasspath();
// entries = prj.getResolvedClasspath(false);
} catch(JavaModelException e) {
TomcatLauncherPlugin.log(e);
}
if (entries != null) {
getClassPathEntries(entries, prj, data, outputPath);
}
}
private void getClassPathEntries(IClasspathEntry[] entries, IJavaProject prj, ArrayList data, IPath outputPath) {
for (int i = 0; i < entries.length; i++) {
IClasspathEntry entry = entries[i];
if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
String prjName = entry.getPath().lastSegment();
if(!visitedProjects.contains(prjName)) {
visitedProjects.add(prjName);
getClassPathEntries(getJavaProject().getJavaModel().getJavaProject(prjName), data);
}
} else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
add(data, entry.getPath());
} else if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
IPath path = entry.getOutputLocation();
if(path != null && !path.equals(outputPath))
{
add(data, path);
}
} else if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
if (!entry.getPath().toString().equals("org.eclipse.jdt.launching.JRE_CONTAINER")) {
// Add container itself, as TomcatBootstrap can actually process them
// at the moment
// Basically, users will be able to choose b/w the whole container
// or some artifacts enclosed by it
add(data, entry.getPath());
// Expand container and add its content as individual
// elements
IClasspathContainer container;
try {
container =
JavaCore.getClasspathContainer(entry.getPath(), prj);
} catch (JavaModelException e) {
TomcatLauncherPlugin.log(
"failed to obtain classpath container '" + entry.getPath() + "'" +
" for project '" + prj.getProject().getName() + "'");
TomcatLauncherPlugin.log(e);
container = null;
}
if (container != null) {
getClassPathEntries(container.getClasspathEntries(), prj, data, outputPath);
}
}
} else {
add(data, entry.getPath());
}
}
}
private void add(ArrayList data, IPath entry) {
String path = entry.toFile().toString().replace('\\','/');
// ignore tomcat's own libs and the JRE paths..
if(!data.contains(path) && path.indexOf("TOMCAT_HOME") == -1 && path.indexOf("JRE_CONTAINER") == -1 && path.indexOf("JRE_LIB") == -1)
{
data.add(path.replace('\\','/'));
}
}
/** reads the selected entries from persistent storage */
private java.util.List readSelectedEntries() {
ArrayList selected = new ArrayList();
IFile file = getJavaProject().getProject().getFile(new Path(WEBAPP_CLASSPATH_FILENAME));
if (file == null) return selected;
File cpFile = file.getLocation().makeAbsolute().toFile();
if (cpFile.exists()) {
FileReader reader = null;
try {
reader = new FileReader(cpFile);
LineNumberReader lr = new LineNumberReader(reader);
String line = null;
while((line = lr.readLine()) != null) {
selected.add(line);
}
} catch(IOException ioEx) {
TomcatLauncherPlugin.log(ioEx);
} finally {
if (reader != null) try { reader.close(); } catch(Exception ignored) {}
}
}
return selected;
}
private boolean isActive() {
entries = null;
try {
TomcatProject project = page.getTomcatProject();
if (project == null) return false;
entries = project.getWebClassPathEntries();
} catch(CoreException coreEx) {
}
return (entries != null);
}
/* Quick hack :
* Using reflection for compatability with Eclipse 2.1 and 3.0 M9
*/
private void invokeForCompatibility(String methodName, List projects) {
Class clazz = cpList.getClass();
Class[] collectionParameter = {Collection.class};
try {
Method method = clazz.getMethod(methodName, collectionParameter);
Object[] args = {projects};
method.invoke(cpList, args);
} catch (Exception e) {
Class[] listParameter = {List.class};
try {
Method method = clazz.getMethod(methodName, listParameter);
Object[] args = {projects};
method.invoke(cpList, args);
} catch (Exception ex) {
TomcatLauncherPlugin.log(ex);
}
}
}
}