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 }