package org.knopflerfish.bundle.soap.desktop;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.wsdl.*;
import javax.wsdl.factory.*;
import javax.wsdl.xml.*;
import javax.wsdl.extensions.*;
import javax.xml.namespace.QName;
// Axis imports
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import java.net.URL;
/**
* Complete wrapper component which allows a user to
* select a SOAP host, browse the services and
* invoke operations.
*
* <p>
* Used the <tt>WSDLLoader</tt> to load WSDL info and
* <tt>SwingRenderer</tt> for displaying data
* </p>
*/
public class JSOAPUI extends JPanel {
// String
Set services = new TreeSet();
String urlBase;
JSplitPane splitPane;
JPanel servicePanel;
JComponent callPanel;
ImageIcon soapIcon;
// String (service name) -> JLabel2
HashMap labels = new HashMap();
/**
* Create the UI and call the AxisAdmin endpoint
* to get iinitial set of services.
*/
public JSOAPUI(String urlBase) {
super(new BorderLayout());
this.urlBase = urlBase;
soapIcon = new ImageIcon(getClass().getResource("/soap.png"));
callPanel = new JPanel(new BorderLayout());
JPanel leftPanel = new JPanel(new BorderLayout());
servicePanel = new JPanel();
JScrollPane serviceScroll = new JScrollPane(servicePanel);
LayoutManager box = new GridLayout(0, 1);
servicePanel.setLayout(box);
serviceScroll.setPreferredSize(new Dimension(100, 100));
callPanel.setPreferredSize(new Dimension(500, 400));
JPanel buttonPanel = new JPanel();
BoxLayout buttonBox = new BoxLayout(buttonPanel, BoxLayout.Y_AXIS);
buttonPanel.setLayout(new GridLayout(0, 1));
JButton openHostButton = new JButton("Connect to...");
openHostButton.setToolTipText("Connects to a new SOAP host");
openHostButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
openHost();
}
});
JButton reloadHostButton = new JButton("Reload");
reloadHostButton.setToolTipText("Reloads service list from SOAP host");
reloadHostButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
getServices();
}
});
buttonPanel.add(openHostButton);
buttonPanel.add(reloadHostButton);
leftPanel.add(buttonPanel, BorderLayout.NORTH);
leftPanel.add(serviceScroll, BorderLayout.CENTER);
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
leftPanel,
callPanel);
add(splitPane, BorderLayout.CENTER);
getServices();
}
/**
* Ask the user for a noew SOAP host
*/
void openHost() {
String s = (String)JOptionPane
.showInputDialog(servicePanel,
"Enter address to SOAP host",
"Connect to new SOAP host",
JOptionPane.QUESTION_MESSAGE, // optionType
null, // icon,
null, // Object[] init
urlBase);
if ((s != null) && (s.length() > 0)) {
urlBase = s;
getServices();
}
}
/**
* Update the UI with all loaded services.
*/
void update() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
synchronized(services) {
servicePanel.removeAll();
labels.clear();
for(Iterator it = services.iterator(); it.hasNext();) {
final String name = (String)it.next();
final JLabel label = new JLabel2(name,
soapIcon,
SwingConstants.CENTER);
label.setToolTipText("Show SOAP service '" + name + "'");
labels.put(name, label);
MouseListener l = new MouseAdapter() {
public void mouseClicked(MouseEvent ev) {
selectService(name);
}
};
label.addMouseListener(l);
servicePanel.add(label);
}
servicePanel.invalidate();
servicePanel.revalidate();
servicePanel.repaint();
callPanel.removeAll();
callPanel.invalidate();
callPanel.revalidate();
callPanel.repaint();
}
}
});
}
/**
* Get the services from the endpoint's AxisAdmin
*/
void getServices() {
String endpoint = urlBase + "axisadmin";
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new URL(endpoint) );
call.setOperationName(new QName("getPublishedServiceNames"));
Object[] params = new Object[] { };
String[] result = (String[])call.invoke(params);
synchronized(services) {
services.clear();
for(int i = 0; i < result.length; i++) {
services.add(result[i]);
}
}
update();
} catch (Exception e) {
JTextArea text = new JTextArea();
text.setText("Failed to set base SOAP URL\n" +
endpoint +
"\n\n" +
e.toString());
text.setEditable(false);
e.printStackTrace();
setCallComponent(text);
}
}
/**
* Get service information from the endpoint
* and create and set a suitable UI.
*/
public void selectService(String name) {
JComponent comp;
String endPoint = urlBase + name;
String wsdlURL = endPoint + "?wsdl";
try {
WSDLFactory factory = WSDLFactory.newInstance();
WSDLReader reader = factory.newWSDLReader();
reader.setFeature("javax.wsdl.verbose", Activator.bVerbose);
reader.setFeature("javax.wsdl.importDocuments", true);
WSDL wsdl = new WSDL();
wsdl.load(endPoint, wsdlURL);
SwingRenderer renderer = new SwingRenderer();
comp = renderer.createComponent(wsdl);
for(Iterator it = labels.keySet().iterator(); it.hasNext();) {
String s = (String)it.next();
JLabel2 label = (JLabel2)labels.get(s);
label.setSelected(false);
}
JLabel2 label = (JLabel2)labels.get(name);
if(label != null) {
label.setSelected(true);
}
} catch (Exception e) {
comp = new JLabel("Failed to set service\n" +
"URL: " + endPoint +
"\n\n" + e);
e.printStackTrace();
}
setCallComponent(comp);
}
void setCallComponent(JComponent comp) {
callPanel.removeAll();
callPanel.add(comp, BorderLayout.CENTER);
callPanel.invalidate();
callPanel.revalidate();
callPanel.repaint();
}
public void addService(String name) {
synchronized(services) {
services.add(name);
}
update();
}
public void removeService(String name) {
synchronized(services) {
services.remove(name);
}
update();
}
void close() {
}
}
/**
* A button look-alike label without borders
*/
class JLabel2 extends JLabel {
Color selColor = new Color(200, 200, 255);
boolean bSelected = false;
JLabel2(String name, Icon icon, int pos) {
super(name, icon, SwingConstants.CENTER);
setVerticalTextPosition(AbstractButton.BOTTOM);
setHorizontalTextPosition(AbstractButton.CENTER);
setOpaque(false);
}
public void paintComponent(Graphics g) {
Dimension size = getSize();
g.setColor(getBackground());
g.fillRect(0,0,size.width, size.height);
super.paintComponent(g);
}
public Color getBackground() {
return bSelected ? selColor : super.getBackground();
}
public void setSelected(boolean b) {
this.bSelected = b;
repaint();
}
}