/*******************************************************************************
* Copyright (c) 2011 Grupo de Sistemas Inteligentes (GSI) - DIT UPM
*
* 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
*******************************************************************************/
package es.upm.dit.gsi.eclipse.jadex.adfmanager.wizards;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.operation.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.*;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.ide.IDE;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import es.upm.dit.gsi.eclipse.jadex.adfmanager.wizards.AddPlanWizardPage1;
import es.upm.dit.gsi.eclipse.jadex.util.ImageFactory;
/**
* Wizard for adding a new Plan to the selected agent
*
* It has got 3 pages:
* - Page1: Agent selection and asking for automatic class generation
* - Page2: Plan details
* - Page3: Parameter selection
*
* It supports automatic class generation of the needed java classes.
*
* @author Pablo Muñoz
* @TODO verify if the Plan exists in the selected file. Add support for triggers (no event support developed yet) and conditions *
*/
public class AddPlanWizard extends Wizard implements INewWizard {
private AddPlanWizardPage1 page1;
private AddPlanWizardPage2 page2;
private ParameterSelectionWizardPage page3;
private ISelection selection;
/**
* Constructor for Agent Wizard.
*/
public AddPlanWizard(ISelection selection) {
super();
setNeedsProgressMonitor(true);
this.selection = selection;
setDefaultPageImageDescriptor(ImageFactory.getImageDescriptor(ImageFactory.GSI_BANNER_SMALL));
}
/**
* Adding the page to the wizard.
*/
public void addPages() {
page1 = new AddPlanWizardPage1(selection);
page1.setTitle("Add Plan Wizard");
page2 = new AddPlanWizardPage2(selection);
page2.setTitle("Add Plan Wizard");
page3 = new ParameterSelectionWizardPage(selection);
page3.setTitle("Add Plan Wizard");
addPage(page1);
addPage(page2);
addPage(page3);
}
/**
* This method is called when 'Finish' button is pressed in
* the wizard. We will create an operation and run it
* using wizard as execution context.
*/
public boolean performFinish() {
final IFile agentFile = page1.getAgentFile();
final IFolder sourceFolder = page1.getSourceFolder();
final String packageName = page1.getPackageName();
final String planName = page2.getPlanName();
final String planPriority = page2.getPlanPriority();
final String planClassName = page1.getPlanClassName();
final String planFileName = page1.getPlanFileName();
final String planType = page2.getPlanType();
//Goal parameters
final Parameter[] parameters = page3.getParameters();
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
try {
doFinish(agentFile, sourceFolder, packageName,planName, planPriority, planClassName, planFileName, planType, parameters, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, false, op);
} catch (InterruptedException e) {
return false;
} catch (InvocationTargetException e) {
Throwable realException = e.getTargetException();
MessageDialog.openError(getShell(), "Error", realException.getMessage());
return false;
}
return true;
}
/**
* The worker method. It will find the container, create the
* file if missing or just replace its contents, and open
* the editor on the newly created file.
*/
private void doFinish(
IFile agentFile,
IFolder sourceFolder,
String packageName,
String planName,
String planPriority,
String planClassName,
String planFileName,
String planType,
Parameter[] parameters,
IProgressMonitor monitor)
throws CoreException {
monitor.beginTask("Modificating ADF File", 2);
try{
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = docBuilder.parse(agentFile.getRawLocation().toOSString());
//Get the plans element
Node plans = doc.getElementsByTagName("plans").item(0);
Element newPlan = doc.createElement("plan");
newPlan.setAttribute("name", planName);
if(planPriority != null) newPlan.setAttribute("priority", planPriority);
Element body = doc.createElement("body");
if(planClassName != null) body.setAttribute("class", planClassName);
//if(planFileName != null) body.setAttribute("impl", planFileName);
if(planType != null) body.setAttribute("type", planType);
newPlan.appendChild(body);
//Set the Plan Parameters
if(parameters != null){
for(Parameter p : parameters){
Element parameter = doc.createElement("parameter");
parameter.setAttribute("name", p.get_name());
parameter.setAttribute("class", p.get_class());
parameter.setAttribute("description", p.get_description());
parameter.setAttribute("direction",p.get_direction());
parameter.setAttribute("dynamic", p.get_dynamic());
parameter.setAttribute("exported",p.get_exported());
parameter.setAttribute("optional", p.get_optional());
parameter.setAttribute("transient",p.get_transient());
parameter.setAttribute("updaterate", p.get_updaterate());
if(p.get_value().length() > 0){
Element value = doc.createElement("value");
value.setTextContent(p.get_value());
parameter.appendChild(value);
}
newPlan.appendChild(parameter);
}
}
plans.appendChild(newPlan);
//TO-DO Implement Auxiliary.WriteToXML
Auxiliary.writeToXML(doc, agentFile, monitor);
}
catch(Exception e1){
e1.printStackTrace();
}
System.out.println("Done");
if(planClassName != null){
IJavaProject project = JavaCore.create(agentFile.getProject());
IPackageFragmentRoot rootFragment = project.getPackageFragmentRoot(sourceFolder);
IPackageFragment fragment = rootFragment.createPackageFragment(packageName, false,monitor);
String source = getPlanSource(fragment.getElementName(),planClassName);
final ICompilationUnit cu = fragment.createCompilationUnit(planFileName, source, false, null);
cu.getResource().setDerived(true, monitor);
monitor.setTaskName("Opening file for editing...");
Display.getDefault ().asyncExec
(new Runnable ()
{
public void run ()
{
try
{
JavaUI.openInEditor (cu);
}
catch (Exception e)
{
e.printStackTrace ();
}
}
}
);
cu.close();
}
final IFile file = agentFile;
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
IWorkbenchPage page =
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
IEditorPart editor = IDE.openEditor(page, file, true);
ICommandService cmdService = (ICommandService) editor.getSite().getService(ICommandService.class);
Command format = cmdService.getCommand("org.eclipse.wst.sse.ui.format.document");
if (format.isDefined()) {
try {
format.executeWithChecks(new ExecutionEvent());
}
catch(Exception e1){
}
}
} catch (PartInitException e) {
}
}
});
agentFile.refreshLocal(IFile.DEPTH_INFINITE, monitor);
monitor.worked(1);
}
private String getPlanSource(String packageName, String planName){
StringBuffer source = new StringBuffer();
source.append("package " + packageName + ";\n");
source.append("\n");
source.append("import jadex.bdi.runtime.Plan" + ";\n");
source.append("\n");
source.append("public class " + planName + " extends Plan {" + "\n");
source.append("\t" + "public void body(){" + "\n");
source.append("\t" + "\t" + "/*" + "\n");
source.append("\t" + "\t" + "* TO DO" + "\n");
source.append("\t" + "\t" + "*/" + "\n");
source.append("\t" + "}" + "\n");
source.append("}" );
return source.toString();
}
/**
* We will accept the selection in the workbench to see if
* we can initialize from it.
* @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
*/
public void init(IWorkbench workbench, IStructuredSelection selection) {
this.selection = selection;
}
}