You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/02 17:33:45 UTC

svn commit: r1209569 [30/50] - in /struts/struts2/branches/STRUTS_3_X: apps/blank/src/main/java/example/ apps/blank/src/test/java/example/ apps/jboss-blank/src/main/java/example/ apps/jboss-blank/src/test/java/example/ apps/mailreader/src/main/java/mai...

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/LocationUtils.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/LocationUtils.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/LocationUtils.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/LocationUtils.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2005 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.struts2.xwork2.util.location;
+
+import org.apache.struts2.xwork2.util.ClassLoaderUtil;
+import org.w3c.dom.Element;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Location-related utility methods.
+ */
+public class LocationUtils {
+    
+    /**
+     * The string representation of an unknown location: "<code>[unknown location]</code>".
+     */
+    public static final String UNKNOWN_STRING = "[unknown location]";
+    
+    private static List<WeakReference<LocationFinder>> finders = new ArrayList<WeakReference<LocationFinder>>();
+    
+    /**
+     * An finder or object locations
+     */
+    public interface LocationFinder {
+        /**
+         * Get the location of an object
+         * @param obj the object for which to find a location
+         * @param description and optional description to be added to the object's location
+         * @return the object's location or <code>null</code> if object's class isn't handled
+         *         by this finder.
+         */
+        Location getLocation(Object obj, String description);
+    }
+
+    private LocationUtils() {
+        // Forbid instanciation
+    }
+    
+    /**
+     * Builds a string representation of a location, in the
+     * "<code><em>descripton</em> - <em>uri</em>:<em>line</em>:<em>column</em></code>"
+     * format (e.g. "<code>foo - file://path/to/file.xml:3:40</code>"). For {@link Location#UNKNOWN an unknown location}, returns
+     * {@link #UNKNOWN_STRING}.
+     * 
+     * @return the string representation
+     */
+    public static String toString(Location location) {
+        StringBuilder result = new StringBuilder();
+
+        String description = location.getDescription();
+        if (description != null) {
+            result.append(description).append(" - ");
+        }
+
+        String uri = location.getURI();
+        if (uri != null) {
+            result.append(uri).append(':').append(location.getLineNumber()).append(':').append(location.getColumnNumber());
+        } else {
+            result.append(UNKNOWN_STRING);
+        }
+        
+        return result.toString();
+    }
+
+    /**
+     * Parse a location string of the form "<code><em>uri</em>:<em>line</em>:<em>column</em></code>" (e.g.
+     * "<code>path/to/file.xml:3:40</code>") to a Location object. Additionally, a description may
+     * also optionally be present, separated with an hyphen (e.g. "<code>foo - path/to/file.xml:3.40</code>").
+     * 
+     * @param text the text to parse
+     * @return the location (possibly <code>null</code> if text was null or in an incorrect format)
+     */
+    public static LocationImpl parse(String text) throws IllegalArgumentException {
+        if (text == null || text.length() == 0) {
+            return null;
+        }
+
+        // Do we have a description?
+        String description;
+        int uriStart = text.lastIndexOf(" - "); // lastIndexOf to allow the separator to be in the description
+        if (uriStart > -1) {
+            description = text.substring(0, uriStart);
+            uriStart += 3; // strip " - "
+        } else {
+            description = null;
+            uriStart = 0;
+        }
+        
+        try {
+            int colSep = text.lastIndexOf(':');
+            if (colSep > -1) {
+                int column = Integer.parseInt(text.substring(colSep + 1));
+                
+                int lineSep = text.lastIndexOf(':', colSep - 1);
+                if (lineSep > -1) {
+                    int line = Integer.parseInt(text.substring(lineSep + 1, colSep));
+                    return new LocationImpl(description, text.substring(uriStart, lineSep), line, column);
+                }
+            } else {
+                // unkonwn?
+                if (text.endsWith(UNKNOWN_STRING)) {
+                    return LocationImpl.UNKNOWN;
+                }
+            }
+        } catch(Exception e) {
+            // Ignore: handled below
+        }
+        
+        return LocationImpl.UNKNOWN;
+    }
+
+    /**
+     * Checks if a location is known, i.e. it is not null nor equal to {@link Location#UNKNOWN}.
+     * 
+     * @param location the location to check
+     * @return <code>true</code> if the location is known
+     */
+    public static boolean isKnown(Location location) {
+        return location != null && !Location.UNKNOWN.equals(location);
+    }
+
+    /**
+     * Checks if a location is unknown, i.e. it is either null or equal to {@link Location#UNKNOWN}.
+     * 
+     * @param location the location to check
+     * @return <code>true</code> if the location is unknown
+     */
+    public static boolean isUnknown(Location location) {
+        return location == null || Location.UNKNOWN.equals(location);
+    }
+
+    /**
+     * Add a {@link LocationFinder} to the list of finders that will be queried for an object's
+     * location by {@link #getLocation(Object, String)}.
+     * <p>
+     * <b>Important:</b> LocationUtils internally stores a weak reference to the finder. This
+     * avoids creating strong links between the classloader holding this class and the finder's
+     * classloader, which can cause some weird memory leaks if the finder's classloader is to
+     * be reloaded. Therefore, you <em>have</em> to keep a strong reference to the finder in the
+     * calling code, e.g.:
+     * <pre>
+     *   private static LocationUtils.LocationFinder myFinder =
+     *       new LocationUtils.LocationFinder() {
+     *           public Location getLocation(Object obj, String desc) {
+     *               ...
+     *           }
+     *       };
+     *
+     *   static {
+     *       LocationUtils.addFinder(myFinder);
+     *   }
+     * </pre>
+     * 
+     * @param finder the location finder to add
+     */
+    public static void addFinder(LocationFinder finder) {
+        if (finder == null) {
+            return;
+        }
+
+        synchronized(LocationFinder.class) {
+            // Update a clone of the current finder list to avoid breaking
+            // any iteration occuring in another thread.
+            List<WeakReference<LocationFinder>> newFinders = new ArrayList<WeakReference<LocationFinder>>(finders);
+            newFinders.add(new WeakReference<LocationFinder>(finder));
+            finders = newFinders;
+        }
+    }
+    
+    /**
+     * Get the location of an object. Some well-known located classes built in the JDK are handled
+     * by this method. Handling of other located classes can be handled by adding new location finders.
+     * 
+     * @param obj the object of which to get the location
+     * @return the object's location, or {@link Location#UNKNOWN} if no location could be found
+     */
+    public static Location getLocation(Object obj) {
+        return getLocation(obj, null);
+    }
+    
+    /**
+     * Get the location of an object. Some well-known located classes built in the JDK are handled
+     * by this method. Handling of other located classes can be handled by adding new location finders.
+     * 
+     * @param obj the object of which to get the location
+     * @param description an optional description of the object's location, used if a Location object
+     *        has to be created.
+     * @return the object's location, or {@link Location#UNKNOWN} if no location could be found
+     */
+    public static Location getLocation(Object obj, String description) {
+        if (obj instanceof Location) {
+            return (Location) obj;
+        }
+        
+        if (obj instanceof Locatable) {
+            return ((Locatable)obj).getLocation();
+        }
+        
+        // Check some well-known locatable exceptions
+        if (obj instanceof SAXParseException) {
+            SAXParseException spe = (SAXParseException)obj;
+            if (spe.getSystemId() != null) {
+                return new LocationImpl(description, spe.getSystemId(), spe.getLineNumber(), spe.getColumnNumber());
+            } else {
+                return Location.UNKNOWN;
+            }
+        }
+        
+        if (obj instanceof TransformerException) {
+            TransformerException ex = (TransformerException)obj;
+            SourceLocator locator = ex.getLocator();
+            if (locator != null && locator.getSystemId() != null) {
+                return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+            } else {
+                return Location.UNKNOWN;
+            }
+        }
+        
+        if (obj instanceof Locator) {
+            Locator locator = (Locator)obj;
+            if (locator.getSystemId() != null) {
+                return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+            } else {
+                return Location.UNKNOWN;
+            }
+        }
+        
+        if (obj instanceof Element) {
+            return LocationAttributes.getLocation((Element)obj);
+        }
+
+        List<WeakReference<LocationFinder>> currentFinders = finders; // Keep the current list
+        int size = currentFinders.size();
+        for (int i = 0; i < size; i++) {
+            WeakReference<LocationFinder> ref = currentFinders.get(i);
+            LocationFinder finder = ref.get();
+            if (finder == null) {
+                // This finder was garbage collected: update finders
+                synchronized(LocationFinder.class) {
+                    // Update a clone of the current list to avoid breaking current iterations
+                    List<WeakReference<LocationFinder>> newFinders = new ArrayList<WeakReference<LocationFinder>>(finders);
+                    newFinders.remove(ref);
+                    finders = newFinders;
+                }
+            }
+            
+            Location result = finder.getLocation(obj, description);
+            if (result != null) {
+                return result;
+            }
+        }
+        
+        if (obj instanceof Throwable) {
+        		Throwable t = (Throwable) obj;
+        		StackTraceElement[] stack = t.getStackTrace();
+        		if (stack != null && stack.length > 0) {
+        			StackTraceElement trace = stack[0];
+        			if (trace.getLineNumber() >= 0) {
+	        			String uri = trace.getClassName();
+	        			if (trace.getFileName() != null) {
+	        				uri = uri.replace('.','/');
+	        				uri = uri.substring(0, uri.lastIndexOf('/') + 1);
+	        				uri = uri + trace.getFileName();
+	        				URL url = ClassLoaderUtil.getResource(uri, LocationUtils.class);
+	        				if (url != null) {
+        						uri = url.toString();
+	        				}
+	        			}
+	        			if (description == null) {
+	        				StringBuilder sb = new StringBuilder();
+	        				sb.append("Class: ").append(trace.getClassName()).append("\n");
+	        				sb.append("File: ").append(trace.getFileName()).append("\n");
+	        				sb.append("Method: ").append(trace.getMethodName()).append("\n");
+	        				sb.append("Line: ").append(trace.getLineNumber());
+	        				description = sb.toString();
+	        			}
+	        			return new LocationImpl(description, uri, trace.getLineNumber(), -1);
+        			}
+        		}
+        }
+
+        return Location.UNKNOWN;
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/package.html?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/package.html (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/location/package.html Fri Dec  2 16:33:03 2011
@@ -0,0 +1,3 @@
+<html>
+  <body>Classes and utilities used to track location information.</body>
+</html>
\ No newline at end of file

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/Logger.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/Logger.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/Logger.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/Logger.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging;
+
+/**
+ * Main logger interface for logging things
+ */
+public interface Logger {
+    void trace(String msg, String... args);
+    void trace(String msg, Throwable ex, String... args);
+    boolean isTraceEnabled();
+    
+    void debug(String msg, String... args);
+    void debug(String msg, Throwable ex, String... args);
+    boolean isDebugEnabled();
+    
+    void info(String msg, String... args);
+    void info(String msg, Throwable ex, String... args);
+    boolean isInfoEnabled();
+    
+    void warn(String msg, String... args);
+    void warn(String msg, Throwable ex, String... args);
+    boolean isWarnEnabled();
+    
+    void error(String msg, String... args);
+    void error(String msg, Throwable ex, String... args);
+    boolean isErrorEnabled();
+    
+    void fatal(String msg, String... args);
+    void fatal(String msg, Throwable ex, String... args);
+    boolean isFatalEnabled();
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerFactory.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging;
+
+import org.apache.struts2.xwork2.util.logging.commons.CommonsLoggerFactory;
+import org.apache.struts2.xwork2.util.logging.jdk.JdkLoggerFactory;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Creates loggers.  Static accessor will lazily try to decide on the best factory if none specified.
+ */
+public abstract class LoggerFactory {
+    
+    private static final ReadWriteLock lock = new ReentrantReadWriteLock();
+    private static LoggerFactory factory;
+    
+    public static void setLoggerFactory(LoggerFactory factory) {
+        lock.writeLock().lock();
+        try {
+            LoggerFactory.factory = factory;
+        } finally {
+            lock.writeLock().unlock();
+        }
+            
+    }
+    
+    public static Logger getLogger(Class<?> cls) {
+        return getLoggerFactory().getLoggerImpl(cls);
+    }
+    
+    public static Logger getLogger(String name) {
+        return getLoggerFactory().getLoggerImpl(name);
+    }
+    
+    protected static LoggerFactory getLoggerFactory() {
+        lock.readLock().lock();
+        try {
+            if (factory != null) {
+                return factory;
+            }
+        } finally {
+            lock.readLock().unlock();
+        }
+        lock.writeLock().lock();
+        try {
+            if (factory == null) {
+                try {
+                    Class.forName("org.apache.commons.logging.LogFactory");
+                    factory = new CommonsLoggerFactory();
+                } catch (ClassNotFoundException ex) {
+                    // commons logging not found, falling back to jdk logging
+                    factory = new JdkLoggerFactory();
+                }
+            }
+            return factory;
+        }
+        finally {
+            lock.writeLock().unlock();
+        }
+    }
+    
+    protected abstract Logger getLoggerImpl(Class<?> cls);
+    
+    protected abstract Logger getLoggerImpl(String name); 
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerUtils.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerUtils.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerUtils.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/LoggerUtils.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging;
+
+/**
+ * Logging utility methods
+ */
+public class LoggerUtils {
+
+    /**
+     * Formats messages using parameters. For example, the call:
+     * 
+     * <pre>
+     * format("foo #1", "bob");
+     * </pre>
+     * 
+     * will return:
+     * <pre>
+     * foo bob
+     * </pre>
+     * 
+     * @param msg The message
+     * @param args A list of arguments.  A maximum of 10 are supported.
+     * @return The formatted string
+     */
+    public static String format(String msg, String... args) {
+        if (msg != null && msg.length() > 0 && msg.indexOf('#') > -1) {
+            StringBuilder sb = new StringBuilder();
+            boolean isArg = false;
+            for (int x = 0; x < msg.length(); x++) {
+                char c = msg.charAt(x);
+                if (isArg) {
+                    isArg = false;
+                    if (Character.isDigit(c)) {
+                        int val = Character.getNumericValue(c);
+                        if (val >= 0 && val < args.length) {
+                            sb.append(args[val]);
+                            continue;
+                        }
+                    }
+                    sb.append('#');
+                }
+                if (c == '#') {
+                    isArg = true;
+                    continue;
+                }
+                sb.append(c);
+            }
+            
+            if (isArg) {
+                sb.append('#');
+            }
+            return sb.toString();
+        }
+        return msg;
+        
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLogger.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLogger.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLogger.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLogger.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging.commons;
+
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerUtils;
+import org.apache.commons.logging.Log;
+
+/**
+ * Simple logger that delegates to commons logging
+ */
+public class CommonsLogger implements Logger {
+    
+    private Log log;
+    
+    public CommonsLogger(Log log) {
+        this.log = log;
+    }
+
+    public void error(String msg, String... args) {
+        log.error(LoggerUtils.format(msg, args));
+    }
+
+    public void error(String msg, Throwable ex, String... args) {
+        log.error(LoggerUtils.format(msg, args), ex);
+    }
+
+    public void info(String msg, String... args) {
+        log.info(LoggerUtils.format(msg, args));
+    }
+
+    public void info(String msg, Throwable ex, String... args) {
+        log.info(LoggerUtils.format(msg, args), ex);
+    }
+
+    
+
+    public boolean isInfoEnabled() {
+        return log.isInfoEnabled();
+    }
+
+    public void warn(String msg, String... args) {
+        log.warn(LoggerUtils.format(msg, args));
+    }
+
+    public void warn(String msg, Throwable ex, String... args) {
+        log.warn(LoggerUtils.format(msg, args), ex);
+    }
+    
+    public boolean isDebugEnabled() {
+        return log.isDebugEnabled();
+    }
+    
+    public void debug(String msg, String... args) {
+        log.debug(LoggerUtils.format(msg, args));
+    }
+
+    public void debug(String msg, Throwable ex, String... args) {
+        log.debug(LoggerUtils.format(msg, args), ex);
+    }
+    
+    public boolean isTraceEnabled() {
+        return log.isTraceEnabled();
+    }
+    
+    public void trace(String msg, String... args) {
+        log.trace(LoggerUtils.format(msg, args));
+    }
+
+    public void trace(String msg, Throwable ex, String... args) {
+        log.trace(LoggerUtils.format(msg, args), ex);
+    }
+
+
+    public void fatal(String msg, String... args) {
+        log.fatal(LoggerUtils.format(msg, args));
+    }
+
+    public void fatal(String msg, Throwable ex, String... args) {
+        log.fatal(LoggerUtils.format(msg, args), ex);
+    }
+
+    public boolean isErrorEnabled() {
+        return log.isErrorEnabled();
+    }
+
+    public boolean isFatalEnabled() {
+        return log.isFatalEnabled();
+    }
+
+    public boolean isWarnEnabled() {
+        return log.isWarnEnabled();
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLoggerFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLoggerFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLoggerFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/commons/CommonsLoggerFactory.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging.commons;
+
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Creates commons-logging-backed loggers
+ */
+public class CommonsLoggerFactory extends LoggerFactory {
+
+    @Override
+    protected Logger getLoggerImpl(Class<?> cls) {
+        return new CommonsLogger(LogFactory.getLog(cls));
+    }
+    
+    @Override
+    protected Logger getLoggerImpl(String name) {
+        return new CommonsLogger(LogFactory.getLog(name));
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLogger.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLogger.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLogger.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLogger.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging.jdk;
+
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerUtils;
+
+import java.util.logging.Level;
+
+/**
+ * Delegates to jdk logger.  Maps fatal to Level.SEVERE along with error.
+ */
+public class JdkLogger implements Logger {
+    
+    private java.util.logging.Logger log;
+    
+    public JdkLogger(java.util.logging.Logger log) {
+        this.log = log;
+    }
+
+    public void error(String msg, String... args) {
+        log.log(Level.SEVERE, LoggerUtils.format(msg, args));
+    }
+
+    public void error(String msg, Throwable ex, String... args) {
+        log.log(Level.SEVERE, LoggerUtils.format(msg, args), ex);
+    }
+    
+    public void fatal(String msg, String... args) {
+        log.log(Level.SEVERE, LoggerUtils.format(msg, args));
+    }
+
+    public void fatal(String msg, Throwable ex, String... args) {
+        log.log(Level.SEVERE, LoggerUtils.format(msg, args), ex);
+    }
+
+    public void info(String msg, String... args) {
+        log.log(Level.INFO, LoggerUtils.format(msg, args));
+    }
+
+    public void info(String msg, Throwable ex, String... args) {
+        log.log(Level.INFO, LoggerUtils.format(msg, args), ex);
+    }
+
+    public boolean isInfoEnabled() {
+        return log.isLoggable(Level.INFO);
+    }
+
+    public void warn(String msg, String... args) {
+        log.log(Level.WARNING, LoggerUtils.format(msg, args));
+    }
+
+    public void warn(String msg, Throwable ex, String... args) {
+        log.log(Level.WARNING, LoggerUtils.format(msg, args), ex);
+    }
+    
+    public boolean isDebugEnabled() {
+        return log.isLoggable(Level.FINE);
+    }
+    
+    public void debug(String msg, String... args) {
+        log.log(Level.FINE, LoggerUtils.format(msg, args));
+    }
+
+    public void debug(String msg, Throwable ex, String... args) {
+        log.log(Level.FINE, LoggerUtils.format(msg, args), ex);
+    }
+    
+    public boolean isTraceEnabled() {
+        return log.isLoggable(Level.FINEST);
+    }
+    
+    public void trace(String msg, String... args) {
+        log.log(Level.FINEST, LoggerUtils.format(msg, args));
+    }
+
+    public void trace(String msg, Throwable ex, String... args) {
+        log.log(Level.FINEST, LoggerUtils.format(msg, args), ex);
+    }
+
+    public boolean isErrorEnabled() {
+        return log.isLoggable(Level.SEVERE);
+    }
+
+    public boolean isFatalEnabled() {
+        return log.isLoggable(Level.SEVERE);
+    }
+
+    public boolean isWarnEnabled() {
+        return log.isLoggable(Level.WARNING);
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLoggerFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLoggerFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLoggerFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/logging/jdk/JdkLoggerFactory.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.logging.jdk;
+
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+
+/**
+ * Creates jdk loggers
+ */
+public class JdkLoggerFactory extends LoggerFactory {
+
+    @Override
+    protected Logger getLoggerImpl(Class<?> cls) {
+        return new JdkLogger(java.util.logging.Logger.getLogger(cls.getName()));
+    }
+    
+    @Override
+    protected Logger getLoggerImpl(String name) {
+        return new JdkLogger(java.util.logging.Logger.getLogger(name));
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/package.html?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/package.html (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/package.html Fri Dec  2 16:33:03 2011
@@ -0,0 +1 @@
+<body>XWork util classes.</body>

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ObjectProfiler.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ObjectProfiler.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ObjectProfiler.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ObjectProfiler.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2002-2003, Atlassian Software Systems Pty Ltd All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *     * Neither the name of Atlassian Software Systems Pty Ltd nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.apache.struts2.xwork2.util.profiling;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * @author <a href="mailto:scott@atlassian.com">Scott Farquhar</a>
+ */
+public class ObjectProfiler
+{
+
+    /**
+     * Given a class, and an interface that it implements, return a proxied version of the class that implements
+     * the interface.
+     * <p>
+     * The usual use of this is to profile methods from Factory objects:
+     * <pre>
+     * public PersistenceManager getPersistenceManager()
+     * {
+     *   return new DefaultPersistenceManager();
+     * }
+     *
+     * instead write:
+     * public PersistenceManager getPersistenceManager()
+     * {
+     *   return ObjectProfiler.getProfiledObject(PersistenceManager.class, new DefaultPersistenceManager());
+     * }
+     * </pre>
+     * <p>
+     * A side effect of this is that you will no longer be able to downcast to DefaultPersistenceManager.  This is probably a *good* thing.
+     *
+     * @param interfaceClazz    The interface to implement.
+     * @param o                 The object to proxy
+     * @return                  A proxied object, or the input object if the interfaceClazz wasn't an interface.
+     */
+    public static Object getProfiledObject(Class interfaceClazz, Object o)
+    {
+        //if we are not active - then do nothing
+        if (!UtilTimerStack.isActive())
+            return o;
+
+        //this should always be true - you shouldn't be passing something that isn't an interface
+        if (interfaceClazz.isInterface())
+        {
+            InvocationHandler timerHandler = new TimerInvocationHandler(o);
+            return Proxy.newProxyInstance(interfaceClazz.getClassLoader(),
+                    new Class[]{interfaceClazz}, timerHandler);
+        }
+        else
+        {
+            return o;
+        }
+    }
+
+    /**
+     * A profiled call {@link Method#invoke(java.lang.Object, java.lang.Object[])}. If {@link UtilTimerStack#isActive() }
+     * returns false, then no profiling is performed.
+     */
+    public static Object profiledInvoke(Method target, Object value, Object[] args) throws IllegalAccessException, InvocationTargetException
+    {
+        //if we are not active - then do nothing
+        if (!UtilTimerStack.isActive())
+            return target.invoke(value, args);
+
+        String logLine = new String(getTrimmedClassName(target) + "." + target.getName() + "()");
+
+        UtilTimerStack.push(logLine);
+        try
+        {
+            Object returnValue = target.invoke(value, args);
+
+            //if the return value is an interface then we should also proxy it!
+            if (returnValue != null && target.getReturnType().isInterface())
+            {
+//                System.out.println("Return type " + returnValue.getClass().getName() + " is being proxied " + target.getReturnType().getName() + " " + logLine);
+                InvocationHandler timerHandler = new TimerInvocationHandler(returnValue);
+                return Proxy.newProxyInstance(returnValue.getClass().getClassLoader(),
+                        new Class[]{target.getReturnType()}, timerHandler);
+            }
+            else
+            {
+                return returnValue;
+            }
+        }
+        finally
+        {
+            UtilTimerStack.pop(logLine);
+        }
+    }
+
+    /**
+     * Given a method, get the Method name, with no package information.
+     */
+    public static String getTrimmedClassName(Method method)
+    {
+        String classname = method.getDeclaringClass().getName();
+        return classname.substring(classname.lastIndexOf('.') + 1);
+    }
+
+}
+
+class TimerInvocationHandler implements InvocationHandler
+{
+    protected Object target;
+
+    public TimerInvocationHandler(Object target)
+    {
+        if (target == null)
+            throw new IllegalArgumentException("Target Object passed to timer cannot be null");
+        this.target = target;
+    }
+
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+    {
+        return ObjectProfiler.profiledInvoke(method, target, args);
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ProfilingTimerBean.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ProfilingTimerBean.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ProfilingTimerBean.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/ProfilingTimerBean.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2002-2003, Atlassian Software Systems Pty Ltd All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *     * Neither the name of Atlassian Software Systems Pty Ltd nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.apache.struts2.xwork2.util.profiling;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Bean to contain information about the pages profiled
+ *
+ * @author <a href="mailto:mike@atlassian.com">Mike Cannon-Brookes</a>
+ * @author <a href="mailto:scott@atlassian.com">Scott Farquhar</a>
+ * 
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: ProfilingTimerBean.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class ProfilingTimerBean implements java.io.Serializable {
+	
+	private static final long serialVersionUID = -6180672043920208784L;
+	
+	List<ProfilingTimerBean> children = new ArrayList<ProfilingTimerBean>();
+    ProfilingTimerBean parent = null;
+
+    String resource;
+
+    long startTime;
+    long totalTime;
+
+    public ProfilingTimerBean(String resource)
+    {
+        this.resource = resource;
+    }
+
+    protected void addParent(ProfilingTimerBean parent)
+    {
+        this.parent = parent;
+    }
+
+    public ProfilingTimerBean getParent()
+    {
+        return parent;
+    }
+
+
+    public void addChild(ProfilingTimerBean child)
+    {
+        children.add(child);
+        child.addParent(this);
+    }
+
+
+    public void setStartTime()
+    {
+        this.startTime = System.currentTimeMillis();
+    }
+
+    public void setEndTime()
+    {
+        this.totalTime = System.currentTimeMillis() - startTime;
+    }
+
+    public String getResource()
+    {
+        return resource;
+    }
+
+    /**
+     * Get a formatted string representing all the methods that took longer than a specified time.
+     */
+
+    public String getPrintable(long minTime)
+    {
+        return getPrintable("", minTime);
+    }
+
+    protected String getPrintable(String indent, long minTime)
+    {
+        //only print the value if we are larger or equal to the min time.
+        if (totalTime >= minTime)
+        {
+            StringBuilder buffer = new StringBuilder();
+            buffer.append(indent);
+            buffer.append("[" + totalTime + "ms] - " + resource);
+            buffer.append("\n");
+
+            for (ProfilingTimerBean aChildren : children) {
+                buffer.append((aChildren).getPrintable(indent + "  ", minTime));
+            }
+
+            return buffer.toString();
+        }
+        else
+            return "";
+    }
+}
+

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/UtilTimerStack.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/UtilTimerStack.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/UtilTimerStack.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/UtilTimerStack.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2002-2003, Atlassian Software Systems Pty Ltd All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *     * Neither the name of Atlassian Software Systems Pty Ltd nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.apache.struts2.xwork2.util.profiling;
+
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+
+
+/**
+ * A timer stack.
+ *
+ * <p />
+ * 
+ * <!-- START SNIPPET: profilingAspect_struts2 -->
+ * 
+ * Struts2 profiling aspects involves the following :-
+ * <ul>
+ *   <li>ActionContextCleanUp</li>
+ *   <li>FreemarkerPageFilter</li>
+ *   <li>DispatcherFilter</li>
+ *   <ul>
+ *      <li>Dispatcher</li>
+ *      <ul>
+ *          <li>creation of DefaultActionProxy</li>
+ *          <ul>
+ *              <li>creation of DefaultActionInvocation</li>
+ *              <ul>
+ *   	          <li>creation of Action</li>
+ *              </ul>
+ *          </ul>
+ *          <li>execution of DefaultActionProxy</li>
+ *          <ul>
+ *              <li>invocation of DefaultActionInvocation</li>
+ *              <ul>
+ *                  <li>invocation of Interceptors</li>
+ *                  <li>invocation of Action</li>
+ *                  <li>invocation of PreResultListener</li>
+ *                  <li>invocation of Result</li>
+ *              </ul>
+ *          </ul>
+ *      </ul>
+ *   </ul>
+ * </ul>
+ * 
+ * <!-- END SNIPPET: profilingAspect_struts2 -->
+ *
+ *
+ * <!-- START SNIPPET: profilingAspect_xwork -->
+ * 
+ * XWork2 profiling aspects involves the following :-
+ * <ul>
+ *   <ul>
+ *      <li>creation of DefaultActionProxy</li>
+ *      <ul>
+ *         <li>creation of DefaultActionInvocation</li>
+ *         <ul>
+ *   	      <li>creation of Action</li>
+ *        </ul>
+ *      </ul>
+ *      <li>execution of DefaultActionProxy</li>
+ *      <ul>
+ *         <li>invocation of DefaultActionInvocation</li>
+ *         <ul>
+ *           <li>invocation of Interceptors</li>
+ *           <li>invocation of Action</li>
+ *           <li>invocation of PreResultListener</li>
+ *           <li>invocation of Result</li>
+ *        </ul>
+ *     </ul>
+ *   </ul>
+ * </ul>
+ * 
+ * <!-- END SNIPPET: profilingAspect_xwork -->
+ * 
+ * 
+ * <!-- START SNIPPET: activationDescription -->
+ * 
+ * Activating / Deactivating of the profiling feature could be done through:- 
+ * 
+ * <!-- END SNIPPET: activationDescription -->
+ * 
+ * <p/>
+ * 
+ * System properties:- <p/>
+ * <pre>
+ * <!-- START SNIPPET: activationThroughSystemProperty -->
+ * 
+ *  -Dxwork.profile.activate=true
+ *  
+ * <!-- END SNIPPET: activationThroughSystemProperty --> 
+ * </pre>
+ * 
+ * <!-- START SNIPPET: activationThroughSystemPropertyDescription -->
+ * 
+ * This could be done in the container startup script eg. CATALINA_OPTS in catalina.sh 
+ * (tomcat) or using "java -Dxwork.profile.activate=true -jar start.jar" (jetty) 
+ * 
+ * <!-- END SNIPPET: activationThroughSystemPropertyDescription -->
+ * 
+ * <p/>
+ * Code :- <p/>
+ * <pre>
+ * <!-- START SNIPPET: activationThroughCode -->
+ *   
+ *  UtilTimerStack.setActivate(true);
+ *    
+ * <!-- END SNIPPET: activationThroughCode --> 
+ * </pre>
+ * 
+ * 
+ * 
+ * <!-- START SNIPPET: activationThroughCodeDescription -->
+ * 
+ * This could be done in a static block, in a Spring bean with lazy-init="false", 
+ * in a Servlet with init-on-startup as some numeric value, in a Filter or 
+ * Listener's init method etc.
+ * 
+ * <!-- END SNIPPET: activationThroughCodeDescription -->
+ * 
+ * <p/>
+ * Parameter:- 
+ * 
+ * <pre>
+ * <!-- START SNIPPET: activationThroughParameter -->
+ * 
+ * &lt;action ... &gt;  
+ *  ...
+ *  &lt;interceptor-ref name="profiling"&gt;
+ *      &lt;param name="profilingKey"&gt;profiling&lt;/param&gt;
+ *  &lt;/interceptor-ref&gt;
+ *  ...
+ * &lt;/action&gt;
+ * 
+ * or 
+ * 
+ * &lt;action .... &gt;
+ * ...
+ *  &lt;interceptor-ref name="profiling" /&gt;
+ * ...
+ * &lt;/action&gt;
+ * 
+ * through url
+ * 
+ * http://host:port/context/namespace/someAction.action?profiling=true
+ * 
+ * through code
+ * 
+ * ActionContext.getContext().getParameters().put("profiling", "true);
+ * 
+ * <!-- END SNIPPET: activationThroughParameter -->
+ * </pre>
+ * 
+ * 
+ * <!-- START SNIPPET: activationThroughParameterDescription -->
+ * 
+ * To use profiling activation through parameter, one will need to pass in through 
+ * the 'profiling' parameter (which is the default) and could be changed through 
+ * the param tag in the interceptor-ref. 
+ * 
+ * <!-- END SNIPPET: activationThroughParameterDescription -->
+ * 
+ * <p/>
+ * Warning:<p/>
+ * <!-- START SNIPPET: activationThroughParameterWarning -->
+ * 
+ * Profiling activation through a parameter requires the following:
+ *
+ * <ul>
+ *  <li>Profiling interceptor in interceptor stack</li>
+ *  <li>dev mode on (struts.devMode=true in struts.properties)
+ * </ul>
+ * 
+ * <!-- END SNIPPET: activationThroughParameterWarning -->
+ * 
+ * <p/>
+ * 
+ * <!-- START SNIPPET: filteringDescription -->
+ * 
+ * One could filter out the profile logging by having a System property as follows. With this
+ * 'xwork.profile.mintime' property, one could only log profile information when its execution time 
+ * exceed those specified in 'xwork.profile.mintime' system property. If no such property is specified, 
+ * it will be assumed to be 0, hence all profile information will be logged.
+ * 
+ * <!-- END SNIPPET: filteringDescription -->
+ * 
+ * <pre>
+ * <!-- START SNIPPET: filteringCode -->
+ * 
+ *  -Dxwork.profile.mintime=10000
+ * 
+ * <!-- END SNIPPET: filteringCode -->
+ * </pre>
+ * 
+ * <!-- START SNIPPET: methodDescription -->
+ * 
+ * One could extend the profiling feature provided by Struts2 in their web application as well. 
+ * 
+ * <!-- END SNIPPET: methodDescription -->
+ * 
+ * <pre>
+ * <!-- START SNIPPET: method1 -->
+ * 
+ *    String logMessage = "Log message";
+ *    UtilTimerStack.push(logMessage);
+ *    try {
+ *        // do some code
+ *    }
+ *    finally {
+ *        UtilTimerStack.pop(logMessage); // this needs to be the same text as above
+ *    }
+ *    
+ * <!-- END SNIPPET: method1 -->   
+ * </pre>
+ * 
+ * or 
+ * 
+ * <pre>
+ * <!-- START SNIPPET: method2 -->
+ * 
+ *   String result = UtilTimerStack.profile("purchaseItem: ", 
+ *       new UtilTimerStack.ProfilingBlock<String>() {
+ *            public String doProfiling() {
+ *               // do some code
+ *               return "Ok";
+ *            }
+ *       });
+ *       
+ * <!-- END SNIPPET: method2 -->      
+ * </pre>
+ * 
+ * 
+ * <!-- START SNIPPET: profileLogFile -->
+ * 
+ * Profiled result is logged using commons-logging under the logger named 
+ * 'org.apache.struts2.xwork2.util.profiling.UtilTimerStack'. Depending on the underlying logging implementation
+ * say if it is Log4j, one could direct the log to appear in a different file, being emailed to someone or have 
+ * it stored in the db.
+ * 
+ * <!-- END SNIPPET: profileLogFile -->
+ * 
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: UtilTimerStack.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class UtilTimerStack
+{
+
+    // A reference to the current ProfilingTimerBean
+    protected static ThreadLocal<ProfilingTimerBean> current = new ThreadLocal<ProfilingTimerBean>();
+
+    /**
+     * System property that controls whether this timer should be used or not.  Set to "true" activates
+     * the timer.  Set to "false" to disactivate.
+     */
+    public static final String ACTIVATE_PROPERTY = "xwork.profile.activate";
+
+    /**
+     * System property that controls the min time, that if exceeded will cause a log (at INFO level) to be
+     * created.
+     */
+    public static final String MIN_TIME = "xwork.profile.mintime";
+    
+    private static final Logger LOG = LoggerFactory.getLogger(UtilTimerStack.class);
+
+    /**
+     * Initialized in a static block, it can be changed at runtime by calling setActive(...)
+     */
+    private static boolean active;
+
+    static {
+        active = "true".equalsIgnoreCase(System.getProperty(ACTIVATE_PROPERTY));
+    }
+
+    /**
+     * Create and start a performance profiling with the <code>name</code> given. Deal with 
+     * profile hierarchy automatically, so caller don't have to be concern about it.
+     * 
+     * @param name profile name
+     */
+    public static void push(String name)
+    {
+        if (!isActive())
+            return;
+
+        //create a new timer and start it
+        ProfilingTimerBean newTimer = new ProfilingTimerBean(name);
+        newTimer.setStartTime();
+
+        //if there is a current timer - add the new timer as a child of it
+        ProfilingTimerBean currentTimer = (ProfilingTimerBean) current.get();
+        if (currentTimer != null)
+        {
+            currentTimer.addChild(newTimer);
+        }
+
+        //set the new timer to be the current timer
+        current.set(newTimer);
+    }
+
+    /**
+     * End a preformance profiling with the <code>name</code> given. Deal with
+     * profile hierarchy automatically, so caller don't have to be concern about it.
+     * 
+     * @param name profile name
+     */
+    public static void pop(String name)
+    {
+        if (!isActive())
+            return;
+
+        ProfilingTimerBean currentTimer = (ProfilingTimerBean) current.get();
+
+        //if the timers are matched up with each other (ie push("a"); pop("a"));
+        if (currentTimer != null && name != null && name.equals(currentTimer.getResource()))
+        {
+            currentTimer.setEndTime();
+            ProfilingTimerBean parent = currentTimer.getParent();
+            //if we are the root timer, then print out the times
+            if (parent == null)
+            {
+                printTimes(currentTimer);
+                current.set(null); //for those servers that use thread pooling
+            }
+            else
+            {
+                current.set(parent);
+            }
+        }
+        else
+        {
+            //if timers are not matched up, then print what we have, and then print warning.
+            if (currentTimer != null)
+            {
+                printTimes(currentTimer);
+                current.set(null); //prevent printing multiple times
+                if (LOG.isWarnEnabled()) {
+                    LOG.warn("Unmatched Timer.  Was expecting " + currentTimer.getResource() + ", instead got " + name);
+                }
+            }
+        }
+
+
+    }
+
+    /**
+     * Do a log (at INFO level) of the time taken for this particular profiling.
+     * 
+     * @param currentTimer profiling timer bean
+     */
+    private static void printTimes(ProfilingTimerBean currentTimer)
+    {
+        if (LOG.isInfoEnabled()) {
+            LOG.info(currentTimer.getPrintable(getMinTime()));
+        }
+    }
+
+    /**
+     * Get the min time for this profiling, it searches for a System property
+     * 'xwork.profile.mintime' and default to 0.
+     * 
+     * @return long
+     */
+    private static long getMinTime()
+    {
+        try
+        {
+            return Long.parseLong(System.getProperty(MIN_TIME, "0"));
+        }
+        catch (NumberFormatException e)
+        {
+           return -1;
+        }
+    }
+
+    /**
+     * Determine if profiling is being activated, by searching for a system property
+     * 'xwork.profile.activate', default to false (profiling is off).
+     * 
+     * @return <tt>true</tt>, if active, <tt>false</tt> otherwise.
+     */
+    public static boolean isActive()
+    {
+        return active;
+    }
+
+    /**
+     * Turn profiling on or off.
+     * 
+     * @param active
+     */
+    public static void setActive(boolean active)
+    {
+        if (active)
+            System.setProperty(ACTIVATE_PROPERTY, "true");
+        else
+        	System.clearProperty(ACTIVATE_PROPERTY);
+
+        UtilTimerStack.active = active; 
+    }
+
+
+    /**
+     * A convenience method that allows <code>block</code> of code subjected to profiling to be executed 
+     * and avoid the need of coding boiler code that does pushing (UtilTimeBean.push(...)) and 
+     * poping (UtilTimerBean.pop(...)) in a try ... finally ... block.
+     * 
+     * <p/>
+     * 
+     * Example of usage:
+     * <pre>
+     * 	 // we need a returning result
+     *   String result = UtilTimerStack.profile("purchaseItem: ", 
+     *       new UtilTimerStack.ProfilingBlock<String>() {
+     *            public String doProfiling() {
+     *               getMyService().purchaseItem(....)
+     *               return "Ok";
+     *            }
+     *       });
+     * </pre>
+     * or
+     * <pre>
+     *   // we don't need a returning result
+     *   UtilTimerStack.profile("purchaseItem: ", 
+     *       new UtilTimerStack.ProfilingBlock<String>() {
+     *            public String doProfiling() {
+     *               getMyService().purchaseItem(....)
+     *               return null;
+     *            }
+     *       });
+     * </pre>
+     * 
+     * @param <T> any return value if there's one.
+     * @param name profile name
+     * @param block code block subjected to profiling
+     * @return T
+     * @throws Exception
+     */
+    public static <T> T profile(String name, ProfilingBlock<T> block) throws Exception {
+    	UtilTimerStack.push(name);
+    	try {
+    		return block.doProfiling();
+    	}
+    	finally {
+    		UtilTimerStack.pop(name);
+    	}
+    }
+    
+    /**
+     * A callback interface where code subjected to profile is to be executed. This eliminates the need
+     * of coding boiler code that does pushing (UtilTimerBean.push(...)) and poping (UtilTimerBean.pop(...))
+     * in a try ... finally ... block.
+     * 
+     * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: UtilTimerStack.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+     * 
+     * @param <T>
+     */
+    public static interface ProfilingBlock<T> {
+    	
+    	/**
+    	 * Method that execute the code subjected to profiling.
+    	 * 
+    	 * @return  profiles Type
+    	 * @throws Exception
+    	 */
+    	T doProfiling() throws Exception;
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/package.html?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/package.html (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/profiling/package.html Fri Dec  2 16:33:03 2011
@@ -0,0 +1 @@
+<body>Classes to enable profiling of action execution.</body>

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextFactory.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,15 @@
+package org.apache.struts2.xwork2.util.reflection;
+
+import java.util.Map;
+
+public interface ReflectionContextFactory {
+    /**
+     * Creates and returns a new standard naming context for evaluating an OGNL
+     * expression.
+     *
+     * @param root the root of the object graph
+     * @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
+     *         set appropriately
+     */
+    Map createDefaultContext( Object root );
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextState.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextState.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextState.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionContextState.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2002-2006,2009 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.struts2.xwork2.util.reflection;
+
+import org.apache.struts2.xwork2.conversion.impl.XWorkConverter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Manages variables in the reflection context and returns values
+ * to be used by the application.
+ *
+ * @author Gabe
+ */
+public class ReflectionContextState {
+
+    public static final String CURRENT_PROPERTY_PATH="current.property.path";
+    public static final String FULL_PROPERTY_PATH="current.property.path";
+    private static final String GETTING_BY_KEY_PROPERTY="xwork.getting.by.key.property";
+
+    private static final String SET_MAP_KEY="set.map.key";
+
+    public static boolean isCreatingNullObjects(Map<String, Object> context) {
+		//TODO
+		return getBooleanProperty(ReflectionContextState.CREATE_NULL_OBJECTS, context);
+	}
+
+	public static void setCreatingNullObjects(Map<String, Object> context, boolean creatingNullObjects) {
+		setBooleanValue(ReflectionContextState.CREATE_NULL_OBJECTS, context, creatingNullObjects);
+	}
+
+	public static boolean isGettingByKeyProperty(Map<String, Object> context) {
+		return getBooleanProperty(GETTING_BY_KEY_PROPERTY, context);
+	}
+	
+	public static void setDenyMethodExecution(Map<String, Object> context, boolean denyMethodExecution) {
+		setBooleanValue(ReflectionContextState.DENY_METHOD_EXECUTION, context, denyMethodExecution);
+	}
+	
+	public static boolean isDenyMethodExecution(Map<String, Object> context) {
+		return getBooleanProperty(ReflectionContextState.DENY_METHOD_EXECUTION, context);
+	}
+
+	public static void setGettingByKeyProperty(Map<String, Object> context, boolean gettingByKeyProperty) {
+		setBooleanValue(GETTING_BY_KEY_PROPERTY, context, gettingByKeyProperty);
+	}	
+	
+	public static boolean isReportingConversionErrors(Map<String, Object> context) {
+		return getBooleanProperty(XWorkConverter.REPORT_CONVERSION_ERRORS, context);
+	}
+
+	public static void setReportingConversionErrors(Map<String, Object> context, boolean reportingErrors) {
+		setBooleanValue(XWorkConverter.REPORT_CONVERSION_ERRORS, context, reportingErrors);
+	}
+
+	public static Class getLastBeanClassAccessed(Map<String, Object> context) {
+		return (Class)context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED);
+	}
+
+	public static void setLastBeanPropertyAccessed(Map<String, Object> context, String property) {
+		context.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED, property);
+	}
+
+	public static String getLastBeanPropertyAccessed(Map<String, Object> context) {
+		return (String)context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED);
+	}
+
+	public static void setLastBeanClassAccessed(Map<String, Object> context, Class clazz) {
+		context.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED, clazz);
+	}
+	/**
+	 * Gets the current property path but not completely.
+	 * It does not use the [ and ] used in some representations
+	 * of Maps and Lists. The reason for this is that the current
+	 * property path is only currently used for caching purposes
+	 * so there is no real reason to have an exact replica.
+     *
+	 * <p/>So if the real path is myProp.myMap['myKey'] this would
+	 * return myProp.myMap.myKey.
+     * 
+	 * @param context
+	 */
+	public static String getCurrentPropertyPath(Map<String, Object> context) {
+		return (String)context.get(CURRENT_PROPERTY_PATH);
+	}
+
+	public static String getFullPropertyPath(Map<String, Object> context) {
+		return (String)context.get(FULL_PROPERTY_PATH);
+	}
+
+	public static void setFullPropertyPath(Map<String, Object> context, String path) {
+		context.put(FULL_PROPERTY_PATH, path);
+
+	}
+
+	public static void updateCurrentPropertyPath(Map<String, Object> context, Object name) {
+		String currentPath=getCurrentPropertyPath(context);
+		if (name!=null) {
+			if (currentPath!=null) {
+                StringBuilder sb = new StringBuilder(currentPath);
+                sb.append(".");
+                sb.append(name.toString());
+				currentPath = sb.toString();
+			}	else {
+				currentPath = name.toString();
+			}
+			context.put(CURRENT_PROPERTY_PATH, currentPath);
+		}
+	}
+
+	public static void setSetMap(Map<String, Object> context, Map<Object, Object> setMap, String path) {
+		Map<Object, Map<Object, Object>> mapOfSetMaps=(Map)context.get(SET_MAP_KEY);
+		if (mapOfSetMaps==null) {
+			mapOfSetMaps=new HashMap<Object, Map<Object, Object>>();
+			context.put(SET_MAP_KEY, mapOfSetMaps);
+		}
+		mapOfSetMaps.put(path, setMap);
+	}
+
+	public static Map<Object, Object> getSetMap(Map<String, Object> context, String path) {
+		Map<Object, Map<Object, Object>> mapOfSetMaps=(Map)context.get(SET_MAP_KEY);
+		if (mapOfSetMaps==null) {
+			return null;
+		}
+		return mapOfSetMaps.get(path);
+	}
+
+	private static boolean getBooleanProperty(String property, Map<String, Object> context) {
+		Boolean myBool=(Boolean)context.get(property);
+		return (myBool==null)?false:myBool.booleanValue();
+	}
+
+	private static void setBooleanValue(String property, Map<String, Object> context, boolean value) {
+		context.put(property, new Boolean(value));
+	}
+
+	/**
+	 *
+	 */
+	public static void clearCurrentPropertyPath(Map<String, Object> context) {
+		context.put(CURRENT_PROPERTY_PATH, null);
+
+	}
+
+
+    public static void clear(Map<String, Object> context) {
+        if (context != null) {
+            context.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED,null);
+            context.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED,null);
+    
+            context.put(CURRENT_PROPERTY_PATH,null);
+            context.put(FULL_PROPERTY_PATH,null);
+        }
+
+    }
+
+
+    public static final String CREATE_NULL_OBJECTS = "xwork.NullHandler.createNullObjects";
+    public static final String DENY_METHOD_EXECUTION = "xwork.MethodAccessor.denyMethodExecution";
+    public static final String DENY_INDEXED_ACCESS_EXECUTION = "xwork.IndexedPropertyAccessor.denyMethodExecution";
+
+
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionException.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionException.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionException.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionException.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,41 @@
+package org.apache.struts2.xwork2.util.reflection;
+
+import org.apache.struts2.xwork2.XWorkException;
+
+public class ReflectionException extends XWorkException {
+
+    public ReflectionException() {
+        // TODO Auto-generated constructor stub
+    }
+
+    public ReflectionException(String s) {
+        super(s);
+        // TODO Auto-generated constructor stub
+    }
+
+    public ReflectionException(String s, Object target) {
+        super(s, target);
+        // TODO Auto-generated constructor stub
+    }
+
+    public ReflectionException(Throwable cause) {
+        super(cause);
+        // TODO Auto-generated constructor stub
+    }
+
+    public ReflectionException(Throwable cause, Object target) {
+        super(cause, target);
+        // TODO Auto-generated constructor stub
+    }
+
+    public ReflectionException(String s, Throwable cause) {
+        super(s, cause);
+        // TODO Auto-generated constructor stub
+    }
+
+    public ReflectionException(String s, Throwable cause, Object target) {
+        super(s, cause, target);
+        // TODO Auto-generated constructor stub
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionExceptionHandler.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionExceptionHandler.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionExceptionHandler.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionExceptionHandler.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,14 @@
+package org.apache.struts2.xwork2.util.reflection;
+
+/**
+ * Declares a class that wants to handle its own reflection exceptions
+ */
+public interface ReflectionExceptionHandler {
+
+    /**
+     * Handles a reflection exception
+     * 
+     * @param ex The reflection exception
+     */
+    void handle(ReflectionException ex);
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProvider.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProvider.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProvider.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,141 @@
+package org.apache.struts2.xwork2.util.reflection;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Map;
+
+public interface ReflectionProvider {
+    
+    Method getGetMethod(Class targetClass, String propertyName) throws IntrospectionException, ReflectionException;
+    
+    Method getSetMethod(Class targetClass, String propertyName) throws IntrospectionException, ReflectionException;
+    
+    Field getField(Class inClass, String name);
+    
+    /**
+     * Sets the object's properties using the default type converter, defaulting to not throw
+     * exceptions for problems setting the properties.
+     *
+     * @param props   the properties being set
+     * @param o       the object
+     * @param context the action context
+     */
+    void setProperties(Map<String, String> props, Object o, Map<String, Object> context);
+
+    /**
+     * Sets the object's properties using the default type converter.
+     *
+     * @param props                   the properties being set
+     * @param o                       the object
+     * @param context                 the action context
+     * @param throwPropertyExceptions boolean which tells whether it should throw exceptions for
+     *                                problems setting the properties
+     */
+    void setProperties(Map<String, String> props, Object o, Map<String, Object> context, boolean throwPropertyExceptions) throws ReflectionException;
+    
+    /**
+     * Sets the properties on the object using the default context, defaulting to not throwing
+     * exceptions for problems setting the properties.
+     *
+     * @param properties
+     * @param o
+     */
+    void setProperties(Map<String, String> properties, Object o);
+    
+    /**
+     *  This method returns a PropertyDescriptor for the given class and property name using
+     * a Map lookup (using getPropertyDescriptorsMap()).
+     */
+    PropertyDescriptor getPropertyDescriptor(Class targetClass, String propertyName) throws IntrospectionException, ReflectionException;
+
+    /**
+     * Copies the properties in the object "from" and sets them in the object "to"
+     * using specified type converter, or {@link org.apache.struts2.xwork2.conversion.impl.XWorkConverter} if none
+     * is specified.
+     *
+     * @param from       the source object
+     * @param to         the target object
+     * @param context    the action context we're running under
+     * @param exclusions collection of method names to excluded from copying ( can be null)
+     * @param inclusions collection of method names to included copying  (can be null)
+     *                   note if exclusions AND inclusions are supplied and not null nothing will get copied.
+     */
+    void copy(Object from, Object to, Map<String, Object> context, Collection<String> exclusions, Collection<String> inclusions);
+    
+    /**
+     * Looks for the real target with the specified property given a root Object which may be a
+     * CompoundRoot.
+     *
+     * @return the real target or null if no object can be found with the specified property
+     */
+    Object getRealTarget(String property, Map<String, Object> context, Object root) throws ReflectionException;
+    
+    /**
+     * Sets the named property to the supplied value on the Object,
+     *
+     * @param name    the name of the property to be set
+     * @param value   the value to set into the named property
+     * @param o       the object upon which to set the property
+     * @param context the context which may include the TypeConverter
+     * @param throwPropertyExceptions boolean which tells whether it should throw exceptions for
+     *                                problems setting the properties
+     */
+    void setProperty(String name, Object value, Object o, Map<String, Object> context, boolean throwPropertyExceptions);
+
+    /**
+     * Sets the named property to the supplied value on the Object, defaults to not throwing
+     * property exceptions.
+     *
+     * @param name    the name of the property to be set
+     * @param value   the value to set into the named property
+     * @param o       the object upon which to set the property
+     * @param context the context which may include the TypeConverter
+     */
+    void setProperty(String name, Object value, Object o, Map<String, Object> context);
+    
+    /**
+     * Creates a Map with read properties for the given source object.
+     * <p/>
+     * If the source object does not have a read property (i.e. write-only) then
+     * the property is added to the map with the value <code>here is no read method for property-name</code>.
+     * 
+     * @param source   the source object.
+     * @return  a Map with (key = read property name, value = value of read property).
+     * @throws IntrospectionException is thrown if an exception occurs during introspection.
+     */
+    Map<String, Object> getBeanMap(Object source) throws IntrospectionException, ReflectionException;
+    
+    /**
+     * Evaluates the given OGNL expression to extract a value from the given root
+     * object in a given context
+     *
+     * @param expression the OGNL expression to be parsed
+     * @param context the naming context for the evaluation
+     * @param root the root object for the OGNL expression
+     * @return the result of evaluating the expression
+     */
+    Object getValue( String expression, Map<String, Object> context, Object root ) throws ReflectionException;
+    
+    /**
+     * Evaluates the given OGNL expression to insert a value into the object graph
+     * rooted at the given root object given the context.
+     *
+     * @param expression the OGNL expression to be parsed
+     * @param root the root object for the OGNL expression
+     * @param context the naming context for the evaluation
+     * @param value the value to insert into the object graph
+     */
+    void setValue( String expression, Map<String, Object> context, Object root, Object value ) throws ReflectionException;
+    
+    /**
+     * Get's the java beans property descriptors for the given source.
+     * 
+     * @param source  the source object.
+     * @return  property descriptors.
+     * @throws IntrospectionException is thrown if an exception occurs during introspection.
+     */
+    PropertyDescriptor[] getPropertyDescriptors(Object source) throws IntrospectionException;
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProviderFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProviderFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProviderFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/util/reflection/ReflectionProviderFactory.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,10 @@
+package org.apache.struts2.xwork2.util.reflection;
+
+import org.apache.struts2.xwork2.ActionContext;
+
+public class ReflectionProviderFactory {
+
+    public static ReflectionProvider getInstance() {
+        return ActionContext.getContext().getContainer().getInstance(ReflectionProvider.class);
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ActionValidatorManager.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ActionValidatorManager.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ActionValidatorManager.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ActionValidatorManager.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2002-2007,2009 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.struts2.xwork2.validator;
+
+import java.util.List;
+
+/**
+ * ActionValidatorManager is the main interface for validation managers (regular and annotation based).
+ *
+ * @author Rainer Hermanns
+ */
+public interface ActionValidatorManager {
+
+    /**
+     * Returns a list of validators for the given class, context, and method. This is the primary
+     * lookup method for validators.
+     *
+     * @param clazz the class to lookup.
+     * @param context the context of the action class - can be <tt>null</tt>.
+     * @param method the name of the method being invoked on the action - can be <tt>null</tt>.
+     * @return a list of all validators for the given class and context.
+     */
+    List<Validator> getValidators(Class clazz, String context, String method);
+
+    /**
+     * Returns a list of validators for the given class and context. This is the primary
+     * lookup method for validators.
+     *
+     * @param clazz the class to lookup.
+     * @param context the context of the action class - can be <tt>null</tt>.
+     * @return a list of all validators for the given class and context.
+     */
+    List<Validator> getValidators(Class clazz, String context);
+
+    /**
+     * Validates the given object using action and its context.
+     *
+     * @param object the action to validate.
+     * @param context the action's context.
+     * @throws ValidationException if an error happens when validating the action.
+     */
+    void validate(Object object, String context) throws ValidationException;
+
+    /**
+     * Validates an action give its context and a validation context.
+     *
+     * @param object the action to validate.
+     * @param context the action's context.
+     * @param validatorContext the validation context to use
+     * @throws ValidationException if an error happens when validating the action.
+     */
+    void validate(Object object, String context, ValidatorContext validatorContext) throws ValidationException;
+
+    /**
+     * Validates the given object using an action, its context, and the name of the method being invoked on the action.
+     *
+     * @param object the action to validate.
+     * @param context the action's context.
+     * @param method the name of the method being invoked on the action - can be <tt>null</tt>.
+     * @throws ValidationException if an error happens when validating the action.
+     */
+    void validate(Object object, String context, String method) throws ValidationException;
+
+    /**
+     * Validates an action give its context and a validation context.
+     *
+     * @param object the action to validate.
+     * @param context the action's context.
+     * @param validatorContext the validation context to use
+     * @param method the name of the method being invoked on the action - can be <tt>null</tt>.
+     * @throws ValidationException if an error happens when validating the action.
+     */
+    void validate(Object object, String context, ValidatorContext validatorContext, String method) throws ValidationException;
+}