/**
* Copyright 2005 Open Cloud Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mobicents.eclipslee.servicecreation.ui;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
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.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.PropertyPage;
import org.mobicents.eclipslee.servicecreation.ServiceCreationPlugin;
import org.mobicents.eclipslee.util.slee.jar.DeployableUnitJarFile;
import org.mobicents.eclipslee.util.slee.xml.ant.AntInitTargetXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntPathXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntProjectXML;
import org.mobicents.eclipslee.util.slee.xml.components.ComponentNotFoundException;
/**
* @author cath
*/
public class ExternalComponentsPropertyPage extends PropertyPage {
/*
private static final String PAGE_SETTINGS = "ExternalComponentsPropertyPage";
private static final String INDEX = "pageIndex";
*/
public boolean performOk() {
HashMap dus[] = myControl.getDeployableUnits();
// For each item currently installed in /lib/DU
// if it's in dus with Type of DU ignore
// if it's in dus with Type of Location. remove.
// if it's not in dus, remove.
/*
for (int i = 0; i < dus.length; i++) {
HashMap du = dus[i];
String name = (String) du.get("Name");
String type = (String) du.get("Type");
IPath path = (IPath) du.get("Location");
}
*/
// Get the list of currently installed DUs
IPath path = new Path("/lib/DU/");
IFolder folder = getProject().getFolder(path);
try {
if (!folder.exists())
folder.create(true, true, null);
} catch (CoreException e) {
MessageDialog.openError(new Shell(), "Error updating JAIN SLEE external components",
"It was not possible to create the /lib/DU folder.");
return false;
}
try {
IResource children[] = folder.members();
// Remove any DUs that are no longer in the dus array
// or have a Type of "Jar".
for (int i = 0; i < children.length; i++) {
IResource child = children[i];
if (child.getType() == IResource.FOLDER) {
IFolder duFolder = (IFolder) child;
HashMap map = getDU(dus, duFolder);
if (map == null || map.get("Type").equals("Jar")) {
// Remove this DU folder
removeFromClasspath(duFolder);
duFolder.delete(true, true, null);
continue;
}
// Otherwise, leave this DU alone.
}
}
// Install any DUs that are not contained in the duFolder.
int errors = 0;
for (int i = 0; i < dus.length; i++) {
HashMap du = dus[i];
if (((String) du.get("Type")).equals("Jar")) {
IFolder duFolder = getDUFolder(du, children);
if (duFolder == null) {
duFolder = folder.getFolder(new Path((String) du.get("Name")));
duFolder.create(true, true, null);
String unpackLocation = duFolder.getRawLocation().toOSString();
IPath jarLocation = (IPath) du.get("Location");
try {
DeployableUnitJarFile jarFile = new DeployableUnitJarFile(new File(jarLocation.toOSString()));
jarFile.unpack(new File(unpackLocation));
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR,
ServiceCreationPlugin.getDefault().getBundle().getSymbolicName(),
IStatus.ERROR, "Error unpacking jarfile " + jarLocation.toOSString() + " to " + unpackLocation, e);
ServiceCreationPlugin.getDefault().getLog().log(status);
errors++;
}
duFolder.refreshLocal(IResource.DEPTH_INFINITE, new ProgressMonitor(duFolder));
}
}
}
if (errors > 0) {
MessageDialog.openError(new Shell(), "Error updating JAIN SLEE external components",
"At least one deployable unit jar file could not be extracted. The plug-in will attempt to continue, but components extracted from this jar file may not be fully functional.");
}
} catch (CoreException e) {
MessageDialog.openError(new Shell(), "Error updating JAIN SLEE external components",
"An error occurred updating the JAIN SLEE external components. The plug-in will attempt to continue, but components relying on external components may not be fully functional.");
}
return true;
}
private IFolder getDUFolder(HashMap du, IResource [] children) {
String name = (String) du.get("Name");
for (int i = 0; i < children.length; i++) {
if (children[i].getType() == IResource.FOLDER) {
if (children[i].getName().equals(name))
return (IFolder) children[i];
}
}
return null;
}
private HashMap getDU(HashMap dus[], IFolder duFolder) {
String name = duFolder.getName();
for (int i = 0; i < dus.length; i++) {
if (dus[i].get("Name").equals(name))
return dus[i];
}
return null;
}
private IProject getProject() {
IAdaptable adaptable = getElement();
if (adaptable != null) {
IJavaElement elem = (IJavaElement) adaptable.getAdapter(IJavaElement.class);
if (elem instanceof IJavaProject)
return ((IJavaProject) elem).getProject();
}
return null;
}
protected Control createContents(Composite parent) {
noDefaultAndApplyButton();
Control result;
IProject project = getProject();
if (project == null || !isSLEEProject(project)) {
// Shouldn't happen.
return null;
}
if (!project.isOpen()) {
result = createForClosedProject(parent);
} else {
result = createWithSLEE(parent, project);
}
Dialog.applyDialogFont(result);
return result;
}
private boolean isSLEEProject(IProject project) {
try {
return project.hasNature(ServiceCreationPlugin.NATURE_ID);
} catch (CoreException e) {
ServiceCreationPlugin.log("CoreException thrown in isSLEEProject(): " + project);
}
return false;
}
private Control createForClosedProject(Composite parent) {
Label label = new Label(parent, SWT.LEFT);
label.setText("This project must be opened before its properties can be set.");
setValid(true);
myControl = null;
return label;
}
private Control createWithSLEE(Composite parent, IProject project) {
myControl = new ExternalComponentsControl();
myControl.init(JavaCore.create(project));
return myControl.createControl(parent);
}
private void removeFromClasspath(IFolder folder) {
try {
Vector entries = new Vector();
IResource resources[] = folder.members();
for (int i = 0; i < resources.length; i++) {
if (resources[i].getType() == IResource.FILE
&& resources[i].getName().endsWith(".jar"))
entries.add(resources[i]);
if (resources[i].getType() == IResource.FOLDER)
removeFromClasspath((IFolder) resources[i]);
}
IProject project = getProject();
IJavaProject javaProject = JavaCore.create(project);
IClasspathEntry old[] = javaProject.getRawClasspath();
Vector newCP = new Vector();
for (int i = 0; i < old.length; i++) {
// Get the IPath of the jar file in this classpath entry
IPath jarPath = old[i].getPath();
// Is this a LIBRARY entry
if (old[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
// Is this LIBRARY entry in this folder
if (folder.getFullPath().isPrefixOf(jarPath)) {
continue; // Don't add this jar file back to the path.
}
}
// Add this jar file back into the path.
newCP.add(old[i]);
}
IClasspathEntry newEntries[] = (IClasspathEntry []) newCP.toArray(new IClasspathEntry[newCP.size()]);
javaProject.setRawClasspath(newEntries, null);
removeFromBuildFile(javaProject, entries);
} catch (CoreException e) {
ServiceCreationPlugin.log(e);
}
}
private void addToClasspath(IFolder folder) {
try {
Vector entries = new Vector();
IResource resources[] = folder.members();
for (int i = 0; i < resources.length; i++) {
if (resources[i].getType() == IResource.FILE) {
if (resources[i].getName().endsWith(".jar")) {
entries.add(resources[i]);
}
}
if (resources[i].getType() == IResource.FOLDER) {
addToClasspath((IFolder) resources[i]);
}
}
IProject project = getProject();
IJavaProject javaProject = JavaCore.create(project);
IClasspathEntry old[] = javaProject.getRawClasspath();
IClasspathEntry newEntries[] = new IClasspathEntry[entries.size() + old.length];
System.arraycopy(old, 0, newEntries, 0, old.length);
for (int i = 0; i < entries.size(); i++) {
IResource resource = (IResource) entries.get(i);
newEntries[old.length + i] = JavaCore.newLibraryEntry(resource.getFullPath(), null, null);
}
javaProject.setRawClasspath(newEntries, null);
addToBuildFile(javaProject, entries);
} catch (CoreException e) {
MessageDialog.openWarning(new Shell(), "Error Updating Classpath", "It was not possible to add the deployable unit's jar files to the classpath. File completion will be unavailable.");
}
}
private void addToBuildFile(IJavaProject javaProject, Vector entries) {
try {
IPath antBuildPath = new Path("/build.xml");
IFile antFile = javaProject.getProject().getFile(antBuildPath);
AntProjectXML projectXML = new AntProjectXML(antFile.getContents());
AntInitTargetXML initXML = (AntInitTargetXML) projectXML.getTarget("init");
AntPathXML pathXML = null;
try {
pathXML = initXML.getPathID("ExternalComponents");
} catch (ComponentNotFoundException e) {
pathXML = initXML.addPath("ExternalComponents");
}
for (int i = 0; i < entries.size(); i++) {
IResource resource = (IResource) entries.get(i);
pathXML.addPathElement(resource.getProjectRelativePath().toOSString());
}
antFile.setContents(projectXML.getInputStreamFromXML(), true, true, null);
} catch (Exception e) {
MessageDialog.openWarning(new Shell(), "Error updating build file",
"An error was encountered updating the project's build file. The plug-in will attempt to continue, but the build file may need some manual editing.");
}
}
private void removeFromBuildFile(IJavaProject javaProject, Vector entries) {
try {
IPath antBuildPath = new Path("/build.xml");
IFile antFile = javaProject.getProject().getFile(antBuildPath);
AntProjectXML projectXML = new AntProjectXML(antFile.getContents());
AntInitTargetXML initXML = (AntInitTargetXML) projectXML.getTarget("init");
AntPathXML pathXML = null;
try {
pathXML = initXML.getPathID("ExternalComponents");
} catch (ComponentNotFoundException e) {
pathXML = initXML.addPath("ExternalComponents");
}
for (int i = 0; i < entries.size(); i++) {
IResource resource = (IResource) entries.get(i);
pathXML.removePathElement(resource.getProjectRelativePath().toOSString());
}
antFile.setContents(projectXML.getInputStreamFromXML(), true, true, null);
} catch (Exception e) {
MessageDialog.openWarning(new Shell(), "Error updating build file",
"An error was encountered updating the project's build file. The plug-in will attempt to continue, but the build file may need some manual editing.");
}
}
private class ProgressMonitor implements IProgressMonitor {
public ProgressMonitor(IFolder folder) {
duFolder = folder;
}
public void setTaskName(String str) {}
public void done() {
addToClasspath(duFolder);
}
public void setCanceled(boolean b) {}
public void beginTask(String str, int i) {}
public void internalWorked(double d) {}
public void subTask(String str) {}
public boolean isCanceled() { return false; }
public void worked(int i) {}
private IFolder duFolder;
}
private ExternalComponentsControl myControl;
}