⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 propertyassembler.java

📁 一个java工作流引擎
💻 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 + -