001 /****************************************************************************** 002 * Copyright (C) MActor Developers. All rights reserved. * 003 * ---------------------------------------------------------------------------* 004 * This file is part of MActor. * 005 * * 006 * MActor is free software; you can redistribute it and/or modify * 007 * it under the terms of the GNU General Public License as published by * 008 * the Free Software Foundation; either version 2 of the License, or * 009 * (at your option) any later version. * 010 * * 011 * MActor is distributed in the hope that it will be useful, * 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 014 * GNU General Public License for more details. * 015 * * 016 * You should have received a copy of the GNU General Public License * 017 * along with MActor; if not, write to the Free Software * 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * 019 ******************************************************************************/ 020 package org.mactor.ui.gui.actions; 021 022 import java.awt.BorderLayout; 023 import java.awt.FlowLayout; 024 import java.awt.Frame; 025 import java.io.File; 026 import java.io.FileInputStream; 027 import java.io.FileWriter; 028 import java.io.IOException; 029 import java.io.InputStream; 030 import java.net.MalformedURLException; 031 import java.net.URL; 032 import java.util.LinkedList; 033 import java.util.List; 034 035 import javax.swing.AbstractAction; 036 import javax.swing.JButton; 037 import javax.swing.JCheckBox; 038 import javax.swing.JDialog; 039 import javax.swing.JLabel; 040 import javax.swing.JPanel; 041 import javax.swing.JTextField; 042 043 import org.dom4j.Element; 044 import org.mactor.brokers.soap.wsdl.Wsdl; 045 import org.mactor.brokers.soap.wsdl.Wsdl.OperationInfo; 046 import org.mactor.framework.MactorException; 047 import org.mactor.framework.spec.ActionSpec; 048 import org.mactor.framework.spec.MessagePublishSpec; 049 import org.mactor.framework.spec.MessageReceiveSpec; 050 import org.mactor.framework.spec.MessageRespondSpec; 051 import org.mactor.framework.spec.MessageSubscribeSpec; 052 import org.mactor.framework.spec.ProjectContext; 053 import org.mactor.ui.gui.AsyncAction; 054 import org.mactor.ui.gui.GuiUtil; 055 import org.mactor.ui.gui.project.GuiAction; 056 import org.mactor.ui.gui.project.ProjectController; 057 import org.mactor.ui.gui.project.ProjectNodeType; 058 import org.mactor.ui.gui.project.ProjectTreeNode; 059 import org.mactor.ui.gui.project.ProjectTreeNodeBuilder; 060 import org.mactor.ui.gui.project.editors.SimpleFormPanel; 061 062 public class CreateChannelsFromWsdlAction implements GuiAction { 063 public boolean isPermitted(ProjectTreeNode selectedTreeNode, ProjectController projectController, String[] parameters) { 064 return selectedTreeNode != null && (selectedTreeNode.getNodeType().equals(ProjectNodeType.MBC_CHANNEL) || selectedTreeNode.getNodeType().equals(ProjectNodeType.MBC_MESSAGE_BROKER)); 065 } 066 public void perform(ProjectTreeNode selectedTreeNode, ProjectController projectController, String[] parameters) throws MactorException { 067 // http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl 068 ProjectTreeNode targetNode = null; 069 if (selectedTreeNode.getNodeType().equals(ProjectNodeType.MBC_CHANNEL)) 070 targetNode = selectedTreeNode.getParentNode(); 071 else if (selectedTreeNode.getNodeType().equals(ProjectNodeType.MBC_MESSAGE_BROKER)) 072 targetNode = selectedTreeNode; 073 else 074 throw new MactorException("Invalid request"); 075 new WsdlWizard(projectController.getControllerFrame(), targetNode, projectController).setVisible(true); 076 } 077 public class WsdlWizard extends JDialog { 078 JCheckBox generateTestsButton = new JCheckBox("Generate Test Stubs"); 079 JCheckBox generateMockBatteryButton = new JCheckBox("Generate Mock Battery (only for incoming)"); 080 ProjectController projectController; 081 SimpleFormPanel form = new SimpleFormPanel(); 082 JTextField url = new JTextField(); 083 ProjectTreeNode targetNode; 084 JButton closeButton = new JButton(new AbstractAction("Close") { 085 public void actionPerformed(java.awt.event.ActionEvent arg0) { 086 dispose(); 087 }; 088 }); 089 JButton importIncomingButton = new JButton(new AsyncAction("Create Incoming Channels from WSDL (MActor working as a Server)", false, new AsyncAction.AsyncRunnable() { 090 public void run() { 091 generateChannels(true); 092 } 093 })); 094 JButton importOutgoingButton = new JButton(new AsyncAction("Create Outgoing Channels from WSDL (MActor working as a Client)", false, new AsyncAction.AsyncRunnable() { 095 public void run() { 096 generateChannels(false); 097 } 098 })); 099 String template; 100 public void generateChannels(boolean incoming) { 101 if (url.getText() == null || url.getText().trim().length() == 0) { 102 GuiUtil.showInfo(this, "URL must be specifed!"); 103 return; 104 } 105 try { 106 List<String> tests = new LinkedList<String>(); 107 File wsdlFile = null; 108 URL wsdlUrl = null; 109 Wsdl wsdl = null; 110 try { 111 wsdlUrl = new URL(url.getText().trim()); 112 } catch (Exception e) { 113 wsdlFile = new File(url.getText().trim()); 114 } 115 if (wsdlFile != null) 116 wsdl = new Wsdl(wsdlFile); 117 else 118 wsdl = new Wsdl(wsdlUrl); 119 String wsdlFileName = null; 120 String name = null; 121 if (incoming) { 122 if (wsdl.getOperations().size() > 0) 123 name = wsdl.getOperations().get(0).getService(); 124 else 125 name = System.currentTimeMillis() + ""; 126 InputStream is = null; 127 if (wsdlFile != null) 128 is = new FileInputStream(wsdlFile); 129 else 130 is = new URL(url.getText()).openStream(); 131 wsdlFileName = writeToDisk(is, name); 132 } 133 template = CreateEntityAction.getTemplateContent("MBC_CHANNEL"); 134 for (Wsdl.OperationInfo oi : wsdl.getOperations()) { 135 ProjectTreeNode node = ProjectTreeNodeBuilder.createNewNode(ProjectNodeType.MBC_CHANNEL, template); 136 Element e = (Element) node.getModelObject(); 137 e.addAttribute("requires_response", true + ""); 138 String channel = null; 139 String uri = null; 140 if (incoming) { 141 try { 142 URL u = new URL(oi.getTargetURL()); 143 uri = "http://localhost:8877" + u.getPath(); 144 if (u.getQuery() != null) 145 uri = uri + "?" + u.getQuery(); 146 } catch (MalformedURLException me) { 147 uri = oi.getTargetURL(); 148 } 149 channel = "Incoming" + oi.getTargetMethodName(); 150 addValue(e, "WsdlFile", wsdlFileName); 151 } else { 152 uri = oi.getTargetURL(); 153 channel = "Outgoing" + oi.getTargetMethodName(); 154 } 155 addValue(e, "SoapAction", oi.getSoapActionURI()); 156 addValue(e, "SoapEndpoint", uri); 157 e.attribute("name").setValue(channel); 158 node = ProjectTreeNodeBuilder.createNewNode(ProjectNodeType.MBC_CHANNEL, e.asXML()); 159 projectController.insertNodeIntoNode(targetNode, node); 160 if (generateTestsButton.isSelected()) { 161 tests.add(createTest(incoming, channel, name, oi)); 162 } 163 } 164 if (incoming && generateMockBatteryButton.isSelected()) 165 createMockBattery(name, tests); 166 projectController.reloadProject(); 167 } catch (Exception e) { 168 e.printStackTrace(); 169 GuiUtil.showGuiError(WsdlWizard.this, e); 170 } 171 } 172 private void addValue(Element e, String name, String value) { 173 Element v = e.addElement("value"); 174 v.addAttribute("name", name); 175 v.setText(value); 176 } 177 String testTemplate; 178 private String createTest(boolean incoming, String channelName, String serviceName, OperationInfo oi) throws MactorException, IOException { 179 if (testTemplate == null) 180 testTemplate = CreateEntityAction.getTemplateContent("T_TEST"); 181 ProjectTreeNode test = ProjectTreeNodeBuilder.createNewNode(ProjectNodeType.T_TEST, testTemplate); 182 String fn = ProjectContext.getGlobalInstance().getNextFilename("Test" + channelName + ".xml", false); 183 test.rename(fn); 184 Element testElement = (Element) test.getModelObject(); 185 if (incoming) 186 initIncomingTest(testElement, channelName, oi); 187 else 188 initOutgoingTest(testElement, channelName, oi); 189 test.save(); 190 return fn; 191 } 192 private void initIncomingTest(Element testElement, String channel, OperationInfo oi) throws MactorException, IOException { 193 MessageSubscribeSpec msSpec = new MessageSubscribeSpec(); 194 msSpec.setChannel(channel); 195 msSpec.setName("SubscribeTo" + channel); 196 msSpec.getMessageSelector().setCommand("java:org.mactor.extensions.xml.XPathIgnoreNsRegExpMessageSelector"); 197 MessageRespondSpec mrespSpec = new MessageRespondSpec(); 198 mrespSpec.setName("RespondTo" + channel); 199 mrespSpec.getMessageBuilder().setTemplatePath(createTemplateFile(oi.getService(), oi.getTargetMethodName(), "Response", oi.getNamespaceURI())); 200 mrespSpec.getMessageBuilder().setCommand("java:org.mactor.extensions.xml.XPathTemplateMessageBuilder"); 201 MessageReceiveSpec mrSpec = new MessageReceiveSpec(); 202 mrSpec.setName("ReceiveFrom" + channel); 203 mrSpec.setMinMessageCount(1); 204 mrSpec.setMaxTimeoutSeconds(600000); 205 mrSpec.setMessageSubscribeNodeName("SubscribeTo" + channel); 206 mrSpec.addSpecNode(mrespSpec); 207 ActionSpec aSpec = new ActionSpec(); 208 aSpec.setName("VerifyReceivedMessage"); 209 aSpec.setCommand("java:org.mactor.extensions.xml.XPathIgnoreNsRegExpValidator"); 210 msSpec.addToElement(testElement); 211 mrSpec.addToElement(testElement); 212 aSpec.addToElement(testElement); 213 } 214 private String createTemplateFile(String service, String messageName, String suffix, String targetNs) throws IOException { 215 String dirName = service + "_templates"; 216 File dir = ProjectContext.getGlobalInstance().getAbsolutePath(dirName); 217 if (!dir.exists()) 218 dir.mkdirs(); 219 String name = dirName + "/" + messageName + suffix + ".xml"; 220 File file = ProjectContext.getGlobalInstance().getAbsolutePath(name); 221 FileWriter fw = new FileWriter(file); 222 fw.write("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns=\"" + targetNs + "\">"); 223 fw.write("\n <soapenv:Body>"); 224 fw.write("\n <" + messageName + ">"); 225 fw.write("\n\n <!--insert the message body here -->"); 226 fw.write("\n\n </" + messageName + ">"); 227 fw.write("\n </soapenv:Body>"); 228 fw.write("\n</soapenv:Envelope>"); 229 // 230 fw.close(); 231 return name; 232 } 233 private void initOutgoingTest(Element testElement, String channel, OperationInfo oi) throws MactorException, IOException { 234 MessagePublishSpec mpSpec = new MessagePublishSpec(); 235 mpSpec.setName("PublishTo" + channel); 236 mpSpec.setChannel(channel); 237 mpSpec.getMessageBuilder().setTemplatePath(createTemplateFile(oi.getService(), oi.getTargetMethodName(), "Request", oi.getNamespaceURI())); 238 mpSpec.getMessageBuilder().setCommand("java:org.mactor.extensions.xml.XPathTemplateMessageBuilder"); 239 ActionSpec aSpec = new ActionSpec(); 240 aSpec.setName("VerifyReceivedMessage"); 241 aSpec.setCommand("java:org.mactor.extensions.xml.XPathIgnoreNsRegExpValidator"); 242 mpSpec.addToElement(testElement); 243 aSpec.addToElement(testElement); 244 } 245 private void createMockBattery(String serviceName, List<String> tests) throws MactorException { 246 String template = CreateEntityAction.getTemplateContent("TM_MOCK_BATTERY"); 247 ProjectTreeNode tm = ProjectTreeNodeBuilder.createNewNode(ProjectNodeType.TM_MOCK_BATTERY, template); 248 Element e = (Element) tm.getModelObject(); 249 for (String t : tests) 250 e.addElement("test").addAttribute("name", t); 251 tm.save(); 252 } 253 private String writeToDisk(InputStream is, String name) throws MactorException, IOException { 254 File f = new File(ProjectContext.getGlobalInstance().getProjectConfigDir() + "/" + name + ".wsdl"); 255 FileWriter fw = new FileWriter(f); 256 for (;;) { 257 int val = is.read(); 258 if (val < 0) 259 break; 260 fw.write(val); 261 } 262 fw.close(); 263 return f.getName(); 264 } 265 public WsdlWizard(Frame parentFrame, ProjectTreeNode targetNode, ProjectController projectController) { 266 super(parentFrame, true); 267 setTitle("Create SOAP Channels From WSDL"); 268 this.targetNode = targetNode; 269 this.projectController = projectController; 270 setLayout(new BorderLayout()); 271 form.add(new JLabel("WSDL URI:")); 272 form.add(url); 273 JPanel p1 = new JPanel(new FlowLayout()); 274 p1.add(importIncomingButton); 275 JPanel p2 = new JPanel(new FlowLayout()); 276 p2.add(importOutgoingButton); 277 form.add(generateTestsButton); 278 form.add(generateMockBatteryButton); 279 JPanel bottomPanel = new JPanel(new FlowLayout()); 280 form.add(p1); 281 form.add(p2); 282 bottomPanel.add(closeButton); 283 add(form, BorderLayout.CENTER); 284 add(bottomPanel, BorderLayout.SOUTH); 285 pack(); 286 } 287 } 288 }