org.beangle.struts2.view.component.Component Maven / Gradle / Ivy
/*
* Beangle, Agile Development Scaffold and Toolkit
*
* Copyright (c) 2005-2014, Beangle Software.
*
* Beangle is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Beangle is distributed in the hope that it will be useful.
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Beangle. If not, see .
*/
package org.beangle.struts2.view.component;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Stack;
import org.apache.struts2.StrutsException;
import org.apache.struts2.util.FastByteArrayOutputStream;
import org.apache.struts2.views.util.ContextUtil;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
/**
* remove actionMapper\determineActionURL\determineNamespace remove copy parameter
*
* @author chaostone
*/
public class Component {
public static final String COMPONENT_STACK = "b_component_stack";
protected ValueStack stack;
protected Map parameters;
/**
* Constructor.
*
* @param stack
* OGNL value stack.
*/
public Component(ValueStack stack) {
this.stack = stack;
this.parameters = new LinkedHashMap();
getComponentStack().push(this);
}
/**
* Gets the name of this component.
*
* @return the name of this component.
*/
private String getComponentName() {
Class> c = getClass();
String name = c.getName();
int dot = name.lastIndexOf('.');
return name.substring(dot + 1).toLowerCase();
}
/**
* Gets the component stack of this component.
*
* @return the component stack of this component, never null.
*/
protected Stack getComponentStack() {
@SuppressWarnings("unchecked")
Stack componentStack = (Stack) stack.getContext().get(COMPONENT_STACK);
if (componentStack == null) {
componentStack = new Stack();
stack.getContext().put(COMPONENT_STACK, componentStack);
}
return componentStack;
}
/**
* Callback for the start tag of this component. Should the body be
* evaluated?
*
* @param writer
* the output writer.
* @return true if the body should be evaluated
*/
public boolean start(Writer writer) {
return true;
}
/**
* Callback for the end tag of this component. Should the body be evaluated
* again?
*
* NOTE: will pop component stack.
*
* @param writer the output writer.
* @param body the rendered body.
* @return true if the body should be evaluated again
*/
public boolean end(Writer writer, String body) {
return end(writer, body, true);
}
/**
* Callback for the start tag of this component. Should the body be
* evaluated again?
*
* NOTE: has a parameter to determine to pop the component stack.
*
* @param writer the output writer.
* @param body the rendered body.
* @param popComponentStack
* should the component stack be popped?
* @return true if the body should be evaluated again
*/
protected boolean end(Writer writer, String body, boolean popComponentStack) {
assert (body != null);
try {
writer.write(body);
} catch (IOException e) {
throw new StrutsException("IOError while writing the body: " + e.getMessage(), e);
}
if (popComponentStack) popComponentStack();
return false;
}
/**
* Pops the component stack.
*/
protected void popComponentStack() {
getComponentStack().pop();
}
/**
* Finds the nearest ancestor of this component stack.
*
* @param clazz
* the class to look for, or if assignable from.
* @return the component if found, null if not.
*/
@SuppressWarnings("unchecked")
protected T findAncestor(Class clazz) {
Stack extends Component> componentStack = getComponentStack();
for (int i = componentStack.size() - 2; i >= 0; i--) {
Component component = componentStack.get(i);
if (clazz.equals(component.getClass())) return (T) component;
}
return null;
}
/**
* Evaluates the OGNL stack to find a String value.
*
* @param expr
* OGNL expression.
* @return the String value found.
*/
protected String findString(String expr) {
return (String) findValue(expr, String.class);
}
/**
* Evaluates the OGNL stack to find a String value.
*
* If the given expression is null a error is logged and a RuntimeException
* is thrown constructed with a messaged based on the given field and errorMsg paramter.
*
* @param expr
* OGNL expression.
* @param field
* field name used when throwing RuntimeException
.
* @param errorMsg
* error message used when throwing RuntimeException
.
* @return the String value found.
* @throws StrutsException
* is thrown in case of expression is null.
*/
protected String findString(String expr, String field, String errorMsg) {
if (expr == null) {
throw fieldError(field, errorMsg, null);
} else {
return findString(expr);
}
}
/**
* Constructs a RuntimeException
based on the given
* information.
*
* A message is constructed and logged at ERROR level before being returned as a
* RuntimeException
.
*
* @param field
* field name used when throwing RuntimeException
.
* @param errorMsg
* error message used when throwing RuntimeException
.
* @param e
* the caused exception, can be null.
* @return the constructed StrutsException
.
*/
protected StrutsException fieldError(String field, String errorMsg, Exception e) {
String msg = "tag '" + getComponentName() + "', field '" + field
+ (parameters != null && parameters.containsKey("name") ? "', name '" + parameters.get("name") : "")
+ "': " + errorMsg;
throw new StrutsException(msg, e);
}
/**
* Finds a value from the OGNL stack based on the given expression. Will
* always evaluate expr
against stack except when expr
is null. If
* altsyntax (%{...}) is applied, simply strip
* it off.
*
* @param expr
* the expression. Returns null if expr is null.
* @return the value, null if not found.
*/
protected Object findValue(String expr) {
if (expr == null) { return null; }
expr = stripExpressionIfAltSyntax(expr);
return stack.findValue(expr, false);
}
/**
* If altsyntax (%{...}) is applied, simply strip the "%{" and "}" off.
*
* @param expr
* the expression (must be not null)
* @return the stripped expression if altSyntax is enabled. Otherwise the
* parameter expression is returned as is.
*/
protected String stripExpressionIfAltSyntax(String expr) {
return stripExpressionIfAltSyntax(stack, expr);
}
/**
* If altsyntax (%{...}) is applied, simply strip the "%{" and "}" off.
*
* @param stack
* the ValueStack where the context value is searched for.
* @param expr
* the expression (must be not null)
* @return the stripped expression if altSyntax is enabled. Otherwise the
* parameter expression is returned as is.
*/
public static String stripExpressionIfAltSyntax(ValueStack stack, String expr) {
if (altSyntax(stack)) {
// does the expression start with %{ and end with }? if so, just cut
// it off!
if (expr.startsWith("%{") && expr.endsWith("}")) { return expr.substring(2, expr.length() - 1); }
}
return expr;
}
/**
* Is the altSyntax enabled? [TRUE]
*
*
* @param stack
* the ValueStack where the context value is searched for.
* @return true if altSyntax is activated. False otherwise. See struts.properties
* where the altSyntax flag is
* defined.
*/
public static boolean altSyntax(ValueStack stack) {
return ContextUtil.isUseAltSyntax(stack.getContext());
}
/**
* Is the altSyntax enabled? [TRUE]
*
* See struts.properties
where the altSyntax flag is defined.
*/
public boolean altSyntax() {
return altSyntax(stack);
}
/**
* Adds the sorrounding %{ } to the expression for proper processing.
*
* @param expr
* the expression.
* @return the modified expression if altSyntax is enabled, or the parameter
* expression otherwise.
*/
protected String completeExpressionIfAltSyntax(String expr) {
if (altSyntax()) { return "%{" + expr + "}"; }
return expr;
}
/**
* This check is needed for backwards compatibility with 2.1.x
*
* @param expr
* the expression.
* @return the found string if altSyntax is enabled. The parameter
* expression otherwise.
*/
protected String findStringIfAltSyntax(String expr) {
if (altSyntax()) { return findString(expr); }
return expr;
}
/**
* Evaluates the OGNL stack to find an Object value.
*
* Function just like findValue(String)
except that if the given expression is
* null a error is logged and a RuntimeException
is thrown constructed with
* a messaged based on the given field and errorMsg paramter.
*
* @param expr
* OGNL expression.
* @param field
* field name used when throwing RuntimeException
.
* @param errorMsg
* error message used when throwing RuntimeException
.
* @return the Object found, is never null.
* @throws StrutsException
* is thrown in case of not found in the OGNL stack, or
* expression is null.
*/
protected Object findValue(String expr, String field, String errorMsg) {
if (expr == null) {
throw fieldError(field, errorMsg, null);
} else {
Object value = null;
Exception problem = null;
try {
value = findValue(expr);
} catch (Exception e) {
problem = e;
}
if (value == null) { throw fieldError(field, errorMsg, problem); }
return value;
}
}
/**
* Evaluates the OGNL stack to find an Object of the given type. Will
* evaluate expr
the portion wrapped with altSyntax (%{...})
* against stack when altSyntax is on, else the whole expr
is
* evaluated against the stack.
*
* This method only supports the altSyntax. So this should be set to true.
*
* @param expr
* OGNL expression.
* @param toType
* the type expected to find.
* @return the Object found, or null if not found.
*/
protected Object findValue(String expr, Class> toType) {
if (altSyntax() && toType == String.class) {
return TextParseUtil.translateVariables('%', expr, stack);
} else {
expr = stripExpressionIfAltSyntax(expr);
return stack.findValue(expr, toType, false);
}
}
/**
* Constructs a string representation of the given exception.
*
* @param t
* the exception
* @return the exception as a string.
*/
protected String toString(Throwable t) {
FastByteArrayOutputStream bout = new FastByteArrayOutputStream();
PrintWriter wrt = new PrintWriter(bout);
t.printStackTrace(wrt);
wrt.close();
return bout.toString();
}
/**
* Gets the parameters.
*
* @return the parameters. Is never null.
*/
public Map getParameters() {
return parameters;
}
/**
* Adds all the given parameters to this component's own parameters.
*
* @param params
* the parameters to add.
*/
public void addAllParameters(Map params) {
parameters.putAll(params);
}
/**
* Adds the given key and value to this component's own parameter.
*
* If the provided key is null nothing happens. If the provided value is null
* any existing parameter with the given key name is removed.
*
* @param key
* the key of the new parameter to add.
* @param value
* the value assoicated with the key.
*/
public void addParameter(String key, Object value) {
if (key != null) {
Map params = getParameters();
if (value == null) params.remove(key);
else params.put(key, value);
}
}
/**
* Overwrite to set if body shold be used.
*
* @return always false for this component.
*/
public boolean usesBody() {
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy