/*
* Copyright (c) 2008 Extreme! Lab, Indiana University. All rights reserved.
*
* This software is open source. See the bottom of this file for the license.
*
* $Id: DynamicNodeWindow.java,v 1.2 2008/09/03 18:44:54 cherath Exp $
*/
package edu.indiana.extreme.xbaya.graph.dynamic.gui;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.impl.common.JarHelper;
import org.xmlpull.infoset.XmlElement;
import org.xmlpull.infoset.XmlNamespace;
import org.xmlpull.v1.builder.XmlBuilderException;
//import com.sun.tools.javac.Main;
import xsul.XmlConstants;
import xsul.wsdl.WsdlException;
import xsul5.wsdl.WsdlDefinitions;
import edu.indiana.extreme.xbaya.XBayaEngine;
import edu.indiana.extreme.xbaya.XBayaException;
import edu.indiana.extreme.xbaya.XBayaRuntimeException;
import edu.indiana.extreme.xbaya.component.gui.ComponentTreeNode;
import edu.indiana.extreme.xbaya.component.registry.ComponentRegistryLoader;
import edu.indiana.extreme.xbaya.component.registry.URLComponentRegistry;
import edu.indiana.extreme.xbaya.graph.DataPort;
import edu.indiana.extreme.xbaya.graph.Graph;
import edu.indiana.extreme.xbaya.graph.Node;
import edu.indiana.extreme.xbaya.graph.Port;
import edu.indiana.extreme.xbaya.graph.dynamic.BasicTypeMapping;
import edu.indiana.extreme.xbaya.graph.dynamic.DynamicNode;
import edu.indiana.extreme.xbaya.graph.dynamic.DynamicServiceCreator;
import edu.indiana.extreme.xbaya.graph.dynamic.SchemaCompilerUtil;
import edu.indiana.extreme.xbaya.graph.ws.WSNode;
import edu.indiana.extreme.xbaya.graph.ws.WSPort;
import edu.indiana.extreme.xbaya.gui.GridPanel;
import edu.indiana.extreme.xbaya.gui.XBayaDialog;
import edu.indiana.extreme.xbaya.gui.XBayaLabel;
import edu.indiana.extreme.xbaya.gui.XBayaTextArea;
/**
* @author Chathura Herath
*/
public class DynamicNodeWindow {
/**
* CLASSES_DIR
*/
private static final String CLASSES_DIR = "classes";
/**
* SRC_DIR
*/
private static final String SRC_DIR = "src";
/**
* SKELETON_FOLDER_NAME
*/
private static final String SKELETON_FOLDER_NAME = SRC_DIR;
/**
* CLASS
*/
private static final String CLASS = "class";
/**
* PACKAGE
*/
private static final String PACKAGE = "package";
/**
* LINE
*/
private static final String LINE = "\n";
/**
* TAB
*/
private static final String TAB = "\t";
/**
* SPACE
*/
private static final String SPACE = " ";
private XBayaEngine engine;
private DynamicNode node;
private XBayaDialog dialog;
private XBayaTextArea javaCodeTxtArea;
private String typesPath;
private String functionStr;
private JCheckBox checkBox;
/**
* Constructs a WSNodeWindow.
*
* @param engine
* The XBayaEngine
* @param node
*/
public DynamicNodeWindow(XBayaEngine engine, DynamicNode node) {
this.engine = engine;
this.node = node;
initGUI();
}
/**
* Shows the notification.
*
* @param event
* The notification to show
*/
public void show() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int ret = fileChooser.showOpenDialog(this.engine.getGUI().getFrame());
if (JFileChooser.APPROVE_OPTION != ret) {
throw new XBayaRuntimeException(
"Cannot proceed without valid directory");
}
File selectedDir = fileChooser.getSelectedFile();
File rootDir = new File(selectedDir, "xbaya");
deleteDir(rootDir);
rootDir.mkdir();
File srcDir = new File(rootDir, SRC_DIR);
srcDir.mkdir();
File classesDir = new File(rootDir, CLASSES_DIR);
classesDir.mkdir();
initSchema(rootDir, srcDir, srcDir);
this.javaCodeTxtArea.setText(generateClass());
this.dialog.show();
if(this.checkBox.isSelected()){
deployWebservice();
}else{
this.compileAndRegisterJar(rootDir, srcDir, srcDir);
}
}
private void deployWebservice(){
try {
DynamicServiceCreator factory = new DynamicServiceCreator("http://129.79.246.108:8080/axis2/services/ServiceCreator?wsdl");
String code = this.javaCodeTxtArea.getText();
factory.createService(code);
URLComponentRegistry registry = null;
Thread.sleep(10000);
registry = new URLComponentRegistry(new URI("http://129.79.246.108:8080/axis2/services/"+getClassName(code)+"?wsdl"));
new ComponentRegistryLoader(engine).load(registry);
Node newNode = this.engine.getGUI().getGraphCanvas().addNode(((ComponentTreeNode)registry.getComponentTree().getFirstLeaf()).getComponentReference().getComponent(), this.node.getPosition());
List<DataPort> inputPorts = newNode.getInputPorts();
Graph graph = this.engine.getGUI().getGraphCanvas().getGraph();
for (int i=0; i<inputPorts.size(); ++i) {
graph.addEdge(this.node.getInputPort(i).getFromPort(), inputPorts.get(i));
}
List<DataPort> outputPorts = newNode.getOutputPorts();
for (int i=0; i<outputPorts.size(); ++i) {
List<Port> toPorts = this.node.getOutputPort(i).getToPorts();
for (Port port : toPorts) {
graph.removeEdge(this.node.getOutputPort(i), port);
graph.addEdge(outputPorts.get(i), port);
}
}
this.engine.getWorkflow().removeNode(this.node);
} catch (Exception e) {
this.engine.getErrorWindow().error(e);
}
}
private void hide() {
this.dialog.hide();
}
private void initGUI() {
BasicTypeMapping.reset();
this.javaCodeTxtArea = new XBayaTextArea();
XBayaLabel operationLabel = new XBayaLabel("Operation",
this.javaCodeTxtArea);
GridPanel infoPanel = new GridPanel();
infoPanel.add(operationLabel);
infoPanel.add(this.javaCodeTxtArea);
checkBox = new JCheckBox("Export as webservice");
infoPanel.add(new XBayaLabel("", checkBox));
infoPanel.add(checkBox);
infoPanel.layout(2, 2, 0, 0);
JButton okButton = new JButton("OK");
okButton.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
hide();
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(okButton);
this.dialog = new XBayaDialog(this.engine, this.node.getName(),
infoPanel, buttonPanel);
this.dialog.setDefaultButton(okButton);
}
private String generateClass() {
String ret = "package edu.indiana.extreme.xbaya;";
ret += LINE + LINE;
ret += "public class DefaultClassName{";
ret += LINE + LINE + TAB + "public";
String function = "";
List<Port> toNodes = this.node.getOutputPort(0).getToPorts();
XmlElement returnElement = null;
QName returnType = null;
if (toNodes.size() == 0) {
function += SPACE + "void";
} else {
if (toNodes.size() == 1 && toNodes.get(0) instanceof WSPort) {
WSPort outPort = (WSPort) toNodes.get(0);
returnElement = outPort.getComponentPort().getElement();
returnType = outPort.getType();
} else {
throw new XBayaRuntimeException(
"Unhandled port type for Dynamic component or to many outputs");
}
for (Port port : toNodes) {
if (toNodes.get(0) instanceof DataPort) {
if (!returnType.equals(((DataPort) toNodes.get(0))
.getType())) {
throw new XBayaRuntimeException(
"Dynamic output port connected to input ports of different types.");
}
} else {
throw new XBayaRuntimeException(
"Unhandled port type for Dynamic component");
}
}
int index = BasicTypeMapping.getSimpleTypeIndex(returnElement);
if (-1 != index) {
function += SPACE + BasicTypeMapping.getTypeName(index);
} else {
throw new XBayaRuntimeException(
"WIll be fixed with complex type mappign");
}
}
function += SPACE + "operationName(";
List<DataPort> inputPorts = this.node.getInputPorts();
boolean first = true;
// variable list in function prototype
for (DataPort inPort : inputPorts) {
Port fromPort = inPort.getFromPort();
if (fromPort instanceof WSPort) {
WSPort wsPort = (WSPort) fromPort;
XmlElement element = wsPort.getComponentPort().getElement();
// QName inType = ((DataPort) fromPort).getType();
int typeIndex = BasicTypeMapping.getSimpleTypeIndex(element);
if (-1 != typeIndex) {
if (first) {
first = false;
} else {
function += SPACE + ",";
}
function += BasicTypeMapping.getTypeName(typeIndex) + SPACE
+ BasicTypeMapping.getTypeVariableName(typeIndex);
} else {
throw new XBayaRuntimeException(
"Complex Type occured:This will be fixed!!!!!");
}
} else {
throw new XBayaRuntimeException(
"Dynamic Node connected to non data port");
}
}
function += ")" ;
ret += function;
this.functionStr = function;
// body
ret += "{" + LINE + LINE;
if(null != returnElement ){
ret += TAB + TAB + "return" + SPACE
+ BasicTypeMapping.getTypeDefault(BasicTypeMapping.getSimpleTypeIndex(returnElement)) + ";";
}
ret += LINE;
ret += TAB + "}";
ret += LINE + "}";
return ret;
}
private void initSchema(File rootDir, File srcDir, File classesDir) {
List<DataPort> inputPorts = node.getInputPorts();
for (DataPort inPort : inputPorts) {
Port fromPort = inPort.getFromPort();
Node fromNode = inPort.getFromNode();
if (fromNode instanceof WSNode) {
WSNode fromWsNode = (WSNode) fromNode;
if (null != fromPort && fromPort instanceof DataPort) {
DataPort fromDataPort = (DataPort) fromPort;
WsdlDefinitions wsdl = engine.getWorkflow().getWSDLs().get(
fromWsNode.getWSDLID());
System.out.println(xsul5.XmlConstants.BUILDER
.serializeToString(wsdl.xml()));
Iterator<XmlNamespace> itr = wsdl.xml().namespaces()
.iterator();
try {
XmlElement schema = wsdl.getTypes().element("schema")
.clone();
// do not change the following ordering of setting
// namespaces.
schema
.setNamespace(xsul5.XmlConstants.BUILDER
.newNamespace("http://www.w3.org/2001/XMLSchema"));
while (itr.hasNext()) {
XmlNamespace next = itr.next();
if (!"".equals(next.getPrefix())
&& null != next.getPrefix()) {
schema.setAttributeValue("xmlns:"
+ next.getPrefix(), next.getName());
}
}
try {
xsul5.XmlConstants.BUILDER
.serializeToOutputStream(schema,
new FileOutputStream(rootDir
.getCanonicalPath()
+ File.separatorChar
+ "types.xsd"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(fromDataPort.getType());
typesPath = rootDir.getCanonicalPath() + File.separatorChar
+ "mytype.jar";
String[] args = new String[] {
"-d",
classesDir.getCanonicalPath(),
"-src",
srcDir.getCanonicalPath(),
"-out",
typesPath,
rootDir.getCanonicalPath() + File.separatorChar
+ "types.xsd" };
SchemaCompilerUtil.compile(args);
} catch (XmlBuilderException e) {
this.engine.getErrorWindow().error(e);
} catch (CloneNotSupportedException e) {
this.engine.getErrorWindow().error(e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
throw new XBayaRuntimeException(
"Unknown port for code generation" + fromPort);
}
} else {
throw new XBayaRuntimeException(
"Unknown from node for code generation" + fromNode);
}
}
}
private void compileAndRegisterJar(File rootDir, File srcDir, File classesDir) {
// String code = this.javaCodeTxtArea.getText();
// String packageName = getPackageName(code);
// String className = getClassName(code);
// try {
// File classFile = new File(srcDir.getCanonicalPath()+ File.separator
// + packageName.replace('.', File.separatorChar)
// + File.separator + className+".java");
// classFile.getParentFile().mkdirs();
//
// FileWriter out = new FileWriter(classFile);
// out.write(code);
// out.flush();
// out.close();
//
// JarHelper jarHelper = new JarHelper();
// jarHelper.unjarDir(new File(this.typesPath), classesDir);
//
// Main.compile(new String[]{classFile.getCanonicalPath(), "-d", classesDir.getCanonicalPath()});
// File implJar = new File(rootDir, "impl.jar");
// jarHelper.jarDir( classesDir, implJar);
// node.setImplURL(implJar.toURL());
// node.setOperationName(getOperationName(code));
// node.setClassName(getPackageName(code)+"."+getClassName(code));
// } catch (IOException e) {
// this.engine.getErrorWindow().error(e);
// }
}
private String getOperationName(String code){
String[] publicSplit = code.split("public");
String searchStr = this.functionStr.substring(this.functionStr.indexOf("("), this.functionStr.indexOf(")"));
int index = -1;
for (int i=0; i<publicSplit.length; ++i) {
if(publicSplit[i].indexOf(searchStr) != -1){
index = i;
break;
}
}
if(index == -1){
throw new XBayaRuntimeException("Operation name not found");
}
return publicSplit[index].substring(0, publicSplit[index].indexOf(searchStr)).trim().split(" ")[1];
}
private String getPackageName(String code) {
return code.substring(code.indexOf(PACKAGE) + PACKAGE.length(),
code.indexOf(";")).trim();
}
private String getClassName(String code) {
return code.substring(code.indexOf(CLASS) + CLASS.length(),
code.indexOf("{")).trim().split(" ")[0].trim();
}
private boolean hasComplexTypes() {
List<DataPort> inputPorts = node.getInputPorts();
boolean ret = true;
for (DataPort inPort : inputPorts) {
Port fromPort = inPort.getFromPort();
Node fromNode = inPort.getFromNode();
if (fromNode instanceof WSNode) {
WSNode fromWsNode = (WSNode) fromNode;
if (null != fromPort && fromPort instanceof DataPort) {
DataPort fromDataPort = (DataPort) fromPort;
} else {
return false;
}
} else {
return false;
}
}
return false;
}
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
}
/*
* Indiana University Extreme! Lab Software License, Version 1.2
*
* Copyright (c) 2008 The Trustees of Indiana University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) All redistributions of source code must retain the above copyright notice,
* the list of authors in the original source code, this list of conditions and
* the disclaimer listed in this license;
*
* 2) All redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the disclaimer listed in this license in
* the documentation and/or other materials provided with the distribution;
*
* 3) Any documentation included with all redistributions must include the
* following acknowledgement:
*
* "This product includes software developed by the Indiana University Extreme!
* Lab. For further information please visit http://www.extreme.indiana.edu/"
*
* Alternatively, this acknowledgment may appear in the software itself, and
* wherever such third-party acknowledgments normally appear.
*
* 4) The name "Indiana University" or "Indiana University Extreme! Lab" shall
* not be used to endorse or promote products derived from this software without
* prior written permission from Indiana University. For written permission,
* please contact http://www.extreme.indiana.edu/.
*
* 5) Products derived from this software may not use "Indiana University" name
* nor may "Indiana University" appear in their name, without prior written
* permission of the Indiana University.
*
* Indiana University provides no reassurances that the source code provided
* does not infringe the patent or any other intellectual property rights of any
* other entity. Indiana University disclaims any liability to any recipient for
* claims brought by any other entity based on infringement of intellectual
* property rights or otherwise.
*
* LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
* WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
* NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
* INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
* INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
* "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
* LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
* ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
* GENERATED USING SOFTWARE.
*/