Author: mrdon Date: Sat Apr 1 14:12:14 2006 New Revision: 390755 URL: http://svn.apache.org/viewcvs?rev=390755&view=rev Log: Adding the debugging interceptor that allows you tools for getting at the data behind the request. It can dump the data to the screen as XML and open an AJAX-enabled OGNL console that allows you to test OGNL expressions on the page's live data PR: WW-1279
Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/DebuggingInterceptor.java incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/PrettyPrintWriter.java incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/console.ftl incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.css incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.html incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.js Modified: incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/DispatcherUtils.java incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/FilterDispatcher.java incubator/webwork2/src/java/org/apache/struts/action2/util/AttributeMap.java incubator/webwork2/src/java/struts-default.xml Modified: incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/DispatcherUtils.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/DispatcherUtils.java?rev=390755&r1=390754&r2=390755&view=diff ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/DispatcherUtils.java (original) +++ incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/DispatcherUtils.java Sat Apr 1 14:12:14 2006 @@ -161,7 +161,7 @@ // test wether param-access workaround needs to be enabled if (servletContext.getServerInfo().indexOf("WebLogic") >= 0) { - LOG.info("WebLogic server detected. Enabling WebWork parameter access work-around."); + LOG.info("WebLogic server detected. Enabling Struts parameter access work-around."); paramsWorkaroundEnabled = true; } else if (Configuration.isSet(StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)) { paramsWorkaroundEnabled = "true".equals(Configuration.get(StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)); Modified: incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/FilterDispatcher.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/FilterDispatcher.java?rev=390755&r1=390754&r2=390755&view=diff ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/FilterDispatcher.java (original) +++ incubator/webwork2/src/java/org/apache/struts/action2/dispatcher/FilterDispatcher.java Sat Apr 1 14:12:14 2006 @@ -121,7 +121,7 @@ public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; String param = filterConfig.getInitParameter("packages"); - String packages = "org.apache.struts.action2.static template"; + String packages = "org.apache.struts.action2.static template org.apache.struts.action2.interceptor.debugging"; if (param != null) { packages = param + " " + packages; } Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/DebuggingInterceptor.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/DebuggingInterceptor.java?rev=390755&view=auto ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/DebuggingInterceptor.java (added) +++ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/DebuggingInterceptor.java Sat Apr 1 14:12:14 2006 @@ -0,0 +1,334 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.struts.action2.interceptor.debugging; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts.action2.ServletActionContext; +import org.apache.struts.action2.views.freemarker.FreemarkerResult; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.opensymphony.xwork.ActionContext; +import com.opensymphony.xwork.ActionInvocation; +import com.opensymphony.xwork.interceptor.Interceptor; +import com.opensymphony.xwork.interceptor.PreResultListener; +import com.opensymphony.xwork.util.OgnlValueStack; + +/** + * Provides several different debugging screens to provide insight into the + * data behind the page. The value of the 'debug' request parameter determines + * the screen: + * <ul> + * <li> <code>xml</code> - Dumps the parameters, context, session, and value + * stack as an XML document.</li> + * <li> <code>console</code> - Shows a popup 'OGNL Console' that allows the + * user to test OGNL expressions against the value stack. The XML data from + * the 'xml' mode is inserted at the top of the page.</li> + * <li> <code>command</code> - Tests an OGNL expression and returns the + * string result. Only used by the OGNL console.</li> + * </ul> + * <p> + * + * This interceptor only is activated when devMode is enabled in + * struts.properties. The 'debug' parameter is removed from the parameter list + * before the action is executed. All operations occur before the natural + * Result has a chance to execute. </p> + */ +public class DebuggingInterceptor implements Interceptor { + + private final static Log log = LogFactory.getLog(DebuggingInterceptor.class); + + private String[] ignorePrefixes = new String[]{"org.apache.struts.", + "com.opensymphony.xwork.", "xwork."}; + private String[] _ignoreKeys = new String[]{"application", "session", + "parameters", "request"}; + private HashSet ignoreKeys = new HashSet(Arrays.asList(_ignoreKeys)); + + private final static String XML_MODE = "xml"; + private final static String CONSOLE_MODE = "console"; + private final static String COMMAND_MODE = "command"; + + private final static String SESSION_KEY = "org.apache.struts.action2.interceptor.debugging.VALUE_STACK"; + + private final static String DEBUG_PARAM = "debug"; + private final static String EXPRESSION_PARAM = "expression"; + + + /** Unused. */ + public void init() { } + + + /** Unused. */ + public void destroy() { } + + + /* + * (non-Javadoc) + * + * @see com.opensymphony.xwork.interceptor.Interceptor#invoke(com.opensymphony.xwork.ActionInvocation) + */ + public String intercept(ActionInvocation inv) throws Exception { + + Boolean devMode = (Boolean) ActionContext.getContext().get( + ActionContext.DEV_MODE); + boolean cont = true; + if (devMode.booleanValue()) { + final ActionContext ctx = ActionContext.getContext(); + String type = getParameter(DEBUG_PARAM); + ctx.getParameters().remove(DEBUG_PARAM); + if (XML_MODE.equals(type)) { + inv.addPreResultListener( + new PreResultListener() { + public void beforeResult(ActionInvocation inv, String result) { + printContext(); + } + }); + } else if (CONSOLE_MODE.equals(type)) { + inv.addPreResultListener( + new PreResultListener() { + public void beforeResult(ActionInvocation inv, String actionResult) { + StringWriter writer = new StringWriter(); + printContext(new PrettyPrintWriter(writer)); + String xml = writer.toString(); + xml = xml.replaceAll("&", "&"); + xml = xml.replaceAll(">", ">"); + xml = xml.replaceAll("<", "<"); + ActionContext.getContext().put("debugXML", xml); + + ctx.getSession().put(SESSION_KEY, ctx.get(ctx.VALUE_STACK)); + + FreemarkerResult result = new FreemarkerResult(); + result.setContentType("text/html"); + result.setLocation("org/apache/struts/action2/interceptor/debugging/console.ftl"); + result.setParse(false); + try { + result.execute(inv); + } catch (Exception ex) { + log.error("Unable to create debugging console", ex); + } + + } + }); + } else if (COMMAND_MODE.equals(type)) { + OgnlValueStack stack = (OgnlValueStack) ctx.getSession().get(SESSION_KEY); + String cmd = getParameter(EXPRESION_PARAM); + + HttpServletResponse res = ServletActionContext.getResponse(); + res.setContentType("text/plain"); + + try { + PrintWriter writer = + ServletActionContext.getResponse().getWriter(); + writer.print(stack.findValue(cmd)); + writer.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + cont = false; + } + } + if (cont) { + return inv.invoke(); + } else { + return null; + } + } + + + /** + * Gets a single string from the request parameters + * + [EMAIL PROTECTED] key The key + [EMAIL PROTECTED] The parameter value + */ + private String getParameter(String key) { + String[] arr = (String[]) ActionContext.getContext().getParameters().get(key); + if (arr != null && arr.length > 0) { + return arr[0]; + } + return null; + } + + + /** Prints the current context to the response in XML format. */ + protected void printContext() { + HttpServletResponse res = ServletActionContext.getResponse(); + res.setContentType("text/xml"); + + try { + PrettyPrintWriter writer = new PrettyPrintWriter( + ServletActionContext.getResponse().getWriter()); + printContext(writer); + writer.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + + /** + * Prints the current request to the existing writer. + * + [EMAIL PROTECTED] writer The XML writer + */ + protected void printContext(PrettyPrintWriter writer) { + ActionContext ctx = ActionContext.getContext(); + writer.startNode(DEBUG_PARAM); + serializeIt(ctx.getParameters(), "parameters", writer, + new ArrayList()); + writer.startNode("context"); + String key; + Map ctxMap = ctx.getContextMap(); + for (Iterator i = ctxMap.keySet().iterator(); i.hasNext(); ) { + key = i.next().toString(); + boolean print = !ignoreKeys.contains(key); + + for (int x = 0; x < ignorePrefixes.length; x++) { + if (key.startsWith(ignorePrefixes[x])) { + print = false; + break; + } + } + if (print) { + serializeIt(ctxMap.get(key), key, writer, new ArrayList()); + } + } + writer.endNode(); + serializeIt(ctx.getSession(), "request", writer, new ArrayList()); + serializeIt(ctx.getSession(), "session", writer, new ArrayList()); + + OgnlValueStack stack = (OgnlValueStack) ctx.get(ActionContext.VALUE_STACK); + serializeIt(stack.getRoot(), "valueStack", writer, new ArrayList()); + writer.endNode(); + } + + + /** + * Recursive function to serialize objects to XML. Currently it will + * serialize Collections, maps, Arrays, and JavaBeans. It maintains a stack + * of objects serialized already in the current functioncall. This is used + * to avoid looping (stack overflow) of circular linked objects. Struts and + * XWork objects are ignored. + * + [EMAIL PROTECTED] bean The object you want serialized. + [EMAIL PROTECTED] name The name of the object, used for element <name/> + [EMAIL PROTECTED] writer The XML writer + [EMAIL PROTECTED] stack List of objects we're serializing since the first calling + * of this function (to prevent looping on circular references). + */ + protected void serializeIt(Object bean, String name, + PrettyPrintWriter writer, List stack) { + writer.flush(); + // Check stack for this object + if ((bean != null) && (stack.contains(bean))) { + if (log.isInfoEnabled()) { + log.info("Circular reference detected, not serializing object: " + + name); + } + return; + } else if (bean != null) { + // Push object onto stack. + // Don't push null objects ( handled below) + stack.add(bean); + } + if (bean == null) { + return; + } + String clsName = bean.getClass().getName(); + + writer.startNode(name); + + // It depends on the object and it's value what todo next: + if (bean instanceof Collection) { + Collection col = (Collection) bean; + + // Iterate through components, and call ourselves to process + // elements + for (Iterator i = col.iterator(); i.hasNext(); ) { + serializeIt(i.next(), "value", writer, stack); + } + } else if (bean instanceof Map) { + + Map map = (Map) bean; + + // Loop through keys and call ourselves + for (Iterator i = map.keySet().iterator(); i.hasNext(); ) { + Object key = i.next(); + Object Objvalue = map.get(key); + serializeIt(Objvalue, key.toString(), writer, stack); + } + } else if (bean.getClass().isArray()) { + // It's an array, loop through it and keep calling ourselves + for (int i = 0; i < Array.getLength(bean); i++) { + serializeIt(Array.get(bean, i), "arrayitem", writer, stack); + } + } else { + if (clsName != null && clsName.startsWith("org.apache.struts")) { + // ignore + } else if (clsName != null + && clsName.startsWith("com.opensymphony.xwork")) { + // ignore + } else if (clsName.startsWith("java.lang")) { + writer.setValue(bean.toString()); + } else { + // Not java.lang, so we can call ourselves with this object's + // values + try { + BeanInfo info = Introspector.getBeanInfo(bean.getClass()); + PropertyDescriptor[] props = info.getPropertyDescriptors(); + + for (int i = 0; i < props.length; i++) { + String n = props[i].getName(); + Method m = props[i].getReadMethod(); + + // Call ourselves with the result of the method + // invocation + if (m != null) { + serializeIt(m.invoke(bean, null), n, writer, stack); + } + } + } catch (Exception e) { + log.error(e, e); + } + } + } + + writer.endNode(); + + // Remove object from stack + stack.remove(bean); + } + +} + Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/PrettyPrintWriter.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/PrettyPrintWriter.java?rev=390755&view=auto ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/PrettyPrintWriter.java (added) +++ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/PrettyPrintWriter.java Sat Apr 1 14:12:14 2006 @@ -0,0 +1,181 @@ +package org.apache.struts.action2.interceptor.debugging; + +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.core.util.QuickWriter; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.io.Writer; + +/** + * A simple writer that outputs XML in a pretty-printed indented stream. + * + * <p>By default, the chars <code><xmp>& < > " ' \r</xmp></code> are escaped and replaced with a suitable XML entity. + * To alter this behavior, override the the [EMAIL PROTECTED] #writeText(com.thoughtworks.xstream.core.util.QuickWriter, String)} + * and [EMAIL PROTECTED] #writeAttributeValue(com.thoughtworks.xstream.core.util.QuickWriter, String)} methods.</p> + * + * <p>This code was taken from the XStream project under the BSD license.</p> + * + * @author Joe Walnes + */ +public class PrettyPrintWriter implements HierarchicalStreamWriter { + + private final QuickWriter writer; + private final FastStack elementStack = new FastStack(16); + private final char[] lineIndenter; + + private boolean tagInProgress; + private int depth; + private boolean readyForNewLine; + private boolean tagIsEmpty; + private String newLine; + + private static final char[] NULL = "�".toCharArray(); + private static final char[] AMP = "&".toCharArray(); + private static final char[] LT = "<".toCharArray(); + private static final char[] GT = ">".toCharArray(); + private static final char[] SLASH_R = "
".toCharArray(); + private static final char[] QUOT = """.toCharArray(); + private static final char[] APOS = "'".toCharArray(); + private static final char[] CLOSE = "</".toCharArray(); + + public PrettyPrintWriter(Writer writer, char[] lineIndenter, String newLine) { + this.writer = new QuickWriter(writer); + this.lineIndenter = lineIndenter; + this.newLine = newLine; + } + + public PrettyPrintWriter(Writer writer, char[] lineIndenter) { + this(writer, lineIndenter, "\n"); + } + + public PrettyPrintWriter(Writer writer, String lineIndenter, String newLine) { + this(writer, lineIndenter.toCharArray(), newLine); + } + + public PrettyPrintWriter(Writer writer, String lineIndenter) { + this(writer, lineIndenter.toCharArray()); + } + + public PrettyPrintWriter(Writer writer) { + this(writer, new char[]{' ', ' '}); + } + + public void startNode(String name) { + tagIsEmpty = false; + finishTag(); + writer.write('<'); + writer.write(name); + elementStack.push(name); + tagInProgress = true; + depth++; + readyForNewLine = true; + tagIsEmpty = true; + } + + public void setValue(String text) { + readyForNewLine = false; + tagIsEmpty = false; + finishTag(); + + writeText(writer, text); + } + + public void addAttribute(String key, String value) { + writer.write(' '); + writer.write(key); + writer.write('='); + writer.write('\"'); + writeAttributeValue(writer, value); + writer.write('\"'); + } + + protected void writeAttributeValue(QuickWriter writer, String text) { + writeText(text); + } + + protected void writeText(QuickWriter writer, String text) { + writeText(text); + } + + private void writeText(String text) { + int length = text.length(); + for (int i = 0; i < length; i++) { + char c = text.charAt(i); + switch (c) { + case '\0': + this.writer.write(NULL); + break; + case '&': + this.writer.write(AMP); + break; + case '<': + this.writer.write(LT); + break; + case '>': + this.writer.write(GT); + break; + case '"': + this.writer.write(QUOT); + break; + case '\'': + this.writer.write(APOS); + break; + case '\r': + this.writer.write(SLASH_R); + break; + default: + this.writer.write(c); + } + } + } + + public void endNode() { + depth--; + if (tagIsEmpty) { + writer.write('/'); + readyForNewLine = false; + finishTag(); + elementStack.popSilently(); + } else { + finishTag(); + writer.write(CLOSE); + writer.write((String)elementStack.pop()); + writer.write('>'); + } + readyForNewLine = true; + if (depth == 0 ) { + writer.flush(); + } + } + + private void finishTag() { + if (tagInProgress) { + writer.write('>'); + } + tagInProgress = false; + if (readyForNewLine) { + endOfLine(); + } + readyForNewLine = false; + tagIsEmpty = false; + } + + protected void endOfLine() { + writer.write(newLine); + for (int i = 0; i < depth; i++) { + writer.write(lineIndenter); + } + } + + public void flush() { + writer.flush(); + } + + public void close() { + writer.close(); + } + + public HierarchicalStreamWriter underlyingWriter() { + return this; + } +} Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/console.ftl URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/console.ftl?rev=390755&view=auto ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/console.ftl (added) +++ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/console.ftl Sat Apr 1 14:12:14 2006 @@ -0,0 +1,14 @@ +<html> +<head> + <script language="javascript"> + var baseUrl = "<@ww.url value="/struts"/>"; + window.open(baseUrl+"/webconsole.html", 'OGNL Console','width=500,height=450,'+ + 'status=no,toolbar=no,menubar=no'); + </script> +</head> +<body> +<pre> + ${debugXML} +</pre> +</body> +</html> Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.css URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.css?rev=390755&view=auto ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.css (added) +++ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.css Sat Apr 1 14:12:14 2006 @@ -0,0 +1,19 @@ +.wc-results { + overflow: auto; + margin: 0px; + padding: 5px; + font-family: courier; + color: white; + background-color: black; + height: 400px; +} +.wc-results pre { + display: inline; +} +.wc-command { + margin: 0px; + font-family: courier; + color: white; + background-color: black; + width: 100%; +} Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.html URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.html?rev=390755&view=auto ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.html (added) +++ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.html Sat Apr 1 14:12:14 2006 @@ -0,0 +1,21 @@ +<html> +<head> + <link rel="stylesheet" type="text/css" href="webconsole.css" /> +<script src="webconsole.js"></script> +<script src="dojo/dojo.js"></script> +<script src="dojo/src/event/__package__.js"></script> +<title>OGNL Console</title> +</head> +<body> +<div id="shell" > + <form onsubmit="return false"> + <div class="wc-results" id="wc-result"> + Welcome to the OGNL console! + <br /> + :-> + </div> + <input onkeyup="keyEvent(event)" class="wc-command" id="wc-command" type="text" /> + </form> +</div> +</body> +</html> Added: incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.js URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.js?rev=390755&view=auto ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.js (added) +++ incubator/webwork2/src/java/org/apache/struts/action2/interceptor/debugging/webconsole.js Sat Apr 1 14:12:14 2006 @@ -0,0 +1,58 @@ + function printResult(result_string) + { + var result_div = document.getElementById('wc-result'); + var result_array = result_string.split('\n'); + + var new_command = document.getElementById('wc-command').value; + result_div.appendChild(document.createTextNode(new_command)); + result_div.appendChild(document.createElement('br')); + + for (var line_index in result_array) { + var result_wrap = document.createElement('pre') + line = document.createTextNode(result_array[line_index]); + result_wrap.appendChild(line); + result_div.appendChild(result_wrap); + result_div.appendChild(document.createElement('br')); + + } + result_div.appendChild(document.createTextNode(':-> ')); + + result_div.scrollTop = result_div.scrollHeight; + document.getElementById('wc-command').value = ''; + } + + function keyEvent(event) + { + switch(event.keyCode){ + case 13: + var the_shell_command = document.getElementById('wc-command').value; + if (the_shell_command) { + commands_history[commands_history.length] = the_shell_command; + history_pointer = commands_history.length; + var the_url = window.opener.location.pathname + '?debug=command&expression='+escape(the_shell_command); + dojo.io.bind({ + url: the_url, + load: function(type, data, evt){ printResult(data); }, + mimetype: "text/plain" + }); + } + break; + case 38: // this is the arrow up + if (history_pointer > 0) { + history_pointer--; + document.getElementById('wc-command').value = commands_history[history_pointer]; + } + break; + case 40: // this is the arrow down + if (history_pointer < commands_history.length - 1 ) { + history_pointer++; + document.getElementById('wc-command').value = commands_history[history_pointer]; + } + break; + default: + break; + } + } + + var commands_history = new Array(); + var history_pointer; Modified: incubator/webwork2/src/java/org/apache/struts/action2/util/AttributeMap.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/org/apache/struts/action2/util/AttributeMap.java?rev=390755&r1=390754&r2=390755&view=diff ============================================================================== --- incubator/webwork2/src/java/org/apache/struts/action2/util/AttributeMap.java (original) +++ incubator/webwork2/src/java/org/apache/struts/action2/util/AttributeMap.java Sat Apr 1 14:12:14 2006 @@ -8,6 +8,7 @@ import javax.servlet.jsp.PageContext; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.Set; @@ -56,7 +57,7 @@ } public Set entrySet() { - throw new UnsupportedOperationException(UNSUPPORTED); + return Collections.EMPTY_SET; } public Object get(Object key) { @@ -86,7 +87,7 @@ } public Set keySet() { - throw new UnsupportedOperationException(UNSUPPORTED); + return Collections.EMPTY_SET; } public Object put(Object key, Object value) { @@ -111,7 +112,7 @@ } public Collection values() { - throw new UnsupportedOperationException(UNSUPPORTED); + return Collections.EMPTY_SET; } private PageContext getPageContext() { Modified: incubator/webwork2/src/java/struts-default.xml URL: http://svn.apache.org/viewcvs/incubator/webwork2/src/java/struts-default.xml?rev=390755&r1=390754&r2=390755&view=diff ============================================================================== --- incubator/webwork2/src/java/struts-default.xml (original) +++ incubator/webwork2/src/java/struts-default.xml Sat Apr 1 14:12:14 2006 @@ -30,6 +30,7 @@ <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/> <interceptor name="conversionError" class="org.apache.struts.action2.interceptor.StrutsConversionErrorInterceptor"/> <interceptor name="createSession" class="org.apache.struts.action2.interceptor.CreateSessionInterceptor" /> + <interceptor name="debugging" class="org.apache.struts.action2.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="external-ref" class="com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor"/> <interceptor name="execAndWait" class="org.apache.struts.action2.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception" class="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor"/> @@ -156,6 +157,7 @@ <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> + <interceptor-ref name="debugging"/> <interceptor-ref name="model-driven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="static-params"/> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]