/**
* 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.popup.actions;
import java.util.HashMap;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.mobicents.eclipslee.servicecreation.util.ClassUtil;
import org.mobicents.eclipslee.servicecreation.util.EclipseUtil;
import org.mobicents.eclipslee.servicecreation.util.SbbFinder;
import org.mobicents.eclipslee.servicecreation.wizards.sbb.SbbEventsDialog;
import org.mobicents.eclipslee.util.SLEE;
import org.mobicents.eclipslee.util.Utils;
import org.mobicents.eclipslee.util.slee.xml.components.ComponentNotFoundException;
import org.mobicents.eclipslee.util.slee.xml.components.EventXML;
import org.mobicents.eclipslee.util.slee.xml.components.SbbEventXML;
import org.mobicents.eclipslee.util.slee.xml.components.SbbXML;
import org.mobicents.eclipslee.xml.EventJarXML;
import org.mobicents.eclipslee.xml.SbbJarXML;
/**
* @author cath
*/
public class EditSbbEventsAction implements IActionDelegate {
public EditSbbEventsAction() {
}
public EditSbbEventsAction(String sbbID) {
this.sbbID = sbbID;
}
public void setActivePart(IAction action, IWorkbenchPart targetPart) {}
public void run(IAction action) {
initialize();
if (dialog == null) {
MessageDialog.openError(new Shell(), "Error Modifying Service Building Block", getLastError());
return;
}
if (dialog.open() == Window.OK) {
try {
IProgressMonitor monitor = null;
HashMap newEvents[] = dialog.getSelectedEvents();
// foreach event in xml
// if not in newEvents
// delete event from xml and sbb abstract class
SbbEventXML oldEvents[] = sbb.getEvents();
for (int old = 0; old < oldEvents.length; old++) {
SbbEventXML oldEvent = oldEvents[old];
if (findEvent(oldEvent, newEvents) == null) {
// Nuke this event.
String scopedName = oldEvent.getScopedName();
sbb.removeEvent(oldEvent);
ClassUtil.removeMethodFromClass(abstractFile, "on" + Utils.capitalize(scopedName));
ClassUtil.removeMethodFromClass(abstractFile, "fire" + Utils.capitalize(scopedName));
ClassUtil.removeMethodFromClass(abstractFile, "on" + Utils.capitalize(scopedName) + "InitialEventSelect");
}
}
// foreach new event
// if getEvent(name, vendor, version) -- update
// else createEvent -- make receive, fire, ies methods
for (int i = 0; i < newEvents.length; i++) {
HashMap event = newEvents[i];
EventJarXML eventJarXML = (EventJarXML) event.get("XML");
EventXML eventXML = eventJarXML.getEvent((String) event.get("Name"), (String) event.get("Vendor"), (String) event.get("Version"));
SbbEventXML sbbEventXML = sbb.getEvent((String) event.get("Name"), (String) event.get("Vendor"), (String) event.get("Version"));
String scopedName = (String) event.get("Scoped Name");
String direction = (String) event.get("Direction");
boolean initialEvent = ((Boolean) event.get("Initial Event")).booleanValue();
String [] selectors = (String []) event.get("Initial Event Selectors");
if (sbbEventXML == null) {
sbbEventXML = sbb.addEvent(eventXML);
sbbEventXML.setScopedName(scopedName);
sbbEventXML.setEventDirection(direction);
sbbEventXML.setInitialEvent(initialEvent);
for (int j = 0; j < selectors.length; j++) {
if (selectors[j].equals("Custom")) {
String methodName = "on" + Utils.capitalize(scopedName) + "InitialEventSelect";
ClassUtil.addMethodToClass(abstractFile,
"\tpublic InitialEventSelector " + methodName + "(InitialEventSelector ies) {\n\treturn ies;\n\t}\n");
sbbEventXML.setInitialEventSelectorMethod(methodName);
} else {
sbbEventXML.addInitialEventSelector(selectors[j]);
}
}
if (direction.indexOf("Receive") != -1)
ClassUtil.addMethodToClass(abstractFile,
"\tpublic void on" + Utils.capitalize(scopedName) + "(" + eventXML.getEventClassName() + " event, ActivityContextInterface aci) {\n\n\t}\n");
if (direction.indexOf("Fire") != -1)
ClassUtil.addMethodToClass(abstractFile,
"\tpublic abstract void fire" + Utils.capitalize(scopedName) + "(" + eventXML.getEventClassName() + " event, ActivityContextInterface aci, Address address);");
} else {
// Modify the existing event.
String oldDirection = sbbEventXML.getEventDirection();
String oldScopedName = sbbEventXML.getScopedName();
// Deal with any changes in event direction
if (!oldDirection.equals(direction)) {
// Direction has changed.
if (direction.indexOf("Fire") == -1) {
// Nuke any fire method.
ClassUtil.removeMethodFromClass(abstractFile,
"fire" + Utils.capitalize(oldScopedName));
} else {
// Create a fire method
if (oldDirection.indexOf("Fire") == -1)
ClassUtil.addMethodToClass(abstractFile,
"\tpublic abstract void fire" + Utils.capitalize(scopedName) + "(" + eventXML.getEventClassName() + " event, ActivityContextInterface aci, Address address);\n\n");
}
if (direction.indexOf("Receive") == -1) {
// nuke any receive method
ClassUtil.removeMethodFromClass(abstractFile,
"on" + Utils.capitalize(oldScopedName));
} else {
// Create the event handler
if (oldDirection.indexOf("Receive") == -1)
ClassUtil.addMethodToClass(abstractFile,
"\tpublic void on" + Utils.capitalize(scopedName) + "(" + eventXML.getEventClassName() + " event, ActivityContextInterface aci) {\n\n\t}\n\n");
}
sbbEventXML.setEventDirection(direction);
}
// Is this an initial event?
sbbEventXML.setInitialEvent(initialEvent);
// Remove old initial event selectors (N.B. not custom IES)
String oldSelectors[] = sbbEventXML.getInitialEventSelectors();
for (int j = 0; j < oldSelectors.length; j++) {
sbbEventXML.removeInitialEventSelector(oldSelectors[j]);
}
// Add new initial event selectors (N.B. not custom IES)
boolean customIES = false;
if (initialEvent) {
for (int j = 0; j < selectors.length; j++) {
if (selectors[j].equals("Custom")) {
customIES = true; // For next part.
continue;
}
sbbEventXML.addInitialEventSelector(selectors[j]);
}
}
// Deal with the IES -- first was there one originally
String oldIESMethod = sbbEventXML.getInitialEventSelectorMethod();
// Secondly, do we need one now?
if (oldIESMethod != null && customIES == false) {
// Nuke the IES
sbbEventXML.setInitialEventSelectorMethod(null);
ClassUtil.removeMethodFromClass(abstractFile, oldIESMethod);
} else {
if (oldIESMethod == null && customIES == true) {
// Create the IES
String methodName = "on" + Utils.capitalize(scopedName) + "InitialEventSelect";
ClassUtil.addMethodToClass(abstractFile,
"\tpublic InitialEventSelector " + methodName + "(InitialEventSelector ies) {\n\t\treturn ies;\n\t}\n");
sbbEventXML.setInitialEventSelectorMethod(methodName);
}
}
// Deal with any change in the scoped name.
if (!oldScopedName.equals(scopedName)) {
sbbEventXML.setScopedName(scopedName);
// Rename the fire, receive and ies methods if they exist.
ClassUtil.renameMethodInClass(abstractFile,
"on" + Utils.capitalize(oldScopedName),
"on" + Utils.capitalize(scopedName));
ClassUtil.renameMethodInClass(abstractFile,
"fire" + Utils.capitalize(oldScopedName),
"fire" + Utils.capitalize(scopedName));
ClassUtil.renameMethodInClass(abstractFile,
"on" + Utils.capitalize(oldScopedName) + "InitialEventSelect",
"on" + Utils.capitalize(scopedName) + "InitialEventSelect");
}
}
}
// Save the XML
xmlFile.setContents(sbbJarXML.getInputStreamFromXML(), true, true, monitor);
} catch (Exception e) {
MessageDialog.openError(new Shell(), "Error Modifying SBB", "An error occurred while modifying the service building block. It must be modified manually.");
e.printStackTrace();
System.err.println(e.toString() + ": " + e.getMessage());
return;
}
}
}
/**
* Get the SBBXML data object for the current selection.
*
*/
private void initialize() {
String projectName = null;
sbb = null;
sbbJarXML = null;
if (selection == null && selection.isEmpty()) {
setLastError("Please select an SBB's Java or XML file first.");
return;
}
if (!(selection instanceof IStructuredSelection)) {
setLastError("Please select an SBB's Java or XML file first.");
return;
}
IStructuredSelection ssel = (IStructuredSelection) selection;
if (ssel.size() > 1) {
setLastError("This plugin only supports editing of one service building block at a time.");
return;
}
// Get the first (and only) item in the selection.
Object obj = ssel.getFirstElement();
if (obj instanceof IFile) {
ICompilationUnit unit = null;
try {
unit = JavaCore.createCompilationUnitFrom((IFile) obj);
} catch (Exception e) {
// Suppress Exception. The next check checks for null unit.
}
if (unit != null) { // .java file
sbbJarXML = SbbFinder.getSbbJarXML(unit);
if (sbbJarXML == null) {
setLastError("Unable to find the corresponding sbb-jar.xml for this SBB.");
return;
}
try {
sbb = sbbJarXML.getSbb(EclipseUtil.getClassName(unit));
} catch (org.mobicents.eclipslee.util.slee.xml.components.ComponentNotFoundException e) {
setLastError("Unable to find the corresponding sbb-jar.xml for this SBB.");
return;
}
// Set 'file' to the SBB XML file, not the Java file.
xmlFile = SbbFinder.getSbbJarXMLFile(unit);
abstractFile = SbbFinder.getSbbAbstractClassFile(unit);
if (xmlFile == null) {
setLastError("Unable to find SBB XML.");
return;
}
if (abstractFile == null) {
setLastError("Unable to find SBB abstract class file.");
return;
}
projectName = unit.getJavaProject().getProject().getName();
} else {
IFile file = (IFile) obj;
String name = SLEE.getName(sbbID);
String vendor = SLEE.getVendor(sbbID);
String version = SLEE.getVersion(sbbID);
try {
sbbJarXML = new SbbJarXML(file);
} catch (Exception e) {
setLastError("Unable to find the corresponding sbb-jar.xml for this SBB.");
return;
}
try {
sbb = sbbJarXML.getSbb(name, vendor, version);
} catch (ComponentNotFoundException e) {
setLastError("This SBB is not defined in this XML file.");
return;
}
xmlFile = file;
abstractFile = SbbFinder.getSbbAbstractClassFile(xmlFile, name, vendor, version);
if (abstractFile == null) {
setLastError("Unable to find SBB abstract class file.");
return;
}
unit = (ICompilationUnit) JavaCore.create(abstractFile);
projectName = unit.getJavaProject().getProject().getName();
}
} else {
setLastError("Unsupported object type: " + obj.getClass().toString());
return;
}
SbbEventXML[] events = sbb.getEvents();
dialog = new SbbEventsDialog(new Shell(), events, projectName);
return;
}
/**
* @see IActionDelegate#selectionChanged(IAction, ISelection)
*/
public void selectionChanged(IAction action, ISelection selection) {
this.selection = selection;
}
private void setLastError(String error) {
if (error == null) {
lastError = "Success";
} else {
lastError = error;
}
}
private String getLastError() {
String error = lastError;
setLastError(null);
return error;
}
private HashMap findEvent(SbbEventXML event, HashMap selectedEvents[]) {
for (int i = 0; i < selectedEvents.length; i++) {
String name = (String) selectedEvents[i].get("Name");
String vendor = (String) selectedEvents[i].get("Vendor");
String version = (String) selectedEvents[i].get("Version");
if (event.getName().equals(name)
&& event.getVendor().equals(vendor)
&& event.getVersion().equals(version)) {
return selectedEvents[i];
}
}
return null;
}
private String sbbID;
private SbbJarXML sbbJarXML;
private SbbXML sbb;
private String lastError;
private ISelection selection;
private SbbEventsDialog dialog;
private IFile xmlFile;
private IFile abstractFile;
}