001: /* ****************************************************************************
002: * XMLRPCDataSource.java
003: * ****************************************************************************/
004:
005: /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006: * Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
007: * Use is subject to license terms. *
008: * J_LZ_COPYRIGHT_END *********************************************************/
009:
010: package org.openlaszlo.data;
011:
012: import java.io.*;
013: import java.util.*;
014: import java.net.MalformedURLException;
015: import javax.servlet.http.*;
016: import org.apache.xmlrpc.*;
017: import org.openlaszlo.server.LPS; // LoadCount belongs in utils
018: import org.openlaszlo.servlets.LoadCount;
019: import org.openlaszlo.xml.internal.*;
020: import org.openlaszlo.media.MimeType;
021: import org.apache.log4j.*;
022:
023: /**
024: *
025: */
026: public class XMLRPCDataSource extends DataSource {
027: private static Logger mLogger = Logger
028: .getLogger(XMLRPCDataSource.class);
029:
030: XmlRpcServer xmlrpc = new XmlRpcServer();
031:
032: static long mLastCleared = -1;
033: static LoadCount mXMLRPCLoad = new LoadCount(10);
034:
035: public XMLRPCDataSource() {
036: clearLoadInfo();
037: }
038:
039: /**
040: * @return unique name of this data source
041: */
042: public String name() {
043: return "xmlrpc";
044: }
045:
046: /**
047: * Sends system information to client.
048: *
049: * @throws DataSourceException if there was a problem retrieving or sending
050: * the data.
051: */
052: public Data getData(String app, HttpServletRequest req,
053: HttpServletResponse res, long lastModifiedTime)
054: throws DataSourceException {
055: mLogger.debug(
056: /* (non-Javadoc)
057: * @i18n.test
058: * @org-mes="getData"
059: */
060: org.openlaszlo.i18n.LaszloMessages.getMessage(
061: XMLRPCDataSource.class.getName(), "051018-62"));
062:
063: String runtime = req.getParameter("lzr");
064:
065: try {
066: if (!req.getMethod().equals("POST"))
067: return compileFault(
068: /* (non-Javadoc)
069: * @i18n.test
070: * @org-mes="Remote request must be POST"
071: */
072: org.openlaszlo.i18n.LaszloMessages.getMessage(
073: XMLRPCDataSource.class.getName(), "051018-74"),
074: runtime);
075:
076: String url = getHTTPURL(getURL(req));
077: if (url == null) {
078: return compileFault(
079: /* (non-Javadoc)
080: * @i18n.test
081: * @org-mes="invalid url specified: " + p[0]
082: */
083: org.openlaszlo.i18n.LaszloMessages.getMessage(
084: XMLRPCDataSource.class.getName(), "051018-85",
085: new Object[] { url }), runtime);
086: }
087:
088: String postbody = req.getParameter("lzpostbody");
089: if (postbody != null) {
090: url += "?lzpostbody=" + postbody;
091: }
092:
093: long t0, t1;
094: t0 = System.currentTimeMillis();
095: mXMLRPCLoad.increment();
096: try {
097: Data data = HTTPDataSource.getHTTPData(req, res, url,
098: -1);
099: mLogger.error("xmlrpc data " + data.getAsString());
100: return new XMLRPCData(data.getAsString().getBytes(),
101: runtime);
102: } finally {
103: t1 = System.currentTimeMillis();
104: mXMLRPCLoad.decrement((int) (t1 - t0));
105: }
106:
107: } catch (Exception e) {
108: return compileFault(e, runtime);
109: }
110: }
111:
112: String getHTTPURL(String url) {
113: if (url != null && url.startsWith("xmlrpc://"))
114: return "http" + url.substring(6);
115: return null;
116: }
117:
118: /**
119: * Compile fault exception message.
120: */
121: Data compileFault(Exception e, String runtime) {
122: mLogger.error("compileFault", e);
123: return compileFault(e.getMessage(), runtime);
124: }
125:
126: /**
127: * Compile fault response.
128: */
129: Data compileFault(String mesg, String runtime) {
130: mLogger.error("compileFault mesg: " + mesg);
131: try {
132:
133: if ("dhtml".equals(runtime)) {
134: byte[] d = XMLRPCJSONCompiler.compileFault(XMLUtils
135: .escapeXml(mesg), runtime);
136: return new XMLRPCData().setResult(d);
137: } else {
138: int swfversion = LPS.getSWFVersionNum(runtime);
139: byte[] d = XMLRPCCompiler.compileFault(XMLUtils
140: .escapeXml(mesg), swfversion);
141: return new XMLRPCData().setResult(d);
142: }
143:
144: } catch (Exception e) {
145: mLogger.error("Exception", e);
146: // this is an error since we can't build a fault response
147: throw new Error(e.getMessage());
148: }
149: }
150:
151: public static void clearLoadInfo() {
152: mXMLRPCLoad.reset();
153: mLastCleared = System.currentTimeMillis();
154: }
155:
156: public static void toXML(StringBuffer sb) {
157: Date lc = new Date(mLastCleared);
158: sb.append("<xmlrpcinfo ").append(" last-cleared=\"").append(lc)
159: .append("\"").append(">");
160: sb.append(mXMLRPCLoad.toXML("xmlrpc_load"));
161: sb.append("</xmlrpcinfo>");
162: }
163:
164: /**
165: * A data object to hold an xmlrpc response.
166: */
167: public class XMLRPCData extends Data {
168: byte[] mResult;
169:
170: public XMLRPCData() {
171: }
172:
173: public XMLRPCData(byte[] result, String runtime)
174: throws IOException {
175: InputStreamReader reader = new InputStreamReader(
176: new ByteArrayInputStream(result));
177: mLogger.debug("XMLRPCData runtime=" + runtime);
178: if ("dhtml".equals(runtime)) {
179: mResult = XMLRPCJSONCompiler.compile(reader, runtime);
180: } else {
181: int swfversion = LPS.getSWFVersionNum(runtime);
182: mResult = XMLRPCCompiler.compile(reader, result.length,
183: swfversion);
184: }
185: }
186:
187: public String getMimeType() {
188: return MimeType.SWF;
189: }
190:
191: public XMLRPCData setResult(byte[] result) {
192: mResult = result;
193: return this ;
194: }
195:
196: /**
197: * @return the encoded XML
198: */
199: public InputStream getInputStream() throws IOException {
200: return new ByteArrayInputStream(mResult);
201: }
202:
203: public long size() {
204: return mResult.length;
205: }
206: }
207: }
|