/*
* Copyright 2004-2014 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.panels.iface;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.text.BadLocationException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.wsdl.BindingOperation;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.jdesktop.swingx.JXTable;
import org.w3c.dom.Element;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.actions.SoapUIPreferencesAction;
import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.actions.iface.CreateWsdlDocumentationAction;
import com.eviware.soapui.impl.wsdl.actions.iface.ExportDefinitionAction;
import com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIAnalyzeAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIReportPanel;
import com.eviware.soapui.impl.wsdl.support.HelpUrls;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.iface.Interface;
import com.eviware.soapui.model.support.ProjectListenerAdapter;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.SwingActionDelegate;
import com.eviware.soapui.support.components.JEditorStatusBar;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.soapui.support.components.MetricsPanel;
import com.eviware.soapui.support.components.MetricsPanel.MetricType;
import com.eviware.soapui.support.components.MetricsPanel.MetricsSection;
import com.eviware.soapui.support.components.ProgressDialog;
import com.eviware.soapui.support.types.StringList;
import com.eviware.soapui.support.xml.SyntaxEditorUtil;
import com.eviware.soapui.support.xml.XmlUtils;
import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
import com.eviware.x.dialogs.Worker;
import com.eviware.x.dialogs.XProgressDialog;
import com.eviware.x.dialogs.XProgressMonitor;
import com.jgoodies.forms.builder.ButtonBarBuilder;
/**
* DesktopPanel for WsdlInterface. Loads all referenced wsdls/xsds for the
* specified WsdlInterface and displays these in seperate tabs
*
* @author Ole.Matzura
*/
public class WsdlInterfaceDesktopPanel extends ModelItemDesktopPanel<WsdlInterface> {
private final static Logger logger = Logger.getLogger(WsdlInterfaceDesktopPanel.class);
private JTabbedPane partTabs;
private List<RSyntaxTextArea> editors = new ArrayList<RSyntaxTextArea>();
private JTree tree;
private Map<String, DefaultMutableTreeNode> groupNodes = new HashMap<String, DefaultMutableTreeNode>();
private Map<String, TreePath> pathMap = new HashMap<String, TreePath>();
private List<TreePath> navigationHistory = new ArrayList<TreePath>();
private StringList targetNamespaces = new StringList();
private int historyIndex;
private boolean navigating;
private JEditorStatusBar statusBar;
private DefaultMutableTreeNode rootNode;
private DefaultTreeModel treeModel;
private InternalProjectListener projectListener;
private final WsdlInterface iface;
private JPanel wsiPanel;
private WSIReportPanel reportPanel;
private SaveWsiReportAction saveWsiReportAction;
private MetricsPanel metrics;
private boolean updatingInterface;
private OperationsTableModel operationsTableModel;
public WsdlInterfaceDesktopPanel(WsdlInterface iface) {
super(iface);
this.iface = iface;
try {
iface.getWsdlContext().loadIfNecessary();
buildUI();
} catch (Exception e) {
UISupport.showErrorMessage(e);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SoapUI.getDesktop().closeDesktopPanel(WsdlInterfaceDesktopPanel.this);
}
});
}
}
private void buildUI() {
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Overview", buildInterfaceOverviewTab());
tabs.addTab("Service Endpoints", buildEndpointsTab());
tabs.addTab("WSDL Content", buildWsdlContentTab());
tabs.addTab("WS-I Compliance", buildWSITab());
add(UISupport.createTabPanel(tabs, true), BorderLayout.CENTER);
}
private Component buildWSITab() {
wsiPanel = new JPanel(new BorderLayout());
wsiPanel.setBackground(Color.WHITE);
wsiPanel.setOpaque(true);
wsiPanel.add(builderWsiToolbar(), BorderLayout.NORTH);
return wsiPanel;
}
private Component builderWsiToolbar() {
JXToolBar toolbar = UISupport.createToolbar();
toolbar.addFixed(UISupport.createToolbarButton(new RunWSIAction()));
toolbar.addFixed(UISupport.createToolbarButton(new WSIOptionsAction()));
toolbar.addRelatedGap();
saveWsiReportAction = new SaveWsiReportAction();
toolbar.addFixed(UISupport.createToolbarButton(saveWsiReportAction));
toolbar.addGlue();
toolbar.addFixed(UISupport.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.WSI_COMPLIANCE_HELP_URL)));
return toolbar;
}
private Component buildInterfaceOverviewTab() {
metrics = new MetricsPanel();
JXToolBar toolbar = UISupport.createSmallToolbar();
toolbar.addGlue();
toolbar.addFixed(UISupport
.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.INTERFACE_OVERVIEW_HELP_URL)));
metrics.add(toolbar, BorderLayout.NORTH);
MetricsSection section = metrics.addSection("WSDL Definition");
try {
section.addMetric("WSDL URL", MetricType.URL).set(iface.getDefinition());
section.addMetric("Namespace").set(iface.getBindingName().getNamespaceURI());
section.addMetric("Binding").set(iface.getBindingName().getLocalPart());
section.addMetric("SOAP Version").set(iface.getSoapVersion().toString());
section.addMetric("Style").set(iface.getStyle());
section.addMetric("WS-A version").set(iface.getWsaVersion());
} catch (Exception e) {
UISupport.showErrorMessage(e);
}
section.finish();
metrics.addSection("Definition Parts");
section = metrics.addSection("Operations");
operationsTableModel = new OperationsTableModel();
JXTable table = section.addTable(operationsTableModel);
table.getColumn(1).setPreferredWidth(60);
table.getColumn(2).setPreferredWidth(60);
section.finish();
table.packColumn(3, 10);
if (table.getColumn(3).getPreferredWidth() < 250) {
table.getColumn(3).setPreferredWidth(250);
}
return new JScrollPane(metrics);
}
private Component buildEndpointsTab() {
return iface.getProject().getEndpointStrategy().getConfigurationPanel(iface);
}
private JComponent buildWsdlContentTab() {
partTabs = new JTabbedPane();
partTabs.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
rootNode = new DefaultMutableTreeNode(iface.getName());
treeModel = new DefaultTreeModel(rootNode);
tree = new JTree(treeModel);
tree.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
tree.setExpandsSelectedPaths(true);
tree.addTreeSelectionListener(new InternalTreeSelectionListener());
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
if (arg0.getClickCount() > 1) {
TreePath selectionPath = tree.getSelectionPath();
if (selectionPath != null) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
Object userObject = treeNode.getUserObject();
if (userObject instanceof InspectItem) {
InspectItem item = (InspectItem) userObject;
if (item != null && item.selector != null) {
item.selector.selectNode(item);
}
}
}
}
}
});
JScrollPane scrollPane = new JScrollPane(tree);
JSplitPane split = UISupport.createHorizontalSplit(scrollPane, UISupport.createTabPanel(partTabs, true));
split.setDividerLocation(250);
split.setResizeWeight(0.3);
initTreeModel(iface);
JPanel panel = new JPanel(new BorderLayout());
panel.add(split, BorderLayout.CENTER);
panel.add(buildWsdlTabToolbar(), BorderLayout.PAGE_START);
statusBar = new JEditorStatusBar();
panel.add(statusBar, BorderLayout.PAGE_END);
setPreferredSize(new Dimension(600, 500));
projectListener = new InternalProjectListener();
iface.getProject().addProjectListener(projectListener);
return panel;
}
private void initTreeModel(WsdlInterface iface) {
try {
if (iface.getWsdlContext().loadIfNecessary()) {
XProgressDialog progressDialog = UISupport.getDialogs().createProgressDialog("Loading Defintion", 3,
"Initializing definition..", true);
Loader loader = new Loader(iface);
if (progressDialog != null) {
progressDialog.setCancelLabel("Run in background");
}
progressDialog.run(loader);
loader = null;
treeModel.nodeStructureChanged(rootNode);
}
} catch (Exception e) {
SoapUI.logError(e);
}
}
private Component buildWsdlTabToolbar() {
JXToolBar toolbar = UISupport.createToolbar();
toolbar.addFixed(UISupport.createToolbarButton(new BackwardAction()));
toolbar.addFixed(UISupport.createToolbarButton(new ForwardAction()));
toolbar.addUnrelatedGap();
JButton button = UISupport.createToolbarButton(SwingActionDelegate.createDelegate(
UpdateInterfaceAction.SOAPUI_ACTION_ID, getModelItem(), null, "/updateDefinition.gif"));
button.setText(null);
toolbar.addFixed(button);
button = UISupport.createToolbarButton(SwingActionDelegate.createDelegate(
ExportDefinitionAction.SOAPUI_ACTION_ID, getModelItem(), null, "/exportDefinition.gif"));
button.setText(null);
toolbar.addFixed(UISupport.createToolbarButton(SwingActionDelegate.createDelegate(
CreateWsdlDocumentationAction.SOAPUI_ACTION_ID, iface, null, "/export.gif")));
toolbar.addFixed(button);
toolbar.addGlue();
button = UISupport.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.WSDL_CONTENT_HELP_URL));
button.setText(null);
toolbar.addFixed(button);
return toolbar;
}
private final class InternalProjectListener extends ProjectListenerAdapter {
@Override
public void interfaceUpdated(Interface iface) {
if (iface == getModelItem()) {
updatingInterface = true;
partTabs.removeAll();
tree.setSelectionRow(-1);
rootNode.removeAllChildren();
editors.clear();
groupNodes.clear();
pathMap.clear();
targetNamespaces.clear();
initTreeModel((WsdlInterface) iface);
operationsTableModel.fireTableDataChanged();
updatingInterface = false;
}
}
}
private final class InternalTreeSelectionListener implements TreeSelectionListener {
public void valueChanged(TreeSelectionEvent e) {
TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
if (newLeadSelectionPath != null) {
if (!navigating) {
// if we have moved back in history.. reverse before adding
while (historyIndex < navigationHistory.size() - 1) {
TreePath path = navigationHistory.remove(navigationHistory.size() - 1);
navigationHistory.add(historyIndex++, path);
}
navigationHistory.add(newLeadSelectionPath);
historyIndex = navigationHistory.size() - 1;
}
DefaultMutableTreeNode tn = (DefaultMutableTreeNode) newLeadSelectionPath.getLastPathComponent();
if (tn.getUserObject() instanceof InspectItem) {
InspectItem item = (InspectItem) tn.getUserObject();
partTabs.setSelectedIndex(item.getTabIndex());
statusBar.setInfo(item.getDescription());
RSyntaxTextArea editor = editors.get(item.getTabIndex());
int lineNumber = item.getLineNumber();
try {
if (lineNumber > 0 && editor.getLineStartOffset(lineNumber) >= 0) {
editor.setCaretPosition(editor.getLineStartOffset(lineNumber));
} else {
editor.setCaretPosition(0);
}
} catch (BadLocationException e1) {
SoapUI.logError(e1, "Unable to reset the caret position");
}
}
tree.scrollPathToVisible(newLeadSelectionPath);
tree.expandPath(newLeadSelectionPath);
}
}
}
private class Loader implements Worker {
private static final String DEFINITION_PARTS_SECTION = "Definition Parts";
private ProgressDialog progressDialog;
private final WsdlInterface iface;
private JProgressBar progressBar;
public Loader(WsdlInterface iface) {
this.iface = iface;
}
public Object construct(XProgressMonitor monitor) {
MetricsSection section = metrics.getSection(DEFINITION_PARTS_SECTION);
section.clear();
try {
List<InterfaceDefinitionPart> schemas = iface.getWsdlContext().getDefinitionParts();
int tabCount = partTabs.getTabCount();
for (InterfaceDefinitionPart part : schemas) {
addTab(part.getUrl(), part.getContent());
}
while (tabCount-- > 0) {
partTabs.remove(0);
}
return null;
} catch (Exception e) {
logger.error("Failed to load WSDL; " + e.getClass().getSimpleName() + "; " + e.getMessage());
add(new JLabel("Failed to load WSDL; " + e.toString()), BorderLayout.NORTH);
SoapUI.logError(e);
return e;
} finally {
section.finish();
}
}
private void addTab(String url, String content) throws Exception {
int ix = url.startsWith("file:") ? url.lastIndexOf(File.separatorChar) : url.lastIndexOf('/');
if (ix == -1) {
ix = url.lastIndexOf('/');
}
String title = url.substring(ix + 1);
metrics.getSection(DEFINITION_PARTS_SECTION).addMetric(title, MetricType.URL).set(url);
if (progressBar != null) {
progressBar.setString(title);
} else if (progressDialog != null) {
progressDialog.setProgress(1, title);
}
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel(url);
label.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
panel.add(label, BorderLayout.NORTH);
RSyntaxTextArea inputArea = SyntaxEditorUtil.createDefaultXmlSyntaxTextArea();
StringWriter writer = new StringWriter();
// XmlUtils.serializePretty( XmlObject.Factory.parse( content ), writer
// );
XmlUtils.serializePretty(XmlUtils.createXmlObject(content), writer);
String xmlString = writer.toString();
// reparse so line numbers are correct
// XmlObject xmlObject = XmlObject.Factory.parse( xmlString, new
// XmlOptions().setLoadLineNumbers() );
XmlObject xmlObject = XmlUtils.createXmlObject(xmlString, new XmlOptions().setLoadLineNumbers());
inputArea.setText(xmlString);
inputArea.setEditable(false);
inputArea.setFont(UISupport.getEditorFont());
JPanel p = new JPanel(new BorderLayout());
RTextScrollPane scrollPane = new RTextScrollPane(inputArea);
UISupport.addPreviewCorner(scrollPane, true);
p.add(scrollPane, BorderLayout.CENTER);
panel.add(p, BorderLayout.CENTER);
partTabs.addTab(title, panel);
if (tree != null) {
initInspectionTree(xmlObject, inputArea);
}
}
private void initInspectionTree(XmlObject xmlObject, RSyntaxTextArea inputArea) {
DefaultMutableTreeNode treeRoot = rootNode;
targetNamespaces.add(SchemaUtils.getTargetNamespace(xmlObject));
int tabCount = partTabs.getTabCount() - 1;
mapTreeItems(xmlObject, treeRoot, false, tabCount, "Complex Types",
"declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:complexType[@name!='']", "@name", true,
null);
mapTreeItems(xmlObject, treeRoot, false, tabCount, "Simple Types",
"declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:simpleType[@name!='']", "@name", true,
null);
mapTreeItems(xmlObject, treeRoot, false, tabCount, "Anonymous Complex Types",
"declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:complexType[not(exists(@name))]",
"parent::node()/@name", true, null);
mapTreeItems(xmlObject, treeRoot, false, tabCount, "Global Elements",
"declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:schema/xs:element[@name!='']", "@name",
true, new GlobalElementSelector());
mapTreeItems(xmlObject, treeRoot, false, tabCount, "Schemas",
"declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:schema", "@targetNamespace", true, null);
List<DefaultMutableTreeNode> messages = mapTreeItems(xmlObject, treeRoot, false, tabCount, "Messages",
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:message", "@name", true, null);
for (DefaultMutableTreeNode treeNode : messages) {
mapTreeItems(
((InspectItem) treeNode.getUserObject()).item,
treeNode,
false,
tabCount,
null,
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:part",
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';concat('part: name=[', @name, '] type=[', @type, '] element=[', @element, ']' )",
true, new PartSelector());
}
List<DefaultMutableTreeNode> portTypes = mapTreeItems(xmlObject, treeRoot, false, tabCount, "PortTypes",
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:portType", "@name", true, null);
for (DefaultMutableTreeNode treeNode : portTypes) {
List<DefaultMutableTreeNode> operationNodes = mapTreeItems(
((InspectItem) treeNode.getUserObject()).item, treeNode, false, tabCount, null,
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:operation", "@name", true, null);
for (DefaultMutableTreeNode treeNode2 : operationNodes) {
mapTreeItems(((InspectItem) treeNode2.getUserObject()).item, treeNode2, false, tabCount, null,
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:*",
"concat( @name, ' [', local-name(), '], message=[', @message, ']' )", false, new MessageSelector());
}
}
List<DefaultMutableTreeNode> bindings = mapTreeItems(
xmlObject,
treeRoot,
false,
tabCount,
"Bindings",
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:binding",
"declare namespace wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/';concat( @name, ' [style=', wsdlsoap:binding[1]/@style, ']' )",
true, null);
for (DefaultMutableTreeNode treeNode : bindings) {
List<DefaultMutableTreeNode> operationNodes = mapTreeItems(
((InspectItem) treeNode.getUserObject()).item,
treeNode,
false,
tabCount,
null,
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:operation",
"declare namespace wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/';concat( @name, ' [soapAction=', wsdlsoap:operation/@soapAction, ']' )",
true, null);
for (DefaultMutableTreeNode treeNode2 : operationNodes) {
mapTreeItems(((InspectItem) treeNode2.getUserObject()).item, treeNode2, false, tabCount, null,
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:*",
"concat( @name, ' [', local-name(), ']' )", false, new BindingOperationSelector());
}
}
List<DefaultMutableTreeNode> services = mapTreeItems(xmlObject, treeRoot, false, tabCount, "Services",
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:service", "@name", true, null);
for (DefaultMutableTreeNode treeNode : services) {
mapTreeItems(((InspectItem) treeNode.getUserObject()).item, treeNode, false, tabCount, null,
"declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:port",
"concat( 'port: name=[', @name, '] binding=[', @binding, ']' )", true, new PortSelector());
}
tree.expandRow(0);
editors.add(inputArea);
}
public void finished() {
if (progressDialog != null) {
progressDialog.setVisible(false);
}
progressDialog = null;
}
public boolean onCancel() {
progressBar = new JProgressBar(0, 1);
progressBar.setSize(new Dimension(120, 20));
progressBar.setStringPainted(true);
progressBar.setString("Loading Definition..");
progressBar.setIndeterminate(true);
ButtonBarBuilder builder = ButtonBarBuilder.createLeftToRightBuilder();
builder.addGlue();
builder.addFixed(progressBar);
builder.addGlue();
builder.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
partTabs.addTab("Loading.. ", builder.getPanel());
return true;
}
}
public boolean dependsOn(ModelItem modelItem) {
return modelItem == getModelItem() || modelItem == getModelItem().getProject();
}
public List<DefaultMutableTreeNode> mapTreeItems(XmlObject xmlObject, DefaultMutableTreeNode treeRoot,
boolean createEmpty, int tabIndex, String groupName, String query, String nameQuery, boolean sort,
NodeSelector selector) {
List<DefaultMutableTreeNode> resultNodes = new ArrayList<DefaultMutableTreeNode>();
try {
XmlObject[] items = xmlObject.selectPath(query);
List<DefaultMutableTreeNode> treeNodes = new ArrayList<DefaultMutableTreeNode>();
DefaultMutableTreeNode root = treeRoot;
if (groupName != null) {
String groupKey = new TreePath(root.getPath()).toString() + "/" + groupName;
root = groupNodes.get(groupKey);
if (root == null && (items.length > 0 || createEmpty)) {
root = new DefaultMutableTreeNode(groupName);
treeRoot.add(root);
groupNodes.put(groupKey, root);
} else if (root != null) {
Enumeration<?> children = root.children();
while (children.hasMoreElements()) {
treeNodes.add((DefaultMutableTreeNode) children.nextElement());
}
}
}
if (items.length == 0) {
return resultNodes;
}
for (XmlObject item : items) {
XmlObject[] selectPath = item.selectPath(nameQuery);
if (selectPath.length > 0) {
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(new InspectItem(item, selectPath[0],
tabIndex, selector));
treeNodes.add(treeNode);
resultNodes.add(treeNode);
}
}
if (sort) {
Collections.sort(treeNodes, new Comparator<DefaultMutableTreeNode>() {
public int compare(DefaultMutableTreeNode o1, DefaultMutableTreeNode o2) {
return o1.toString().compareTo(o2.toString());
}
});
}
root.removeAllChildren();
for (DefaultMutableTreeNode treeNode : treeNodes) {
root.add(treeNode);
String path = "/" + getTreeNodeName(treeNode);
TreePath treePath = new TreePath(treeNode.getPath());
while (treeNode.getParent() != null) {
treeNode = (DefaultMutableTreeNode) treeNode.getParent();
path = "/" + getTreeNodeName(treeNode) + path;
}
pathMap.put(path, treePath);
}
} catch (Throwable e) {
SoapUI.log("Failed to map items for query [" + query + "]:[" + nameQuery + "]");
SoapUI.logError(e);
}
return resultNodes;
}
private String getTreeNodeName(DefaultMutableTreeNode treeNode) {
Object userObject = treeNode.getUserObject();
if (userObject instanceof InspectItem) {
return ((InspectItem) userObject).getName();
} else {
return treeNode.toString();
}
}
private final class InspectItem {
private final XmlObject item;
private String name;
private final int tabIndex;
private XmlLineNumber lineNumber;
private final NodeSelector selector;
public InspectItem(XmlObject item, XmlObject nameObj, int tabIndex, NodeSelector selector) {
this.item = item;
this.selector = selector;
this.name = XmlUtils.getNodeValue(nameObj.getDomNode());
if (name == null) {
name = nameObj.toString();
}
this.tabIndex = tabIndex;
ArrayList<?> list = new ArrayList<Object>();
XmlCursor cursor = item.newCursor();
cursor.getAllBookmarkRefs(list);
for (Object o : list) {
if (o instanceof XmlLineNumber) {
lineNumber = (XmlLineNumber) o;
}
}
cursor.dispose();
}
public String getDescription() {
return getName() + "@" + targetNamespaces.get(tabIndex);
}
public String getName() {
int ix = name.indexOf(' ');
return ix == -1 ? name : name.substring(0, ix);
}
public int getTabIndex() {
return tabIndex;
}
public int getLineNumber() {
return lineNumber == null ? -1 : lineNumber.getLine() - 1;
}
@Override
public String toString() {
return name;
}
public NodeSelector getSelector() {
return selector;
}
public Element getElement() {
return (Element) item.getDomNode();
}
}
public boolean onClose(boolean canCancel) {
if (projectListener != null) {
getModelItem().getProject().removeProjectListener(projectListener);
}
return release();
}
private void simpleSelect(InspectItem item, String attribute, String targetGroup) {
Element elm = item.getElement();
String type = elm.getAttribute(attribute);
if (type.length() > 0) {
int ix = type.indexOf(':');
if (ix != -1) {
type = type.substring(ix + 1);
}
TreePath treePath = pathMap.get("/" + getModelItem().getName() + "/" + targetGroup + "/" + type);
if (treePath != null) {
tree.setSelectionPath(treePath);
}
}
}
protected interface NodeSelector {
public void selectNode(InspectItem item);
}
public class PartSelector implements NodeSelector {
public void selectNode(InspectItem item) {
Element elm = item.getElement();
String type = elm.getAttribute("type");
String element = elm.getAttribute("element");
if (type.length() > 0) {
simpleSelect(item, "type", "Complex Types");
} else if (element.length() > 0) {
simpleSelect(item, "element", "Global Elements");
}
}
}
public class MessageSelector implements NodeSelector {
public void selectNode(InspectItem item) {
simpleSelect(item, "message", "Messages");
}
}
public class GlobalElementSelector implements NodeSelector {
public void selectNode(InspectItem item) {
simpleSelect(item, "type", "Complex Types");
}
}
public class PortSelector implements NodeSelector {
public void selectNode(InspectItem item) {
simpleSelect(item, "binding", "Bindings");
}
}
public class BindingOperationSelector implements NodeSelector {
public void selectNode(InspectItem item) {
Element elm = item.getElement();
String name = elm.getAttribute("name");
Element operationElm = (Element) elm.getParentNode();
Element bindingElm = (Element) operationElm.getParentNode();
String type = bindingElm.getAttribute("type");
if (type.length() > 0) {
int ix = type.indexOf(':');
if (ix != -1) {
type = type.substring(ix + 1);
}
TreePath treePath = pathMap.get("/" + getModelItem().getName() + "/PortTypes/" + type + "/"
+ operationElm.getAttribute("name") + "/" + name);
if (treePath != null) {
tree.setSelectionPath(treePath);
}
}
}
}
private class BackwardAction extends AbstractAction {
public BackwardAction() {
putValue(SMALL_ICON, UISupport.createImageIcon("/arrow_left.png"));
putValue(Action.SHORT_DESCRIPTION, "Navigate to previous selection");
}
public void actionPerformed(ActionEvent arg0) {
if (historyIndex > 0) {
historyIndex--;
navigating = true;
tree.setSelectionPath(navigationHistory.get(historyIndex));
navigating = false;
}
}
}
private class ForwardAction extends AbstractAction {
public ForwardAction() {
putValue(SMALL_ICON, UISupport.createImageIcon("/arrow_right.png"));
putValue(Action.SHORT_DESCRIPTION, "Navigate to next selection");
}
public void actionPerformed(ActionEvent arg0) {
if (historyIndex < navigationHistory.size() - 1) {
historyIndex++;
navigating = true;
tree.setSelectionPath(navigationHistory.get(historyIndex));
navigating = false;
}
}
}
private class RunWSIAction extends AbstractAction {
public RunWSIAction() {
putValue(SMALL_ICON, UISupport.createImageIcon("/run.gif"));
putValue(Action.SHORT_DESCRIPTION, "Creates a WS-I report for this interface");
}
public void actionPerformed(ActionEvent arg0) {
WSIAnalyzeAction action = new WSIAnalyzeAction() {
@Override
protected void showReport(File reportFile, String configFile) throws Exception {
reportPanel = new WSIReportPanel(reportFile, configFile, null, false);
reportPanel.setPreferredSize(new Dimension(600, 400));
if (wsiPanel.getComponentCount() > 1) {
wsiPanel.remove(1);
}
wsiPanel.add(reportPanel, BorderLayout.CENTER);
wsiPanel.revalidate();
saveWsiReportAction.setEnabled(true);
}
};
action.perform(getModelItem(), null);
}
}
private class WSIOptionsAction extends AbstractAction {
public WSIOptionsAction() {
putValue(SMALL_ICON, UISupport.createImageIcon("/options.gif"));
putValue(Action.SHORT_DESCRIPTION, "Sets WS-I report creation options");
}
public void actionPerformed(ActionEvent arg0) {
SoapUIPreferencesAction.getInstance().show(SoapUIPreferencesAction.WS_I_SETTINGS);
}
}
private class SaveWsiReportAction extends AbstractAction {
public SaveWsiReportAction() {
putValue(SMALL_ICON, UISupport.createImageIcon("/export.gif"));
putValue(Action.SHORT_DESCRIPTION, "Saved the current WS-I report to a file");
setEnabled(false);
}
public void actionPerformed(ActionEvent arg0) {
if (reportPanel != null) {
reportPanel.getSaveReportAction().actionPerformed(null);
}
}
}
private class OperationsTableModel extends AbstractTableModel {
public int getColumnCount() {
return 4;
}
public int getRowCount() {
return iface.getOperationCount();
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Name";
case 1:
return "Use";
case 2:
return "One-Way";
case 3:
return "Action";
}
return null;
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (updatingInterface) {
return "<updating>";
}
WsdlOperation operation = iface.getOperationAt(rowIndex);
BindingOperation bindingOperation = operation.getBindingOperation();
switch (columnIndex) {
case 0:
return operation.getName();
case 1: {
boolean in = WsdlUtils.isInputSoapEncoded(bindingOperation);
boolean out = operation.isUnidirectional() ? false : WsdlUtils.isOutputSoapEncoded(bindingOperation);
if (out && in) {
return "SOAP Encoding";
}
if (!out && !in) {
return "Literal";
}
return "Mixed";
}
case 3:
return operation.getAction();
case 2:
return Boolean.valueOf(operation.isUnidirectional());
}
return null;
}
}
}