de.tsl2.nano.bean.def.AbstractExpression Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tsl2.nano.descriptor Show documentation
Show all versions of tsl2.nano.descriptor Show documentation
TSL2 Framework Descriptor (currency-handling, generic formatter, descriptors for beans, collections, actions and values)
package de.tsl2.nano.bean.def;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Default;
import org.simpleframework.xml.DefaultType;
import org.simpleframework.xml.Element;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.cls.IAttribute;
import de.tsl2.nano.core.log.LogFactory;
/**
* Base Attribute Expression as descriptor of a real (extending) expression. can instantiate a
* real expression through registered expression patterns.
*
* @param
* @author Tom
* @version $Revision$
*/
@Default(value = DefaultType.FIELD, required = false)
public abstract class AbstractExpression implements IValueExpression, IAttribute, Serializable {
private static final long serialVersionUID = 2798715915354958266L;
private static final Log LOG = LogFactory.getLog(AbstractExpression.class);
/** declaringClass of first attribute in chain */
@Attribute(required = false)
protected Class> declaringClass;
/** attribute type */
@Attribute(required = false)
protected Class type;
@Element(data = true)
protected String expression;
/**
* should be the same as used in beans attribute definitions. if undefined, the last part of the expression will be
* used.
*/
//@Attribute
protected transient String name;
/**
* framework extensions can register own value-expression extensions. this extensions will be used on calling
* {@link #setExpression(String)}. the extensions must have a constuctor with two arguments: Class declaringClass,
* String expression.
*/
@SuppressWarnings("rawtypes")
protected static final Map> registeredExtensions =
new HashMap>();
public AbstractExpression() {
super();
}
/**
* constructor
*
* @param declaringClass
* @param expression
* @param type
*/
protected AbstractExpression(Class> declaringClass, String expression, Class type) {
super();
setExpression(expression);
this.declaringClass = declaringClass;
this.type = type;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public Class getType() {
if (type == null) {
type = (Class) BeanDefinition.UNDEFINED.getClass();
}
return type;
}
/**
* setType
*
* @param type
*/
public void setType(Class type) {
this.type = type;
}
@Override
public String getExpression() {
return expression;
}
@Override
public void setExpression(String valueExpression) {
if (valueExpression == null || (getExpressionPattern() != null && !valueExpression.matches(getExpressionPattern()))) {
throw new IllegalArgumentException("The expression '" + valueExpression
+ "' has to match the regular expression '" + getExpressionPattern() + "'");
}
//if name was calculated, reset it
if (this.name != null && this.expression != null && this.expression.contains(name))
this.name = null;
this.expression = valueExpression;
}
/**
* @return Returns the declaringClass.
*/
@Override
public Class> getDeclaringClass() {
return declaringClass;
}
public void setDeclaringClass(Class> declaringClass) {
this.declaringClass = declaringClass;
}
@Override
public String toString() {
return (declaringClass != null ? declaringClass.getSimpleName() + ": " : "") + expression;
}
/**
* {@inheritDoc}
*/
@Override
public int compareTo(IAttribute o) {
return getName().compareTo(o.getName());
}
@Override
public String getId() {
return (getDeclaringClass() != null ? getDeclaringClass().getSimpleName() : "[unknown]") + ":" + getExpression();
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
if (name == null) {
name = expression;
}
return expression;
}
@Override
public void setName(String name) {
this.name = name;
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasWriteAccess() {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public Method getAccessMethod() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isVirtual() {
return true;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return getId().hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
return hashCode() == obj.hashCode();
}
// /**
// * {@inheritDoc}
// */
// @Override
// public void setExpression(String valueExpression) {
// /*
// * is it a special value like a value-path or a rule?
// */
// Class extends IValueExpression> extensionClass =
// (Class extends IValueExpression>) getImplementation(valueExpression);
// IValueExpression extension;
// if (extensionClass != null) {
// extension = BeanClass.createInstance(extensionClass, valueExpression);
// } else {
// extension = new ValueExpression(valueExpression, getType());
// }
// setValueExpression(extension);
// }
//
public static String createRegExpOnAllRegistered() {
StringBuilder buf = new StringBuilder();
buf.append("(");
Collection regExps = registeredExtensions.keySet();
for (String e : regExps) {
buf.append("(" + e + ")" + "|");
}
buf.deleteCharAt(buf.length()-1);
buf.append(")");
return buf.toString();
}
/**
* see {@link #registeredExtensions}, {@link #getImplementation(String)} and {@link #getBeanValue(Object, String)}.
*
* @param attributeRegEx regular expression, defining a specialized attribute
* @param extension type to handle the specialized attribute.
*/
public static final void registerExpression(Class extends AbstractExpression> extension) {
try {
String pattern = extension.newInstance().getExpressionPattern();
LOG.info("registering expression class " + extension + " for pattern: " + pattern);
registeredExtensions.put(pattern, extension);
} catch (Exception e) {
ManagedException.forward(e);
}
}
/**
* getExtension
*
* @param expression attribute expression to check
* @return registered extension or null - if standard
*/
protected static Class extends AbstractExpression> getImplementation(String expression) {
Set regExs = registeredExtensions.keySet();
for (String attrRegEx : regExs) {
if (expression.matches(attrRegEx)) {
return registeredExtensions.get(attrRegEx);
}
}
return null;
}
}