📄 propertyassembler.java
字号:
package org.jbpm;
import java.util.*;
import java.lang.reflect.*;
import org.apache.commons.logging.*;
/**
* specifies a graph of objects that should be resolved on an object returned
* by a service.
*
* <p>A service-object is supposed to collect data from the persistency-layer
* and return data-transfer-objects to the client. If the datamodel has a lot
* of relations, a problem arises : Which related objects should be resolved in
* the object that is returned to the client. An Assembler-object is a convenient way of specifying
* which related objects you want to access on the objects returned by the session facade.
* You can specify an Assembler with dot-separated property-names.
* E.g. if the returned object is a Token, "processInstance.definition.states.name" specifies that
* for every returned Token the token.getProcessInstance().getDefinition().getStates() will
* return a collection of States on which the state.getName() will be accessable without
* getting a net.sf.hibernate.LazyInitializationException.
* </p>
*
* <p>Following markers can optionally be appended to the property names :
* <ul>
* <li><b>[ITERATE]</b> : specifies that the property is a collection,
* map or array and that for every element in the collection the
* remaining properties should be assembled.</li>
* <li><b>[RECURSIVE]</b> : specifies that the property is a recursive
* relation that should be resolved till a null value comes out of the
* getter. For everty object in the tree, the remaining properties
* are assembled.</li>
* <li><b>[ITERATE][RECURSIVE]</b> : specifies that the recursive property
* is a collection. E.g. "root.getChildren". </li>
* </ul>
* </p>
*/
public class PropertyAssembler implements Assembler {
private static final String RECURSIVE_MARKER = "[RECURSIVE]";
private static final String ITERATION_MARKER = "[ITERATE]";
private List propertyExpressions = new ArrayList();
/**
* creates a PropertyAssembler from one dot-separated property descriptor.
* @param property is a dot-separated property descriptor.
*/
public PropertyAssembler( String propertyExpressionText ) {
add(propertyExpressionText);
}
/**
* creates a PropertyAssembler from multiple dot-separated property descriptor.
* @param property is a dot-separated property descriptor.
*/
public PropertyAssembler( String[] propertyExpressionTexts ) {
for ( int i = 0; i < propertyExpressionTexts.length; i++ ) {
add( propertyExpressionTexts[ i ] );
}
}
public void add(String propertyExpressionText) {
List propertyExpression = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer( propertyExpressionText, "." );
while (tokenizer.hasMoreTokens()) {
propertyExpression.add( tokenizer.nextToken() );
}
propertyExpressions.add( propertyExpression.toArray( new String[propertyExpression.size()] ) );
}
public void assemble( Object object ) {
Iterator iter = propertyExpressions.iterator();
while (iter.hasNext()) {
assemblePropertyExpression(object, (String[]) iter.next(), 0);
}
}
private void assemblePropertyExpression( Object object, String[] propertyExpression, int index ) {
if ( ( object != null )
&& ( index < propertyExpression.length ) ) {
String property = propertyExpression[index];
if ( hasMarker(property, ITERATION_MARKER+RECURSIVE_MARKER) ) {
assembleRecursiveIteration( object, propertyExpression, index );
} else if ( hasMarker(property, ITERATION_MARKER) ) {
assembleCollection(object, propertyExpression, index );
} else if ( hasMarker(property, RECURSIVE_MARKER) ) {
assembleRecursive( object, propertyExpression, index );
} else {
assembleBeanProperty(object, propertyExpression, index);
}
}
}
private void assembleBeanProperty(Object object, String[] propertyExpression, int index) {
String property = propertyExpression[index];
// the next code fragment makes sure that the size methods is called upon collections
// that is to make sure that lazy collections are initialized.
Object relatedObject = getObject(object,property);
if ( relatedObject != null ) {
if ( relatedObject instanceof Collection ) {
((Collection)relatedObject).size();
} else if ( relatedObject instanceof Map ) {
((Map)relatedObject).size();
}
}
assemblePropertyExpression( getObject(object,property), propertyExpression, index+1 );
}
private void assembleCollection(Object object, String[] propertyExpression, int index) {
if ( object != null ) {
String property = propertyExpression[index];
String collectionProperty = getPropertyName( property );
if ( ! "".equals(collectionProperty) ) {
object = getObject( object, collectionProperty );
}
if ( object != null ) {
Collection collection = getCollection(object);
Iterator iter = collection.iterator();
while (iter.hasNext()) {
assemblePropertyExpression( iter.next(), propertyExpression, index+1 );
}
}
}
}
private void assembleRecursiveIteration(Object object, String[] propertyExpression, int index) {
if ( object != null ) {
String property = propertyExpression[index];
String recursiveProperty = getPropertyName( property );
Object recursiveCollection = getObject( object, recursiveProperty );
if ( recursiveCollection != null ) {
Iterator iter = getCollection( recursiveCollection ).iterator();
while (iter.hasNext()) {
Object recursiveObject = iter.next();
assembleRecursiveIteration( recursiveObject, propertyExpression, index );
assemblePropertyExpression( recursiveObject, propertyExpression, index+1 );
}
}
}
}
private void assembleRecursive(Object object, String[] propertyExpression, int index) {
if ( object != null ) {
String property = propertyExpression[index];
String recursiveProperty = getPropertyName( property );
if ( object != null ) {
Object recursiveObject = getObject( object, recursiveProperty );
if ( recursiveObject!=null ) {
assembleRecursive( recursiveObject, propertyExpression, index );
assemblePropertyExpression( recursiveObject, propertyExpression, index+1 );
}
}
}
}
private boolean isCollection(Object object) {
return ( (object != null )
&& ( ( object instanceof Collection )
|| ( object instanceof Map )
|| ( object instanceof Array ) ) );
}
private Collection getCollection(Object object) {
Collection collection = null;
if ( object instanceof Collection ) {
collection = (Collection) object;
} else if ( object instanceof Map ) {
collection = ((Map)object).values();
} else if ( object instanceof Array ) {
collection = Arrays.asList(((Object[])object));
} else {
throw new AssemblerException( "unsupported collection type '" + object.getClass().getName() + "'" );
}
return collection;
}
private boolean hasMarker( String property, String marker ) {
return (property.indexOf( marker ) != -1);
}
private String getPropertyName( String property ) {
String propertyName = null;
int leftBracketIndex = property.indexOf( "[" );
if ( leftBracketIndex == -1 ) {
propertyName = property;
} else {
propertyName = property.substring(0,leftBracketIndex);
}
return propertyName;
}
private Object getObject(Object object, String property) {
Object returnValue = null;
Method getter = getGetter( object, property );
if ( getter != null ) {
try {
returnValue = getter.invoke( object, null );
} catch (Exception e) {
throw new AssemblerException( "couldn't invoke getter '" + getter + "' on object '" + object + "'", e );
}
}
return returnValue;
}
private Method getGetter(Object object, String property) {
Method getter = null;
if ( ( object != null )
&& ( property != null ) ) {
try {
getter = object.getClass().getMethod( "get" + property.substring( 0, 1 ).toUpperCase() + property.substring( 1 ), null );
} catch (Exception e) {
throw new AssemblerException( "couldn't get getter for property '" + property + "' on object '" + object + "'" );
}
}
return getter;
}
private static Log log = LogFactory.getLog(PropertyAssembler.class);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -