001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/enterprise/control/ApplicationHandler.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044: package org.deegree.enterprise.control;
045:
046: import java.io.BufferedReader;
047: import java.io.File;
048: import java.io.IOException;
049: import java.io.InputStreamReader;
050: import java.io.Reader;
051: import java.io.StringReader;
052: import java.net.MalformedURLException;
053: import java.net.URL;
054: import java.net.URLDecoder;
055: import java.nio.charset.Charset;
056: import java.util.ArrayList;
057: import java.util.HashMap;
058: import java.util.List;
059:
060: import javax.servlet.ServletRequest;
061: import javax.servlet.http.HttpServletRequest;
062:
063: import org.deegree.datatypes.parameter.GeneralOperationParameterIm;
064: import org.deegree.datatypes.parameter.ParameterValueIm;
065: import org.deegree.framework.log.ILogger;
066: import org.deegree.framework.log.LoggerFactory;
067: import org.deegree.framework.xml.NamespaceContext;
068: import org.deegree.framework.xml.XMLParsingException;
069: import org.deegree.framework.xml.XMLTools;
070: import org.deegree.ogcbase.CommonNamespaces;
071: import org.w3c.dom.Document;
072: import org.w3c.dom.Element;
073: import org.w3c.dom.Node;
074: import org.w3c.dom.NodeList;
075: import org.xml.sax.SAXException;
076:
077: /**
078: * Handler for all web events.
079: *
080: * @author <a href="mailto:tfriebe@gmx.net">Torsten Friebe</a>
081: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
082: *
083: * @version $Revision: 9338 $, $Date: 15.10.2007 15:39:10$
084: */
085: public class ApplicationHandler implements WebListener {
086:
087: private static final ILogger LOG = LoggerFactory
088: .getLogger(ApplicationHandler.class);
089:
090: private static final HashMap<String, Class> handler = new HashMap<String, Class>();
091:
092: private static final HashMap<String, String> handlerNext = new HashMap<String, String>();
093:
094: private static final HashMap<String, String> handlerANext = new HashMap<String, String>();
095:
096: private static final HashMap<String, List<ParameterValueIm>> handlerParam = new HashMap<String, List<ParameterValueIm>>();
097:
098: private static final String EVENT = "event";
099:
100: private static final String NAME = "name";
101:
102: private static final String CLASS = "class";
103:
104: private static final String NEXT = "next";
105:
106: private static final String ALTERNATIVENEXT = "alternativeNext";
107:
108: /**
109: * Creates a new ApplicationHandler object.
110: *
111: * @param configFile
112: * @throws Exception
113: */
114: public ApplicationHandler(String configFile) throws Exception {
115: ApplicationHandler.initHandler(configFile);
116: }
117:
118: /**
119: * Handles all web action events. Calls the specified listener using the mapping defined in
120: * control.xml file.
121: *
122: * @param e
123: * the action event generated out of the incoming http POST event.
124: */
125: public void actionPerformed(FormEvent e) {
126: Object source = e.getSource();
127:
128: if (source instanceof HttpServletRequest) {
129: HttpServletRequest request = (HttpServletRequest) source;
130:
131: String actionName = request.getParameter("action");
132: LOG.logDebug("Actionname: " + actionName);
133: if (actionName != null) {
134: // handle simple KVP encoded request
135: try {
136: if ("version".equalsIgnoreCase(actionName)) {
137: this .showVersion(request);
138: } else {
139: try {
140: this .delegateToHelper(actionName, e);
141: } catch (Exception ex) {
142: ex.printStackTrace();
143: LOG.logError("Action " + actionName
144: + " is unknown!");
145: }
146: }
147: } catch (Exception ex) {
148: request.setAttribute("next", "error.jsp");
149: request.setAttribute(
150: "javax.servlet.jsp.jspException", ex);
151: }
152: } else {
153: // handle RPC encoded request
154: try {
155: RPCMethodCall mc = getMethodCall(request);
156: e = new RPCWebEvent(e, mc);
157: this .delegateToHelper(mc.getMethodName(), e);
158: } catch (RPCException re) {
159: re.printStackTrace();
160: request.setAttribute("next", "error.jsp");
161: request.setAttribute(
162: "javax.servlet.jsp.jspException", re);
163: } catch (Exception ee) {
164: ee.printStackTrace();
165: request.setAttribute("next", "error.jsp");
166: request.setAttribute(
167: "javax.servlet.jsp.jspException", ee);
168: }
169: }
170: }
171: }
172:
173: /**
174: * extracts the RPC method call from the
175: *
176: * @param request
177: * @return the RPCMethodCall
178: * @throws RPCException
179: */
180: private RPCMethodCall getMethodCall(ServletRequest request)
181: throws RPCException {
182:
183: String s = request.getParameter("rpc");
184:
185: try {
186: if (s == null) {
187: StringBuffer sb = new StringBuffer(1000);
188: try {
189: BufferedReader br = request.getReader();
190: String line = null;
191: while ((line = br.readLine()) != null) {
192: sb.append(line);
193: }
194: br.close();
195: } catch (Exception e) {
196: throw new RPCException(
197: "Error reading stream from servlet\n"
198: + e.toString());
199: }
200:
201: s = sb.toString();
202: LOG
203: .logDebug("found first (perhaps double) encoded String: "
204: + s);
205: s = URLDecoder.decode(s, Charset.defaultCharset()
206: .name());
207: String[] splitter = s.split(" \t<>");
208: if (splitter.length == 1) {
209: s = URLDecoder.decode(s, Charset.defaultCharset()
210: .name());
211: LOG.logDebug("Decoding a second time: " + s);
212: }
213:
214: int pos1 = s.indexOf("<methodCall>");
215: int pos2 = s.indexOf("</methodCall>");
216: if (pos1 < 0) {
217: throw new RPCException(
218: "request doesn't contain a RPC methodCall");
219: }
220: s = s.substring(pos1, pos2 + 13);
221: } else {
222: s = URLDecoder.decode(s, Charset.defaultCharset()
223: .name());
224: }
225: } catch (Exception e) {
226: e.printStackTrace();
227: throw new RPCException(e.toString());
228: }
229:
230: LOG.logDebug("RPC: " + s);
231:
232: return RPCFactory.createRPCMethodCall(new StringReader(s));
233:
234: }
235:
236: /**
237: *
238: *
239: * @param action
240: * @param e
241: *
242: * @throws Exception
243: */
244: protected void delegateToHelper(String action, FormEvent e)
245: throws Exception {
246: action = action.trim();
247: Class cls = ApplicationHandler.handler.get(action);
248: AbstractListener helper = (AbstractListener) cls.newInstance();
249: helper.setNextPage(handlerNext.get(action));
250: helper.setDefaultNextPage(handlerNext.get(action));
251: helper.setAlternativeNextPage(handlerANext.get(action));
252: helper.setInitParameterList(handlerParam.get(action));
253: helper.handle(e);
254: }
255:
256: /**
257: *
258: *
259: * @param request
260: */
261: protected void showVersion(ServletRequest request) {
262: request.setAttribute("next", "snoopy.jsp");
263: }
264:
265: /**
266: *
267: *
268: * @param configFile
269: *
270: * @throws IOException
271: * @throws MalformedURLException
272: * @throws SAXException
273: */
274: private static void initHandler(String configFile)
275: throws IOException, MalformedURLException, SAXException {
276: LOG.logInfo("Reading event handler configuration file:"
277: + configFile);
278: /*
279: * Read resource into Document...
280: */
281: URL url = new File(configFile).toURL();
282: Reader reader = new InputStreamReader(url.openStream());
283: Document doc = XMLTools.parse(reader);
284: /*
285: * Read and create page elements
286: */
287: NodeList nodes = doc.getElementsByTagName(EVENT);
288:
289: for (int i = 0; i < nodes.getLength(); i++) {
290: String name = XMLTools.getAttrValue(nodes.item(i), null,
291: NAME, null);
292: String cls = XMLTools.getAttrValue(nodes.item(i), null,
293: CLASS, null);
294: String nextPage = XMLTools.getAttrValue(nodes.item(i),
295: null, NEXT, null);
296: String anextPage = XMLTools.getAttrValue(nodes.item(i),
297: null, ALTERNATIVENEXT, null);
298:
299: if (anextPage == null) {
300: anextPage = nextPage;
301: }
302:
303: Class clscls = null;
304: try {
305: clscls = Class.forName(cls);
306: handler.put(name.trim(), clscls);
307: handlerNext.put(name.trim(), nextPage);
308: handlerANext.put(name.trim(), anextPage);
309: List<ParameterValueIm> pvList = parseParameters(nodes
310: .item(i));
311: handlerParam.put(name.trim(), pvList);
312: LOG.logInfo("Handler '" + clscls + "' bound to event '"
313: + name + "'");
314: } catch (Exception ex) {
315: ex.printStackTrace();
316: LOG.logError("No handler '" + cls
317: + "' specified for event '" + name + "'", ex);
318: throw new SAXException(
319: "No handler class specified for event:" + name
320: + " " + cls + "\n" + ex);
321: }
322: }
323: }
324:
325: /**
326: * several parameters can be passed to each Listener by adding
327: *
328: * <pre>
329: * <parameter>
330: * <name>aName</name>
331: * <value>aValue</value>
332: * </parameter>
333: * </pre>
334: *
335: * sections to the corresponding <event> element.
336: *
337: * @param node
338: * @return a List of ParameterValueIm
339: * @throws XMLParsingException
340: */
341: private static List<ParameterValueIm> parseParameters(Node node)
342: throws XMLParsingException {
343:
344: NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
345: List nodes = XMLTools.getNodes(node, "parameter", nsc);
346: List<ParameterValueIm> pvs = new ArrayList<ParameterValueIm>();
347: for (int i = 0; i < nodes.size(); i++) {
348: Element element = (Element) nodes.get(i);
349: String name = XMLTools.getRequiredNodeAsString(element,
350: "name", nsc);
351: String value = XMLTools.getRequiredNodeAsString(element,
352: "value", nsc);
353: GeneralOperationParameterIm descriptor = new GeneralOperationParameterIm(
354: name, null, 1, 1);
355: pvs.add(new ParameterValueIm(descriptor, value));
356: }
357:
358: return pvs;
359: }
360:
361: }
|