001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixxml.testrecording;
021:
022: import java.io.IOException;
023: import java.util.Enumeration;
024: import java.util.HashMap;
025: import java.util.Map;
026:
027: import javax.management.Notification;
028: import javax.management.NotificationBroadcasterSupport;
029: import javax.servlet.http.HttpSession;
030:
031: import org.apache.log4j.Logger;
032: import org.w3c.dom.Document;
033: import org.w3c.dom.Element;
034: import org.w3c.dom.Node;
035: import org.w3c.dom.Text;
036:
037: import de.schlund.pfixxml.PfixServletRequest;
038: import de.schlund.pfixxml.RequestParam;
039: import de.schlund.pfixxml.SPDocument;
040: import de.schlund.pfixxml.ServletManager;
041: import de.schlund.pfixxml.util.Xml;
042:
043: /**
044: * Creates a trail by logging request/response pairs.
045: *
046: * @author <a href="mailto: haecker@schlund.de">Joerg Haecker</a>
047: */
048: public class TrailLogger extends NotificationBroadcasterSupport
049: implements TrailLoggerMBean {
050: private final static Logger LOG = Logger
051: .getLogger(TrailLogger.class);
052:
053: public static final String NOTIFICATION_TYPE = "step";
054: public static final String CLOSE_TYPE = "close";
055:
056: // TODO: ugly static thing code.
057: // maps visit_ids auf TrailLogger
058: public static final Map<String, TrailLogger> map = new HashMap<String, TrailLogger>();
059:
060: public static void log(PfixServletRequest preq, SPDocument resdoc,
061: HttpSession session) {
062: TrailLogger logger;
063: String visit;
064:
065: if (session == null) {
066: return; // no sessions, no trails ...
067: }
068: visit = lookupVisit(session);
069: if (visit != null) {
070: logger = (TrailLogger) map.get(visit);
071: if (logger != null) {
072: logger.log(preq, resdoc);
073: }
074: }
075: }
076:
077: public static String getVisit(HttpSession session) {
078: String visit;
079:
080: visit = lookupVisit(session);
081: if (visit == null) {
082: // TODO
083: Enumeration<?> enm = session.getAttributeNames();
084: System.out.println("session " + session);
085: while (enm.hasMoreElements()) {
086: String valName = (String) enm.nextElement();
087: System.out.println(" " + valName + " -> "
088: + session.getAttribute(valName));
089: }
090: throw new RuntimeException("no visit");
091: }
092: return visit;
093: }
094:
095: public static String lookupVisit(HttpSession session) {
096: return (String) session.getAttribute(ServletManager.VISIT_ID);
097: }
098:
099: //--
100:
101: private final String visit;
102: private int sequenceNumber;
103:
104: public TrailLogger(String visit) throws IOException {
105: this .visit = visit;
106: this .sequenceNumber = 0;
107: map.put(visit, this );
108: }
109:
110: public void log(PfixServletRequest request, SPDocument response) {
111: String step;
112: Notification n;
113:
114: step = Xml
115: .serialize(createStep(request, response), true, false);
116: LOG.debug("step " + sequenceNumber + " " + step);
117: n = new Notification(NOTIFICATION_TYPE, this , sequenceNumber++);
118: n.setUserData(step);
119: sendNotification(n);
120: }
121:
122: public void stop() {
123: if (map.remove(visit) != this ) {
124: throw new IllegalStateException();
125: }
126: sendNotification(new Notification(CLOSE_TYPE, this ,
127: sequenceNumber++));
128: }
129:
130: //-- create xml
131:
132: private static Document createStep(PfixServletRequest request,
133: SPDocument spdoc) {
134: Document doc = Xml.createDocument();
135: Element step = doc.createElement("step");
136: doc.appendChild(step);
137: step.appendChild(doc.importNode(createRequest(request), true));
138: step.appendChild(doc.importNode(createResponse(spdoc), true));
139: return doc;
140: }
141:
142: private static void addElement(Element root, String name,
143: String text, String attr_name, String attr_value) {
144: Element new_ele = root.getOwnerDocument().createElement(name);
145: if (attr_name != null) {
146: new_ele.setAttribute(attr_name, attr_value);
147: }
148: Text text_node = root.getOwnerDocument().createTextNode(text);
149: new_ele.appendChild(text_node);
150: root.appendChild(new_ele);
151: }
152:
153: private static Node createRequest(PfixServletRequest request) {
154: Document doc = Xml.createDocument();
155: Element ele = doc.createElement("request");
156: String uri = request.getRequestURI();
157: String path = uri.substring(0, uri.indexOf(';'));
158: addElement(ele, "path", path, null, null);
159:
160: Element ele_params = doc.createElement("params");
161: String[] req_param_names = request.getRequestParamNames();
162: for (int i = 0; i < req_param_names.length; i++) {
163: String name = req_param_names[i];
164: RequestParam[] values = request.getAllRequestParams(name);
165: for (int j = 0; j < values.length; j++) {
166: if (!values[j].isSynthetic()) {
167: addElement(ele_params, "param", values[j]
168: .getValue(), "name", name);
169: }
170: }
171: }
172: ele.appendChild(ele_params);
173: return ele;
174: }
175:
176: private static Node createResponse(SPDocument doc) {
177: return doc.getDocument().getFirstChild();
178: }
179: }
|