Merge pull request #224 from sdutry/WW-4779

WW-4779 Remove profiling layer
This commit is contained in:
Aleksandr Mashchenko
2018-05-22 23:46:28 +03:00
committed by GitHub
32 changed files with 130 additions and 1803 deletions
@@ -30,7 +30,6 @@ import com.opensymphony.xwork2.interceptor.WithLazyParams;
import com.opensymphony.xwork2.ognl.OgnlUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
import ognl.MethodFailedException;
import ognl.NoSuchPropertyException;
import org.apache.logging.log4j.LogManager;
@@ -237,76 +236,57 @@ public class DefaultActionInvocation implements ActionInvocation {
* @throws ConfigurationException If no result can be found with the returned code
*/
public String invoke() throws Exception {
String profileKey = "invoke: ";
try {
UtilTimerStack.push(profileKey);
if (executed) {
throw new IllegalStateException("Action has already executed");
}
if (asyncManager == null || !asyncManager.hasAsyncActionResult()) {
if (interceptors.hasNext()) {
final InterceptorMapping interceptorMapping = interceptors.next();
String interceptorMsg = "interceptorMapping: " + interceptorMapping.getName();
UtilTimerStack.push(interceptorMsg);
try {
Interceptor interceptor = interceptorMapping.getInterceptor();
if (interceptor instanceof WithLazyParams) {
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
}
resultCode = interceptor.intercept(DefaultActionInvocation.this);
} finally {
UtilTimerStack.pop(interceptorMsg);
}
} else {
resultCode = invokeActionOnly();
}
} else {
Object asyncActionResult = asyncManager.getAsyncActionResult();
if (asyncActionResult instanceof Throwable) {
throw new Exception((Throwable) asyncActionResult);
}
asyncAction = null;
resultCode = saveResult(proxy.getConfig(), asyncActionResult);
}
if (asyncManager == null || asyncAction == null) {
// this is needed because the result will be executed, then control will return to the Interceptor, which will
// return above and flow through again
if (!executed) {
if (preResultListeners != null) {
LOG.trace("Executing PreResultListeners for result [{}]", result);
for (Object preResultListener : preResultListeners) {
PreResultListener listener = (PreResultListener) preResultListener;
String _profileKey = "preResultListener: ";
try {
UtilTimerStack.push(_profileKey);
listener.beforeResult(this, resultCode);
} finally {
UtilTimerStack.pop(_profileKey);
}
}
}
// now execute the result, if we're supposed to
if (proxy.getExecuteResult()) {
executeResult();
}
executed = true;
}
} else {
asyncManager.invokeAsyncAction(asyncAction);
}
return resultCode;
if (executed) {
throw new IllegalStateException("Action has already executed");
}
finally {
UtilTimerStack.pop(profileKey);
if (asyncManager == null || !asyncManager.hasAsyncActionResult()) {
if (interceptors.hasNext()) {
final InterceptorMapping interceptorMapping = interceptors.next();
String interceptorMsg = "interceptorMapping: " + interceptorMapping.getName();
Interceptor interceptor = interceptorMapping.getInterceptor();
if (interceptor instanceof WithLazyParams) {
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
}
resultCode = interceptor.intercept(DefaultActionInvocation.this);
} else {
resultCode = invokeActionOnly();
}
} else {
Object asyncActionResult = asyncManager.getAsyncActionResult();
if (asyncActionResult instanceof Throwable) {
throw new Exception((Throwable) asyncActionResult);
}
asyncAction = null;
resultCode = saveResult(proxy.getConfig(), asyncActionResult);
}
if (asyncManager == null || asyncAction == null) {
// this is needed because the result will be executed, then control will return to the Interceptor, which will
// return above and flow through again
if (!executed) {
if (preResultListeners != null) {
LOG.trace("Executing PreResultListeners for result [{}]", result);
for (Object preResultListener : preResultListeners) {
PreResultListener listener = (PreResultListener) preResultListener;
listener.beforeResult(this, resultCode);
}
}
// now execute the result, if we're supposed to
if (proxy.getExecuteResult()) {
executeResult();
}
executed = true;
}
} else {
asyncManager.invokeAsyncAction(asyncAction);
}
return resultCode;
}
public String invokeActionOnly() throws Exception {
@@ -317,7 +297,6 @@ public class DefaultActionInvocation implements ActionInvocation {
// load action
String timerKey = "actionCreate: " + proxy.getActionName();
try {
UtilTimerStack.push(timerKey);
action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
} catch (InstantiationException e) {
throw new XWorkException("Unable to instantiate Action!", e, proxy.getConfig());
@@ -338,8 +317,6 @@ public class DefaultActionInvocation implements ActionInvocation {
gripe += (((" -- " + e.getMessage()) != null) ? e.getMessage() : " [no message in exception]");
throw new XWorkException(gripe, e, proxy.getConfig());
} finally {
UtilTimerStack.pop(timerKey);
}
if (actionEventListener != null) {
@@ -389,20 +366,15 @@ public class DefaultActionInvocation implements ActionInvocation {
result = createResult();
String timerKey = "executeResult: " + getResultCode();
try {
UtilTimerStack.push(timerKey);
if (result != null) {
result.execute(this);
} else if (resultCode != null && !Action.NONE.equals(resultCode)) {
throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
+ " and result " + getResultCode(), proxy.getConfig());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("No result returned for action {} at {}", getAction().getClass().getName(), proxy.getConfig().getLocation());
}
if (result != null) {
result.execute(this);
} else if (resultCode != null && !Action.NONE.equals(resultCode)) {
throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
+ " and result " + getResultCode(), proxy.getConfig());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("No result returned for action {} at {}", getAction().getClass().getName(), proxy.getConfig().getLocation());
}
} finally {
UtilTimerStack.pop(timerKey);
}
}
@@ -451,8 +423,6 @@ public class DefaultActionInvocation implements ActionInvocation {
String timerKey = "invokeAction: " + proxy.getActionName();
try {
UtilTimerStack.push(timerKey);
Object methodResult;
try {
methodResult = ognlUtil.callMethod(methodName + "()", getStack().getContext(), action);
@@ -497,8 +467,6 @@ public class DefaultActionInvocation implements ActionInvocation {
} else {
throw e;
}
} finally {
UtilTimerStack.pop(timerKey);
}
}
@@ -22,7 +22,6 @@ import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
@@ -150,16 +149,12 @@ public class DefaultActionProxy implements ActionProxy, Serializable {
String retCode = null;
String profileKey = "execute: ";
try {
UtilTimerStack.push(profileKey);
retCode = invocation.invoke();
} finally {
if (cleanupContext) {
ActionContext.setContext(nestedContext);
}
UtilTimerStack.pop(profileKey);
}
return retCode;
@@ -183,27 +178,21 @@ public class DefaultActionProxy implements ActionProxy, Serializable {
}
protected void prepare() {
String profileKey = "create DefaultActionProxy: ";
try {
UtilTimerStack.push(profileKey);
config = configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName);
config = configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName);
if (config == null && unknownHandlerManager.hasUnknownHandlers()) {
config = unknownHandlerManager.handleUnknownAction(namespace, actionName);
}
if (config == null) {
throw new ConfigurationException(getErrorMessage());
}
if (config == null && unknownHandlerManager.hasUnknownHandlers()) {
config = unknownHandlerManager.handleUnknownAction(namespace, actionName);
}
if (config == null) {
throw new ConfigurationException(getErrorMessage());
}
resolveMethod();
resolveMethod();
if (config.isAllowedMethod(method)) {
invocation.init(this);
} else {
throw new ConfigurationException(prepareNotAllowedErrorMessage());
}
} finally {
UtilTimerStack.pop(profileKey);
if (config.isAllowedMethod(method)) {
invocation.init(this);
} else {
throw new ConfigurationException(prepareNotAllowedErrorMessage());
}
}
@@ -1,251 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* <!-- START SNIPPET: description -->
* This interceptor logs the amount of time in milliseconds. In order for this interceptor to work properly, the
* logging framework must be set to at least the <tt>INFO</tt> level.
* This interceptor relies on the <a href="http://jakarta.apache.org/commons/logging/">Commons Logging API</a> to
* report its execution-time value.
* <!-- END SNIPPET: description -->
*
* <!-- START SNIPPET: parameters -->
*
* <ul>
*
* <li>logLevel (optional) - what log level should we use (<code>trace, debug, info, warn, error, fatal</code>)? - defaut is <code>info</code></li>
*
* <li>logCategory (optional) - If provided we would use this category (eg. <code>com.mycompany.app</code>).
* Default is to use <code>com.opensymphony.xwork2.interceptor.TimerInterceptor</code>.</li>
*
* </ul>
*
* The parameters above enables us to log all action execution times in our own logfile.
*
* <!-- END SNIPPET: parameters -->
*
* <!-- START SNIPPET: extending -->
* This interceptor can be extended to provide custom message format. Users should override the
* <code>invokeUnderTiming</code> method.
* <!-- END SNIPPET: extending -->
*
* <pre>
* <!-- START SNIPPET: example -->
* &lt;!-- records only the action's execution time --&gt;
* &lt;action name="someAction" class="com.examples.SomeAction"&gt;
* &lt;interceptor-ref name="completeStack"/&gt;
* &lt;interceptor-ref name="timer"/&gt;
* &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
* &lt;/action&gt;
*
* &lt;!-- records action's execution time as well as other interceptors--&gt;
* &lt;action name="someAction" class="com.examples.SomeAction"&gt;
* &lt;interceptor-ref name="timer"/&gt;
* &lt;interceptor-ref name="completeStack"/&gt;
* &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
* &lt;/action&gt;
* <!-- END SNIPPET: example -->
* </pre>
*
* This second example uses our own log category at debug level.
*
* <pre>
* <!-- START SNIPPET: example2 -->
* &lt;!-- records only the action's execution time --&gt;
* &lt;action name="someAction" class="com.examples.SomeAction"&gt;
* &lt;interceptor-ref name="completeStack"/&gt;
* &lt;interceptor-ref name="timer"&gt;
* &lt;param name="logLevel"&gt;debug&lt;/param&gt;
* &lt;param name="logCategory"&gt;com.mycompany.myapp.actiontime&lt;/param&gt;
* &lt;interceptor-ref/&gt;
* &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
* &lt;/action&gt;
*
* &lt;!-- records action's execution time as well as other interceptors--&gt;
* &lt;action name="someAction" class="com.examples.SomeAction"&gt;
* &lt;interceptor-ref name="timer"/&gt;
* &lt;interceptor-ref name="completeStack"/&gt;
* &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
* &lt;/action&gt;
* <!-- END SNIPPET: example2 -->
* </pre>
*
* @author Jason Carreira
* @author Claus Ibsen
*
* @deprecated will be dropped with next major release (2.6)
*/
@Deprecated
public class TimerInterceptor extends AbstractInterceptor {
private static final Logger LOG = LogManager.getLogger(TimerInterceptor.class);
protected Logger categoryLogger;
protected String logCategory;
protected String logLevel;
public String getLogCategory() {
return logCategory;
}
public void setLogCategory(String logCatgory) {
this.logCategory = logCatgory;
}
public String getLogLevel() {
return logLevel;
}
public void setLogLevel(String logLevel) {
this.logLevel = logLevel;
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
if (! shouldLog()) {
return invocation.invoke();
} else {
return invokeUnderTiming(invocation);
}
}
/**
* Is called to invoke the action invocation and time the execution time.
*
* @param invocation the action invocation.
* @return the result of the action execution.
* @throws Exception can be thrown from the action.
*/
protected String invokeUnderTiming(ActionInvocation invocation) throws Exception {
long startTime = System.currentTimeMillis();
String result = invocation.invoke();
long executionTime = System.currentTimeMillis() - startTime;
StringBuilder message = new StringBuilder(100);
message.append("Executed action [");
String namespace = invocation.getProxy().getNamespace();
if (StringUtils.isNotBlank(namespace)) {
message.append(namespace).append("/");
}
message.append(invocation.getProxy().getActionName());
message.append("!");
message.append(invocation.getProxy().getMethod());
message.append("] took ").append(executionTime).append(" ms.");
doLog(getLoggerToUse(), message.toString());
return result;
}
/**
* Determines if we should log the time.
*
* @return true to log, false to not log.
*/
protected boolean shouldLog() {
// default check first
if (logLevel == null && logCategory == null) {
return LOG.isInfoEnabled();
}
// okay user have set some parameters
return isLoggerEnabled(getLoggerToUse(), logLevel);
}
/**
* Get's the logger to use.
*
* @return the logger to use.
*/
protected Logger getLoggerToUse() {
if (logCategory != null) {
if (categoryLogger == null) {
// init category logger
categoryLogger = LogManager.getLogger(logCategory);
if (logLevel == null) {
logLevel = "info"; // use info as default if not provided
}
}
return categoryLogger;
}
return LOG;
}
/**
* Performs the actual logging.
*
* @param logger the provided logger to use.
* @param message the message to log.
*/
protected void doLog(Logger logger, String message) {
if (logLevel == null) {
logger.info(message);
return;
}
if ("debug".equalsIgnoreCase(logLevel)) {
logger.debug(message);
} else if ("info".equalsIgnoreCase(logLevel)) {
logger.info(message);
} else if ("warn".equalsIgnoreCase(logLevel)) {
logger.warn(message);
} else if ("error".equalsIgnoreCase(logLevel)) {
logger.error(message);
} else if ("fatal".equalsIgnoreCase(logLevel)) {
logger.fatal(message);
} else if ("trace".equalsIgnoreCase(logLevel)) {
logger.trace(message);
} else {
throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported");
}
}
/**
* Is the given logger enalbed at the given level?
*
* @param logger the logger.
* @param level the level to check if <code>isXXXEnabled</code>.
* @return <tt>true</tt> if enabled, <tt>false</tt> if not.
*/
private static boolean isLoggerEnabled(Logger logger, String level) {
if ("debug".equalsIgnoreCase(level)) {
return logger.isDebugEnabled();
} else if ("info".equalsIgnoreCase(level)) {
return logger.isInfoEnabled();
} else if ("warn".equalsIgnoreCase(level)) {
return logger.isWarnEnabled();
} else if ("error".equalsIgnoreCase(level)) {
return logger.isErrorEnabled();
} else if ("fatal".equalsIgnoreCase(level)) {
return logger.isFatalEnabled();
} else if ("trace".equalsIgnoreCase(level)) {
return logger.isTraceEnabled();
} else {
throw new IllegalArgumentException("LogLevel [" + level + "] is not supported");
}
}
}
@@ -1,177 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/*
* 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 com.opensymphony.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>
* @deprecated will be dropped with next major release (2.6)
*/
@Deprecated
public class ObjectProfiler {
/**
* <p>
* Given a class, and an interface that it implements, return a proxied version of the class that implements
* the interface.
* </p>
*
* <p>
* The usual use of this is to profile methods from Factory objects:
* </p>
*
* <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.
* </p>
*
* @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.
*
* @param target target method
* @param value value
* @param args arguments
*
* @return target object
*
* @throws IllegalAccessException in case of access errors
* @throws InvocationTargetException in case of invocation errors
*/
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 = 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()) {
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.
*
* @param method method
*
* @return method name, with no package information
*/
public static String getTrimmedClassName(Method method) {
String classname = method.getDeclaringClass().getName();
return classname.substring(classname.lastIndexOf('.') + 1);
}
}
/**
* @deprecated will be dropped with next major release (2.6)
*/
@Deprecated
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);
}
}
@@ -1,129 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/*
* 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 com.opensymphony.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$ $Id$
*
* @deprecated will be dropped with next major release (2.6)
*/
@Deprecated
public class ProfilingTimerBean implements java.io.Serializable {
private static final long serialVersionUID = -6180672043920208784L;
List<ProfilingTimerBean> children = new ArrayList<>();
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;
}
/**
* @param minTime minimum time
* @return 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 "";
}
}
@@ -1,492 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/*
* 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 com.opensymphony.xwork2.util.profiling;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* <p>A timer stack.</p>
* <!-- START SNIPPET: profilingAspect_struts2 -->
* <p>
* Struts2 profiling aspects involves the following:
* </p>
*
* <ul>
* <li>ActionContextCleanUp</li>
* <li>FreemarkerPageFilter</li>
* <li>DispatcherFilter
* <ul>
* <li>Dispatcher
* <ul>
* <li>creation of DefaultActionProxy
* <ul>
* <li>creation of DefaultActionInvocation
* <ul>
* <li>creation of Action</li>
* </ul>
* </li>
* </ul>
* </li>
* <li>execution of DefaultActionProxy
* <ul>
* <li>invocation of DefaultActionInvocation
* <ul>
* <li>invocation of Interceptors</li>
* <li>invocation of Action</li>
* <li>invocation of PreResultListener</li>
* <li>invocation of Result</li>
* </ul>
* </li>
* </ul>
* </li>
* </ul>
* </li>
* </ul>
* </li>
* </ul>
*
* <!-- END SNIPPET: profilingAspect_struts2 -->
*
*
* <!-- START SNIPPET: profilingAspect_xwork -->
* <p>
* XWork2 profiling aspects involves the following:
* </p>
*
* <ul>
* <li>creation of DefaultActionProxy
* <ul>
* <li>creation of DefaultActionInvocation</li>
* </ul>
* </li>
* <li>creation of Action</li>
* <li>execution of DefaultActionProxy
* <ul>
* <li>invocation of DefaultActionInvocation
* <ul>
* <li>invocation of Interceptors</li>
* <li>invocation of Action</li>
* <li>invocation of PreResultListener</li>
* <li>invocation of Result</li>
* </ul>
* </li>
* </ul>
* </li>
* </ul>
*
* <!-- END SNIPPET: profilingAspect_xwork -->
*
*
* <!-- START SNIPPET: activationDescription -->
* <p>
* Activating / Deactivating of the profiling feature could be done through:
* </p>
* <!-- END SNIPPET: activationDescription -->
*
*
*
* <p>System properties:</p>
* <pre>
* <!-- START SNIPPET: activationThroughSystemProperty -->
*
* -Dxwork.profile.activate=true
*
* <!-- END SNIPPET: activationThroughSystemProperty -->
* </pre>
*
* <!-- START SNIPPET: activationThroughSystemPropertyDescription -->
* <p>
* 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)
* </p>
* <!-- END SNIPPET: activationThroughSystemPropertyDescription -->
*
*
* <p>Code :</p>
* <pre>
* <!-- START SNIPPET: activationThroughCode -->
*
* UtilTimerStack.setActivate(true);
*
* <!-- END SNIPPET: activationThroughCode -->
* </pre>
* <!-- START SNIPPET: activationThroughCodeDescription -->
* <p>
* 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.
* </p>
* <!-- END SNIPPET: activationThroughCodeDescription -->
*
* <p>
* Parameter:
* </p>
*
* <pre>
* <!-- START SNIPPET: activationThroughParameter -->
*
* &lt;action ... &gt;
* ...
* &lt;interceptor-ref name=&quot;profiling&quot;&gt;
* &lt;param name=&quot;profilingKey&quot;&gt;profiling&lt;/param&gt;
* &lt;/interceptor-ref&gt;
* ...
* &lt;/action&gt;
*
* or
*
* &lt;action .... &gt;
* ...
* &lt;interceptor-ref name=&quot;profiling&quot; /&gt;
* ...
* &lt;/action&gt;
*
* through url
*
* http://host:port/context/namespace/someAction.action?profiling=true
*
* through code
*
* ActionContext.getContext().getParameters().put(&quot;profiling&quot;, &quot;true);
*
* <!-- END SNIPPET: activationThroughParameter -->
* </pre>
*
*
* <!-- START SNIPPET: activationThroughParameterDescription -->
* <p>
* 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.
* </p>
* <!-- END SNIPPET: activationThroughParameterDescription -->
*
* <p>Warning:</p>
*
* <!-- START SNIPPET: activationThroughParameterWarning -->
* <p>
* Profiling activation through a parameter requires the following:
* </p>
*
* <ul>
* <li>Profiling interceptor in interceptor stack</li>
* <li>dev mode on (struts.devMode=true in struts.properties)
* </ul>
*
* <!-- END SNIPPET: activationThroughParameterWarning -->
*
* <!-- START SNIPPET: filteringDescription -->
* <p>
* 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.
* </p>
*
* <!-- END SNIPPET: filteringDescription -->
*
* <pre>
* <!-- START SNIPPET: filteringCode -->
*
* -Dxwork.profile.mintime=10000
*
* <!-- END SNIPPET: filteringCode -->
* </pre>
*
* <!-- START SNIPPET: methodDescription -->
* <p>
* One could extend the profiling feature provided by Struts2 in their web application as well.
* </p>
* <!-- END SNIPPET: methodDescription -->
*
* <pre>
* <!-- START SNIPPET: method1 -->
*
* String logMessage = &quot;Log message&quot;;
* UtilTimerStack.push(logMessage);
* try {
* // do some code
* }
* finally {
* UtilTimerStack.pop(logMessage); // this needs to be the same text as above
* }
*
* <!-- END SNIPPET: method1 -->
* </pre>
* <p>
* or
* </p>
* <pre>
* <!-- START SNIPPET: method2 -->
*
* String result = UtilTimerStack.profile(&quot;purchaseItem: &quot;,
* new UtilTimerStack.ProfilingBlock&lt;String&gt;() {
* public String doProfiling() {
* // do some code
* return &quot;Ok&quot;;
* }
* });
*
* <!-- END SNIPPET: method2 -->
* </pre>
*
*
* <!-- START SNIPPET: profileLogFile -->
* <p>
* Profiled result is logged using commons-logging under the logger named
* 'com.opensymphony.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.
* </p>
*
* <!-- END SNIPPET: profileLogFile -->
*
* @deprecated will be dropped with next major release (2.6)
*/
@Deprecated
public class UtilTimerStack {
// A reference to the current ProfilingTimerBean
protected static ThreadLocal<ProfilingTimerBean> current = new ThreadLocal<>();
/**
* System property that controls whether this timer should be used or not. Set to &quot;true&quot; activates
* the timer. Set to &quot;false&quot; to deactivate.
*/
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 = LogManager.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 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 pop(String name) {
if (!isActive()) {
return;
}
ProfilingTimerBean currentTimer = 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
LOG.warn("Unmatched Timer. Was expecting {}, instead got {}", currentTimer.getResource(), 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) {
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 min time for this profiling
*/
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;
}
/**
* @param active Turn profiling on or off.
*/
public static void setActive(boolean active) {
if (active) {
System.setProperty(ACTIVATE_PROPERTY, "true");
} else {
System.clearProperty(ACTIVATE_PROPERTY);
}
UtilTimerStack.active = active;
}
/**
* <p>
* 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>
*
* <p>
* Example of usage:
* </p>
*
* <pre>
* // we need a returning result
* String result = UtilTimerStack.profile("purchaseItem: ",
* new UtilTimerStack.ProfilingBlock&lt;String&gt;() {
* public String doProfiling() {
* getMyService().purchaseItem(....)
* return "Ok";
* }
* });
* </pre>
*
* or
*
* <pre>
* // we don't need a returning result
* UtilTimerStack.profile("purchaseItem: ",
* new UtilTimerStack.ProfilingBlock&lt;String&gt;() {
* 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 in case of any errors
*/
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.
*
* @param <T> type
*/
public static interface ProfilingBlock<T> {
/**
* Method that execute the code subjected to profiling.
*
* @return profiles Type
* @throws Exception in case of any errors
*/
T doProfiling() throws Exception;
}
}
@@ -1,21 +0,0 @@
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
-->
<body>Classes to enable profiling of action execution.</body>
@@ -34,7 +34,6 @@ import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import com.opensymphony.xwork2.util.location.Location;
import com.opensymphony.xwork2.util.location.LocationUtils;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@@ -581,9 +580,7 @@ public class Dispatcher {
extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
}
String timerKey = "Handling request from Dispatcher";
try {
UtilTimerStack.push(timerKey);
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
@@ -623,8 +620,6 @@ public class Dispatcher {
} else {
throw new ServletException(e);
}
} finally {
UtilTimerStack.pop(timerKey);
}
}
@@ -1,104 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.dispatcher.Parameter;
/**
* <!-- START SNIPPET: description -->
*
* Allows profiling to be enabled or disabled via request parameters, when
* devMode is enabled.
*
* <!-- END SNIPPET: description -->
*
*
* <!-- START SNIPPET: parameters -->
*
* <ul>
* <li>profilingKey</li>
* </ul>
*
* <!-- END SNIPPET: parameters -->
*
* <!-- START SNIPPET: extending -->
*
* none
*
* <!-- END SNIPPET: extending -->
*
* <pre>
* <!-- START SNIPPET: example -->
* // to change the profiling key
* &lt;action ...&gt;
* ...
* &lt;interceptor-ref name="profiling"&gt;
* &lt;param name="profilingKey"&gt;profilingKey&lt;/param&gt;
* &lt;/interceptor-ref&gt;
* ...
* &lt;/action&gt;
* <!-- END SNIPPET: example -->
* </pre>
*
* @version $Date$ $Id$
*/
public class ProfilingActivationInterceptor extends AbstractInterceptor {
private String profilingKey = "profiling";
private boolean devMode;
/**
* @return the profilingKey
*/
public String getProfilingKey() {
return profilingKey;
}
/**
* @param profilingKey the profilingKey to set
*/
public void setProfilingKey(String profilingKey) {
this.profilingKey = profilingKey;
}
@Inject(StrutsConstants.STRUTS_DEVMODE)
public void setDevMode(String mode) {
this.devMode = BooleanUtils.toBoolean(mode);
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
if (devMode) {
Parameter val = invocation.getInvocationContext().getParameters().get(profilingKey);
if (val.isDefined()) {
String sval = val.getValue();
boolean enable = BooleanUtils.toBoolean(sval);
UtilTimerStack.setActive(enable);
invocation.getInvocationContext().getParameters().remove(profilingKey);
}
}
return invocation.invoke();
}
}
@@ -226,7 +226,6 @@
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
@@ -234,7 +233,6 @@
<interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
<interceptor name="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" />
<interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
<interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
<interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
<interceptor name="annotationParameterFilter" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationParameterFilterInterceptor" />
@@ -36,7 +36,6 @@
<interceptors>
<!-- START SNIPPET: xwork2-default-interceptors -->
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
@@ -283,7 +283,7 @@ public class ConfigurationTest extends XWorkTestCase {
assertNotNull(proxy);
proxy = actionProxyFactory.createActionProxy("multipleInheritance", "testMultipleInheritance", null, null);
assertNotNull(proxy);
assertEquals(5, proxy.getConfig().getInterceptors().size());
assertEquals(4, proxy.getConfig().getInterceptors().size());
assertEquals(2, proxy.getConfig().getResults().size());
} catch (Exception e) {
e.printStackTrace();
@@ -294,7 +294,7 @@ public class ConfigurationTest extends XWorkTestCase {
public void testPackageExtension() {
try {
ActionProxy proxy = actionProxyFactory.createActionProxy("/foo/bar", "Bar", null, null);
assertEquals(5, proxy.getConfig().getInterceptors().size());
assertEquals(4, proxy.getConfig().getInterceptors().size());
} catch (Exception e) {
e.printStackTrace();
fail();
@@ -23,9 +23,9 @@ import com.opensymphony.xwork2.SimpleAction;
import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.config.ConfigurationProvider;
import com.opensymphony.xwork2.config.entities.*;
import com.opensymphony.xwork2.interceptor.TimerInterceptor;
import com.opensymphony.xwork2.mock.MockInterceptor;
import com.opensymphony.xwork2.mock.MockResult;
import org.apache.struts2.interceptor.NoOpInterceptor;
import java.util.ArrayList;
import java.util.HashMap;
@@ -68,8 +68,8 @@ public class XmlConfigurationProviderActionsTest extends ConfigurationTestBase {
params.put("bar", "24");
results.put("success", new ResultConfig.Builder("success", MockResult.class.getName()).build());
InterceptorConfig timerInterceptorConfig = new InterceptorConfig.Builder("timer", TimerInterceptor.class.getName()).build();
interceptors.add(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptorConfig, new HashMap<String, String>())));
InterceptorConfig noopInterceptorConfig = new InterceptorConfig.Builder("noop", NoOpInterceptor.class.getName()).build();
interceptors.add(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptorConfig, new HashMap<String, String>())));
ActionConfig fooAction = new ActionConfig.Builder("", "Foo", SimpleAction.class.getName())
.addParams(params)
@@ -23,7 +23,7 @@ import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.config.ConfigurationProvider;
import com.opensymphony.xwork2.config.entities.InterceptorConfig;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.interceptor.TimerInterceptor;
import org.apache.struts2.interceptor.NoOpInterceptor;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.context.support.StaticApplicationContext;
@@ -39,13 +39,13 @@ import java.util.Map;
*/
public class XmlConfigurationProviderInterceptorsSpringTest extends ConfigurationTestBase {
InterceptorConfig timerInterceptor = new InterceptorConfig.Builder("timer", TimerInterceptor.class.getName()).build();
InterceptorConfig noopInterceptor = new InterceptorConfig.Builder("noop", NoOpInterceptor.class.getName()).build();
ObjectFactory objectFactory;
StaticApplicationContext sac;
public void testInterceptorsLoadedFromSpringApplicationContext() throws ConfigurationException {
sac.registerSingleton("timer-interceptor", TimerInterceptor.class, new MutablePropertyValues());
sac.registerSingleton("noop-interceptor", NoOpInterceptor.class, new MutablePropertyValues());
final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-interceptors-spring.xml";
@@ -64,8 +64,8 @@ public class XmlConfigurationProviderInterceptorsSpringTest extends Configuratio
assertEquals(1, interceptorConfigs.size());
// assertions for interceptors
InterceptorConfig seen = (InterceptorConfig) interceptorConfigs.get("timer");
assertEquals("timer-interceptor", seen.getClassName());
InterceptorConfig seen = (InterceptorConfig) interceptorConfigs.get("noop");
assertEquals("noop-interceptor", seen.getClassName());
}
@Override
@@ -25,8 +25,8 @@ import com.opensymphony.xwork2.config.ConfigurationProvider;
import com.opensymphony.xwork2.config.RuntimeConfiguration;
import com.opensymphony.xwork2.config.entities.*;
import com.opensymphony.xwork2.interceptor.LoggingInterceptor;
import com.opensymphony.xwork2.interceptor.TimerInterceptor;
import com.opensymphony.xwork2.mock.MockInterceptor;
import org.apache.struts2.interceptor.NoOpInterceptor;
import java.util.ArrayList;
import java.util.HashMap;
@@ -44,7 +44,7 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
InterceptorConfig loggingInterceptor = new InterceptorConfig.Builder("logging", LoggingInterceptor.class.getName()).build();
InterceptorConfig mockInterceptor = new InterceptorConfig.Builder("mock", MockInterceptor.class.getName()).build();
InterceptorConfig timerInterceptor = new InterceptorConfig.Builder("timer", TimerInterceptor.class.getName()).build();
InterceptorConfig noopInterceptor = new InterceptorConfig.Builder("noop", NoOpInterceptor.class.getName()).build();
ObjectFactory objectFactory;
@Override
@@ -68,16 +68,16 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
// the default interceptor stack
InterceptorStackConfig defaultStack = new InterceptorStackConfig.Builder("defaultStack")
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)))
.build();
// the derivative interceptor stack
InterceptorStackConfig derivativeStack = new InterceptorStackConfig.Builder("derivativeStack")
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)))
.addInterceptor(new InterceptorMapping("logging", objectFactory.buildInterceptor(loggingInterceptor, new HashMap<String, String>())))
.build();
.build();
// execute the configuration
provider.init(configuration);
@@ -90,7 +90,7 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
assertEquals(5, interceptorConfigs.size());
// assertions for interceptors
assertEquals(timerInterceptor, interceptorConfigs.get("timer"));
assertEquals(noopInterceptor, interceptorConfigs.get("noop"));
assertEquals(loggingInterceptor, interceptorConfigs.get("logging"));
assertEquals(paramsInterceptor, interceptorConfigs.get("test"));
@@ -114,13 +114,13 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
.build();
ActionConfig actionWithDefaultRef = new ActionConfig.Builder("", "ActionWithDefaultRef", SimpleAction.class.getName())
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.build();
// sub package
// this should inherit
ActionConfig actionWithNoRef = new ActionConfig.Builder("", "ActionWithNoRef", SimpleAction.class.getName())
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.build();
interceptors = new ArrayList<>();
@@ -144,7 +144,7 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
// expectations - the inherited interceptor stack
InterceptorStackConfig inheritedStack = new InterceptorStackConfig.Builder("subDefaultStack")
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.build();
ConfigurationProvider provider = buildConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-interceptor-inheritance.xml");
@@ -160,8 +160,8 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
// expectations - the inherited interceptor stack
inheritedStack = new InterceptorStackConfig.Builder("subSubDefaultStack")
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.build();
PackageConfig subSubPkg = configuration.getPackageConfig("subSubPackage");
@@ -178,7 +178,7 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
params.put("expectedFoo", "expectedFooValue");
InterceptorStackConfig defaultStack = new InterceptorStackConfig.Builder("defaultStack")
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)))
.build();
@@ -195,7 +195,7 @@ public class XmlConfigurationProviderInterceptorsTest extends ConfigurationTestB
interceptorParams.put("foo", "foo123");
InterceptorStackConfig defaultStack2 = new InterceptorStackConfig.Builder("defaultStack")
.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("noop", objectFactory.buildInterceptor(noopInterceptor, new HashMap<String, String>())))
.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, interceptorParams)))
.build();
@@ -1,163 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.SimpleFooAction;
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import com.opensymphony.xwork2.mock.MockActionProxy;
import org.apache.logging.log4j.Logger;
/**
* Unit test for {@link TimerInterceptor}.
*
* @author Claus Ibsen
*/
public class TimerInterceptorTest extends XWorkTestCase {
private MyTimerInterceptor interceptor;
private MockActionInvocation mai;
private MockActionProxy ap;
public void testTimerInterceptor() throws Exception {
TimerInterceptor real = new TimerInterceptor();
real.init();
real.intercept(mai);
real.destroy();
}
public void testInvalidLogLevel() throws Exception {
TimerInterceptor real = new TimerInterceptor();
real.setLogLevel("xxxx");
real.init();
try {
real.intercept(mai);
fail("Should not have reached this point.");
} catch (IllegalArgumentException e) {
// success
}
}
public void testDefault() throws Exception {
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
}
public void testNoNamespace() throws Exception {
ap.setNamespace(null);
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myAction!execute] took "));
}
public void testInputMethod() throws Exception {
ap.setMethod("input");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!input] took "));
}
public void testTraceLevel() throws Exception {
interceptor.setLogLevel("trace");
interceptor.intercept(mai);
assertNull(interceptor.message); // no default logging at trace level
assertEquals("trace", interceptor.getLogLevel());
}
public void testDebugLevel() throws Exception {
interceptor.setLogLevel("debug");
interceptor.intercept(mai);
assertNull(interceptor.message); // no default logging at debug level
}
public void testInfoLevel() throws Exception {
interceptor.setLogLevel("info");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
}
public void testWarnLevel() throws Exception {
interceptor.setLogLevel("warn");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
}
public void testErrorLevel() throws Exception {
interceptor.setLogLevel("error");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
}
public void testFatalLevel() throws Exception {
interceptor.setLogLevel("fatal");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
}
public void testLogCategory() throws Exception {
interceptor.setLogCategory("com.mycompany.myapp.actiontiming");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
}
public void testLogCategoryLevel() throws Exception {
interceptor.setLogCategory("com.mycompany.myapp.actiontiming");
interceptor.setLogLevel("error");
interceptor.intercept(mai);
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
assertEquals("com.mycompany.myapp.actiontiming", interceptor.getLogCategory());
}
@Override
protected void setUp() throws Exception {
super.setUp();
interceptor = new MyTimerInterceptor();
interceptor.init();
mai = new MockActionInvocation();
ap = new MockActionProxy();
ap.setActionName("myAction");
ap.setNamespace("myApp");
ap.setMethod("execute");
mai.setAction(new SimpleFooAction());
mai.setProxy(ap);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
interceptor.destroy();
ap = null;
mai = null;
}
private class MyTimerInterceptor extends TimerInterceptor {
private Logger logger;
private String message;
@Override
protected void doLog(Logger logger, String message) {
super.doLog(logger, message);
this.logger = logger;
this.message = message;
}
}
}
@@ -26,12 +26,12 @@ import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.inject.ContainerBuilder;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor;
import com.opensymphony.xwork2.interceptor.TimerInterceptor;
import com.opensymphony.xwork2.test.StubConfigurationProvider;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import com.opensymphony.xwork2.validator.Validator;
import com.opensymphony.xwork2.validator.validators.ExpressionValidator;
import com.opensymphony.xwork2.validator.validators.RequiredStringValidator;
import org.apache.struts2.interceptor.NoOpInterceptor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.interceptor.DebugInterceptor;
@@ -126,12 +126,12 @@ public class SpringObjectFactoryTest extends XWorkTestCase {
}
public void testObtainInterceptorBySpringName() throws Exception {
sac.registerSingleton("timer-interceptor", TimerInterceptor.class, new MutablePropertyValues());
sac.registerSingleton("noop-interceptor", NoOpInterceptor.class, new MutablePropertyValues());
InterceptorConfig iConfig = new InterceptorConfig.Builder("timer", "timer-interceptor").build();
InterceptorConfig iConfig = new InterceptorConfig.Builder("noop", "noop-interceptor").build();
Interceptor interceptor = objectFactory.buildInterceptor(iConfig, new HashMap<String, String>());
assertEquals(TimerInterceptor.class, interceptor.getClass());
assertEquals(NoOpInterceptor.class, interceptor.getClass());
}
public void testObtainResultBySpringName() throws Exception {
@@ -1,127 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 com.opensymphony.xwork2.util.profiling;
import junit.framework.TestCase;
/**
*
* @author tm_jee
* @version $Date$ $Id$
*/
public class ProfilingTimerBeanTest extends TestCase {
public void testAddChild() throws Exception {
ProfilingTimerBean bean0 = new ProfilingTimerBean("bean0");
ProfilingTimerBean bean1 = new ProfilingTimerBean("bean1");
ProfilingTimerBean bean2 = new ProfilingTimerBean("bean2");
ProfilingTimerBean bean3 = new ProfilingTimerBean("bean3");
ProfilingTimerBean bean4 = new ProfilingTimerBean("bean4");
ProfilingTimerBean bean5 = new ProfilingTimerBean("bean5");
ProfilingTimerBean bean6 = new ProfilingTimerBean("bean6");
ProfilingTimerBean bean7 = new ProfilingTimerBean("bean7");
ProfilingTimerBean bean8 = new ProfilingTimerBean("bean8");
/* bean0
* + bean1
* + bean2
* + bean3
* + bean4
* + bean5
* + bean6
* +bean7
* + bean8
*/
bean0.addChild(bean1);
bean0.addChild(bean3);
bean0.addChild(bean8);
bean1.addChild(bean2);
bean3.addChild(bean4);
bean3.addChild(bean7);
bean4.addChild(bean5);
bean5.addChild(bean6);
// bean0
assertNull(bean0.getParent());
assertEquals(bean0.children.size(), 3);
assertTrue(bean0.children.contains(bean1));
assertTrue(bean0.children.contains(bean3));
assertTrue(bean0.children.contains(bean8));
// bean1
assertEquals(bean1.getParent(), bean0);
assertEquals(bean1.children.size(), 1);
assertTrue(bean1.children.contains(bean2));
// bean2
assertEquals(bean2.getParent(), bean1);
assertEquals(bean2.children.size(), 0);
// bean3
assertEquals(bean3.getParent(), bean0);
assertEquals(bean3.children.size(), 2);
assertTrue(bean3.children.contains(bean4));
assertTrue(bean3.children.contains(bean7));
// bean4
assertEquals(bean4.getParent(), bean3);
assertEquals(bean4.children.size(), 1);
assertTrue(bean4.children.contains(bean5));
// bean5
assertEquals(bean5.getParent(), bean4);
assertEquals(bean5.children.size(), 1);
assertTrue(bean5.children.contains(bean6));
// bean6
assertEquals(bean6.getParent(), bean5);
assertEquals(bean6.children.size(), 0);
// bean7
assertEquals(bean7.getParent(), bean3);
assertEquals(bean7.children.size(), 0);
// bean8
assertEquals(bean8.getParent(), bean0);
assertEquals(bean8.children.size(), 0);
}
public void testTime() throws Exception {
ProfilingTimerBean bean0 = new ProfilingTimerBean("bean0");
bean0.setStartTime();
Thread.sleep(1050);
bean0.setEndTime();
assertTrue(bean0.totalTime >= 1000);
}
public void testPrint() throws Exception {
ProfilingTimerBean bean0 = new ProfilingTimerBean("bean0");
bean0.setStartTime();
Thread.sleep(1050);
bean0.setEndTime();
assertEquals(bean0.getPrintable(2000), "");
assertTrue(bean0.getPrintable(500).length() > 0);
}
}
@@ -1,136 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 com.opensymphony.xwork2.util.profiling;
import junit.framework.TestCase;
/**
* @author tmjee
* @version $Date$ $Id$
*/
public class UtilTimerStackTest extends TestCase {
protected String activateProp;
protected String minTimeProp;
public void testActivateInactivate() throws Exception {
UtilTimerStack.setActive(true);
assertTrue(UtilTimerStack.isActive());
UtilTimerStack.setActive(false);
assertFalse(UtilTimerStack.isActive());
}
public void testPushPop() throws Exception {
UtilTimerStack.push("p1");
Thread.sleep(1050);
ProfilingTimerBean bean = UtilTimerStack.current.get();
assertTrue(bean.startTime > 0);
UtilTimerStack.pop("p1");
assertTrue(bean.totalTime > 1000);
}
public void testProfileCallback() throws Exception {
MockProfilingBlock<String> block = new MockProfilingBlock<String>() {
@Override
public String performProfiling() throws Exception {
Thread.sleep(1050);
return "OK";
}
};
String result = UtilTimerStack.profile("p1", block);
assertEquals(result, "OK");
assertNotNull(block.getProfilingTimerBean());
assertTrue(block.getProfilingTimerBean().totalTime >= 1000);
}
public void testProfileCallbackThrowsException() throws Exception {
try {
UtilTimerStack.profile("p1",
new UtilTimerStack.ProfilingBlock<String>() {
public String doProfiling() throws Exception {
throw new RuntimeException("test");
}
});
fail("exception should have been thrown");
}
catch (Exception e) {
assertTrue(true);
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
activateProp = System.getProperty(UtilTimerStack.ACTIVATE_PROPERTY);
minTimeProp = System.getProperty(UtilTimerStack.MIN_TIME);
System.setProperty(UtilTimerStack.ACTIVATE_PROPERTY, "true");
UtilTimerStack.setActive(true);
System.setProperty(UtilTimerStack.MIN_TIME, "0");
}
@Override
protected void tearDown() throws Exception {
if (activateProp != null) {
System.setProperty(UtilTimerStack.ACTIVATE_PROPERTY, activateProp);
} else {
System.clearProperty(UtilTimerStack.ACTIVATE_PROPERTY);
}
if (minTimeProp != null) {
System.setProperty(UtilTimerStack.MIN_TIME, minTimeProp);
} else {
System.clearProperty(UtilTimerStack.ACTIVATE_PROPERTY);
}
activateProp = null;
minTimeProp = null;
super.tearDown();
}
public abstract class MockProfilingBlock<T> implements UtilTimerStack.ProfilingBlock<T> {
private ProfilingTimerBean bean;
public T doProfiling() throws Exception {
bean = UtilTimerStack.current.get();
return performProfiling();
}
public ProfilingTimerBean getProfilingTimerBean() {
return bean;
}
public abstract T performProfiling() throws Exception;
}
}
@@ -33,14 +33,14 @@
</result-types>
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="noop" class="org.apache.struts2.interceptor.NoOpInterceptor"/>
<interceptor name="logging" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="test" class="com.opensymphony.xwork2.mock.MockInterceptor">
<param name="foo">fooDefault</param>
</interceptor>
<interceptor-stack name="defaultStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="noop"/>
</interceptor-stack>
</interceptors>
@@ -33,14 +33,12 @@
</result-types>
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="logging" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="test" class="com.opensymphony.xwork2.mock.MockInterceptor">
<param name="foo">fooDefault</param>
</interceptor>
<interceptor-stack name="defaultStack">
<interceptor-ref name="timer"/>
</interceptor-stack>
</interceptors>
@@ -59,4 +57,4 @@
<param name="testForXW171"></param>
</action>
</package>
</xwork>
</xwork>
@@ -33,14 +33,14 @@
</result-types>
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="noop" class="org.apache.struts2.interceptor.NoOpInterceptor"/>
<interceptor name="logging" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="test" class="com.opensymphony.xwork2.mock.MockInterceptor">
<param name="foo">fooDefault</param>
</interceptor>
<interceptor-stack name="defaultStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="noop"/>
</interceptor-stack>
</interceptors>
@@ -28,11 +28,11 @@
<!-- this package has a default interceptor ref - so actions with no refs should have the default ref -->
<package name="default">
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="noop" class="org.apache.struts2.interceptor.NoOpInterceptor"/>
<interceptor name="logging" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
</interceptors>
<default-interceptor-ref name="timer" />
<default-interceptor-ref name="noop" />
<action name="ActionWithOwnRef" class="com.opensymphony.xwork2.SimpleAction">
<interceptor-ref name="logging"/>
</action>
@@ -28,10 +28,10 @@
<include file="xwork-test-beans.xml" />
<package name="default">
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="noop" class="org.apache.struts2.interceptor.NoOpInterceptor"/>
<interceptor-stack name="defaultStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="noop"/>
</interceptor-stack>
</interceptors>
</package>
@@ -28,13 +28,13 @@
<include file="xwork-test-beans.xml" />
<package name="default">
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="noop" class="org.apache.struts2.interceptor.NoOpInterceptor"/>
<interceptor name="test" class="com.opensymphony.xwork2.mock.MockInterceptor">
<param name="foo">fooDefault</param>
</interceptor>
<interceptor-stack name="defaultStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="noop"/>
<interceptor-ref name="test"/>
</interceptor-stack>
</interceptors>
@@ -28,14 +28,14 @@
<include file="xwork-test-beans.xml" />
<package name="default">
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="noop" class="org.apache.struts2.interceptor.NoOpInterceptor"/>
<interceptor name="logging" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="test" class="com.opensymphony.xwork2.mock.MockInterceptor">
<param name="foo">expectedFoo</param>
</interceptor>
<interceptor-stack name="defaultStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="noop"/>
<interceptor-ref name="test"/>
</interceptor-stack>
@@ -28,7 +28,7 @@
<include file="xwork-test-beans.xml" />
<package name="default">
<interceptors>
<interceptor name="timer" class="timer-interceptor"/>
<interceptor name="noop" class="noop-interceptor"/>
</interceptors>
</package>
</xwork>
@@ -37,7 +37,6 @@
</result-types>
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
@@ -56,7 +55,6 @@
</interceptor-stack>
<interceptor-stack name="debugStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>
@@ -33,7 +33,6 @@
</result-types>
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
@@ -53,7 +52,6 @@
</interceptor-stack>
<interceptor-stack name="debugStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>
@@ -34,7 +34,6 @@
</result-types>
<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
@@ -55,7 +54,6 @@
</interceptor-stack>
<interceptor-stack name="debugStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
@@ -24,7 +24,6 @@ import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.ValidationAware;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -162,37 +161,29 @@ public class RestActionInvocation extends DefaultActionInvocation {
}
protected void processResult() throws Exception {
String timerKey = "processResult: " + getResultCode();
try {
UtilTimerStack.push(timerKey);
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
// Select the target
selectTarget();
// Select the target
selectTarget();
// Get the httpHeaders
if (httpHeaders == null) {
httpHeaders = new DefaultHttpHeaders(resultCode);
}
// Get the httpHeaders
if (httpHeaders == null) {
httpHeaders = new DefaultHttpHeaders(resultCode);
}
// Apply headers
if (!hasErrors) {
httpHeaders.apply(request, response, target);
} else {
disableCatching(response);
}
// Apply headers
if (!hasErrors) {
httpHeaders.apply(request, response, target);
} else {
disableCatching(response);
}
// Don't return content on a not modified
if (httpHeaders.getStatus() != HttpServletResponse.SC_NOT_MODIFIED ) {
executeResult();
} else {
LOG.debug("Result not processed because the status code is not modified.");
}
} finally {
UtilTimerStack.pop(timerKey);
// Don't return content on a not modified
if (httpHeaders.getStatus() != HttpServletResponse.SC_NOT_MODIFIED ) {
executeResult();
} else {
LOG.debug("Result not processed because the status code is not modified.");
}
}
@@ -24,7 +24,6 @@ import com.opensymphony.sitemesh.compatability.Content2HTMLPage;
import com.opensymphony.xwork2.ActionContext;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
import freemarker.template.Configuration;
import freemarker.template.SimpleHash;
import freemarker.template.Template;
@@ -72,8 +71,6 @@ public class OldDecorator2NewStrutsFreemarkerDecorator extends OldDecorator2NewS
}
try {
UtilTimerStack.push(timerKey);
// get the configuration and template
Configuration config = freemarkerManager.getConfiguration(servletContext);
Template template = config.getTemplate(oldDecorator.getPage(), getLocale(ctx.getActionInvocation(), config)); // WW-1181
@@ -98,8 +95,6 @@ public class OldDecorator2NewStrutsFreemarkerDecorator extends OldDecorator2NewS
String msg = "Error applying decorator to request: " + request.getRequestURL() + "?" + request.getQueryString() + " with message:" + e.getMessage();
LOG.error(msg, e);
throw new ServletException(msg, e);
} finally {
UtilTimerStack.pop(timerKey);
}
}