001: package com.xoetrope.service;
002:
003: import java.io.InputStream;
004: import java.io.InputStreamReader;
005: import java.io.OutputStream;
006: import java.net.MalformedURLException;
007: import java.net.URL;
008: import java.net.URLConnection;
009: import java.net.URLDecoder;
010: import java.util.Hashtable;
011:
012: import net.xoetrope.optional.service.ServiceProxy;
013: import net.xoetrope.optional.service.ServiceProxyArgs;
014: import net.xoetrope.optional.service.ServiceProxyException;
015: import net.xoetrope.xml.XmlElement;
016: import net.xoetrope.xml.nanoxml.NanoXmlParser;
017: import java.io.StringReader;
018: import java.net.URLEncoder;
019: import java.util.Enumeration;
020: import java.util.Vector;
021: import net.xoetrope.optional.service.ServiceContext;
022:
023: /**
024: * Makes a service call via the HTTP protocol. By default the arguments are
025: * URLEncoded and the response unencoded.
026: *
027: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
028: * the GNU Public License (GPL), please see license.txt for more details. If
029: * you make commercial use of this software you must purchase a commercial
030: * license from Xoetrope.</p>
031: * <p> $Revision: 1.14 $</p>
032: */
033: public class XHttpClientServiceProxy extends ServiceProxy {
034: /**
035: * Error sent back in the case that a connection cannot be established.
036: */
037: public static final String ERR_CANNOT_CONNECT = "httpclientserviceproxy:cannotconnect";
038:
039: /*
040: * The original string from which the url is constructed.
041: */
042: protected String urlOrig;
043:
044: /*
045: * The url to be called.
046: */
047: protected URL url;
048:
049: /*
050: * Flag to indicate whether or not the url should be encoded.
051: */
052: protected boolean urlEncode = true;
053:
054: public XHttpClientServiceProxy() {
055: status = OK;
056: }
057:
058: public void setUrlEncoding(String encode) {
059: if (encode.compareTo("false") == 0)
060: urlEncode = false;
061: else
062: urlEncode = true;
063: }
064:
065: public void setUrl(String urlStr) {
066: try {
067: urlOrig = urlStr;
068: url = new URL(urlStr);
069: } catch (MalformedURLException ex) {
070: ex.printStackTrace();
071: }
072: }
073:
074: /**
075: * Makes a call to a server using the http protocol. The arguments are by
076: * default URLEncoded.
077: * @param method the method name to be invoked
078: * @param context the ServiceContext for this ServiceProxy call
079: * @return the response or result of the call
080: * @throws ServiceProxyException
081: */
082: public Object call(String method, ServiceContext context)
083: throws ServiceProxyException {
084: try {
085: status = STARTED;
086: StringBuffer arguments = new StringBuffer("service="
087: + method);
088: ServiceProxyArgs args = context.getArgs();
089: Hashtable passArgs = context.getPassArgs();
090: Enumeration keys = passArgs.keys();
091: while (keys.hasMoreElements()) {
092: String name = (String) keys.nextElement();
093: Object argObj = passArgs.get(name);
094: String argValue = (argObj == null) ? "" : argObj
095: .toString();
096: arguments
097: .append("&" + URLEncoder.encode(name, "UTF-8"));
098: argValue = (argValue == null ? "" : argValue);
099: arguments.append("="
100: + URLEncoder.encode(argValue, "UTF-8"));
101: }
102:
103: String sessionId = (String) args
104: .getPassParam(";jsessionid");
105: if (sessionId == null)
106: url = new URL(urlOrig);
107: else
108: url = new URL(urlOrig + ";jsessionid=" + sessionId);
109:
110: URLConnection conn = url.openConnection();
111: conn.setDefaultUseCaches(false);
112: conn.setDoOutput(true);
113: conn.setIfModifiedSince(0);
114:
115: OutputStream o = conn.getOutputStream();
116: String argData = arguments.toString();
117:
118: o.write(argData.getBytes());
119: o.flush();
120:
121: status = PENDING;
122: conn.connect();
123: InputStream is = conn.getInputStream();
124:
125: InputStreamReader isr = new InputStreamReader(is);
126: char[] c = new char[4096];
127:
128: int i = 1;
129: String result = new String("");
130: while (i != -1) {
131: i = isr.read(c);
132: if (i > 0)
133: result += new String(c, 0, i);
134: }
135: //if ( urlEncode )
136: result = URLDecoder.decode(result, "UTF-8");
137:
138: isr.close();
139: is.close();
140:
141: if (result.length() > 0) {
142: StringReader sr = new StringReader(result);
143: NanoXmlParser parser = new NanoXmlParser();
144: XmlElement ele = parser.parse(sr);
145: Vector vArgs = ele.getChildren();
146: for (int iarg = 0; iarg < vArgs.size(); iarg++) {
147: XmlElement child = (XmlElement) vArgs.get(iarg);
148: String type = child.getAttribute("type");
149: if ((type != null) && type.equals("error"))
150: args.addError(child.getAttribute("value"));
151: else
152: args.setReturnParam(child.getAttribute("id"),
153: child.getAttribute("value"));
154: }
155: } else
156: args.getReturnArgs().clear();
157:
158: status = COMPLETE;
159: return status;
160: } catch (Exception e) {
161: status = FAILED;
162: context.addError(ERR_CANNOT_CONNECT);
163: throw (new ServiceProxyException("'" + method
164: + "' generated an exception : " + e.getMessage()));
165: }
166:
167: }
168:
169: /**
170: * Set the attributes for this service proxy. This class can set attributes
171: * for 'url' and 'urlEncode'.
172: * @param attribs The Hashtable of attributes as found in the XML declaration
173: */
174: public void setAttributes(Hashtable attribs) {
175: setUrl((String) attribs.get("url"));
176: String encode = (String) attribs.get("urlEncode");
177: setUrlEncoding((encode == null) ? "false" : encode);
178: }
179: }
|