You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by si...@apache.org on 2009/03/03 17:18:07 UTC

svn commit: r749642 - in /labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans: BeanData.java BeanHandler.java BeansAspect.aj BeansHandlerAspect.aj MagmaBean.java MagmaBeanSupport.java PropertyInfo.java

Author: simoneg
Date: Tue Mar  3 16:18:06 2009
New Revision: 749642

URL: http://svn.apache.org/viewvc?rev=749642&view=rev
Log:
LABS-285 : javadocs for foundation-beans

Modified:
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanData.java
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanHandler.java
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansAspect.aj
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansHandlerAspect.aj
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBean.java
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBeanSupport.java
    labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/PropertyInfo.java

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanData.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanData.java?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanData.java (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanData.java Tue Mar  3 16:18:06 2009
@@ -30,10 +30,25 @@
 
 import org.apache.commons.beanutils.PropertyUtils;
 
+/**
+ * Holds informations about a bean. The bean is inspected only once, and various components
+ * can participate adding fields to this class or to {@link PropertyInfo} and intercepting the 
+ * {@link PropertyInfo#init(PropertyDescriptor, Class)} method to provide parsing.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 public class BeanData {
 	
+	/**
+	 * Cached {@link BeanData} for already inspected bean classes.
+	 */
 	private static Map<Class,BeanData> data = new HashMap<Class, BeanData>();
 	
+	/**
+	 * Retrieves a {@link BeanData} for a given bean, either cached or by parsing.
+	 * @param clazz the class of the bean.
+	 * @return a {@link BeanData} for the class.
+	 */
 	public static BeanData getFor(Class clazz) {
 		BeanData ret = data.get(clazz);
 		if (ret == null) {
@@ -43,10 +58,20 @@
 		return ret;
 	}
 	
+	/**
+	 * The class this {@link BeanData} holds informations for.
+	 */
 	private Class beanClass = null;
 	
+	/**
+	 * Properties of the class.
+	 */
 	private Map<String, PropertyInfo> properties = new HashMap<String, PropertyInfo>();
 
+	/**
+	 * Builds a new {@link BeanData} for the given class, performing inspection.
+	 * @param clazz the class to inspect.
+	 */
 	private BeanData(Class clazz) {
 		this.beanClass = clazz;
 		BeanInfo beanInfo = null;
@@ -63,18 +88,35 @@
 		}
 	}
 	
+	/**
+	 * Fetches names of properties in the bean class.
+	 * @return names of properties
+	 */
 	public Set<String> getPropertyNames() {
 		return Collections.unmodifiableSet(properties.keySet());
 	}
 	
+	/**
+	 * Fetches a single property.
+	 * @param name the name of the property to fetch.
+	 * @return a {@link PropertyInfo} describing the required property, or null if not found.
+	 */
 	public PropertyInfo getProperty(String name) {
 		return properties.get(name);
 	}
 	
+	/**
+	 * @return the class this {@link BeanData} holds informations for.
+	 */
 	public Class getBeanClass() {
 		return this.beanClass;
 	}
 
+	/**
+	 * Searches for the property on which given method operates.
+	 * @param method the method, a getter or setter.
+	 * @return the {@link PropertyInfo} describing the property the method works on, or null if not found.
+	 */
 	public PropertyInfo findProperty(Method method) {
 		String name = method.getName();
 		if (name.startsWith("set") || name.startsWith("get")) {

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanHandler.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanHandler.java?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanHandler.java (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanHandler.java Tue Mar  3 16:18:06 2009
@@ -27,21 +27,61 @@
 
 import org.apache.commons.beanutils.PropertyUtils;
 
+/**
+ * Offers a "transactional" abstraction to a bean instance getters and setters.
+ * 
+ * Using an handler to populate or read a bean offers the advantage of offering a 
+ * hook point for other components to participate in the process, for example adding 
+ * validations. 
+ * 
+ * Also, this is the good place to add utility methods to perform operations on data, like
+ * conversion or formatting.
+ * 
+ * Having a "transactional" approach gives the opportunity to validate all the fields or to 
+ * make sure all conversions occurrs correctly before writing any value to the bean, reducing
+ * the possibility of stale data. 
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 public class BeanHandler {
 
+	/**
+	 * The bean we are working on.
+	 */
 	private MagmaBeanSupport bean;
+	
+	/**
+	 * The {@link BeanData} of the bean.
+	 */
 	private BeanData data;
 
+	/**
+	 * Temporary storage for bean values.
+	 */
 	private Map<String, Object> values = new HashMap<String, Object>();
+	
+	/**
+	 * Holds which values has been changed, to avoid calling setters on those unchanged properties.
+	 */
 	private Set<String> changed = new HashSet<String>();
 
-	
+	/**
+	 * Builds a handler for the given bean.
+	 * @param bean The bean to operate on.
+	 */
 	public BeanHandler(MagmaBeanSupport bean) {
 		this.bean = bean;
 		this.data = bean.beanData();
 		rollback();
 	}
 	
+	/**
+	 * Sets a value on the bean, the {@link BeanData} is used to check that the property exist, it is writable and the value
+	 * is of correct type. Value is stored on the temporary area, will be effectively transferred to the bean when 
+	 * {@link #commit()} is called, or removed when {@link #rollback()} is called.
+	 * @param field The name of the property to set.
+	 * @param value The value to set.
+	 */
 	public void setValue(String field, Object value) {
 		PropertyInfo property = data.getProperty(field);
 		if (property == null) throw new MagmaException("Cannot find a proprty named {0} in class {1}", field, bean.getClass().getName());
@@ -55,6 +95,13 @@
 		changed.add(field);
 	}
 
+	/**
+	 * Gets a value from the bean, the {@link BeanData} is used to check that the property exist and it is readable. Value
+	 * is taken from the temporary area, where it has been fetched by {@link #rollback()} and eventually modified by
+	 * {@link #setValue(String, Object)} or by other methods contributed by other components. 
+	 * @param field the name of the property to get.
+	 * @return the value of the property.
+	 */
 	public Object getValue(String field) {
 		PropertyInfo property = data.getProperty(field);
 		if (property == null) throw new MagmaException("Cannot find a proprty named {0} in class {1}", field, bean.getClass().getName());
@@ -62,6 +109,10 @@
 		return values.get(field);
 	}
 	
+	/**
+	 * Load from the bean (calling getters) all the applicable properties, and places them in the temporary area, eventually
+	 * overwriting values placed there by {@link #setValue(String, Object)}.
+	 */
 	public void rollback() {
 		this.values.clear();
 		this.changed.clear();
@@ -80,6 +131,11 @@
 		}
 	}
 	
+	/**
+	 * Saves on the bean (calling setters) all the properties modified using {@link #setValue(String, Object)} (or equivalent
+	 * methods contributed by other components). This method is the perfect hook to perform validations or other preprocessing 
+	 * of values.
+	 */
 	public void commit() {
 		for (Iterator<String> iterator = changed.iterator(); iterator.hasNext();) {
 			String name = iterator.next();
@@ -95,6 +151,11 @@
 		}
 	}
 
+	/**
+	 * Notifies this {@link BeanHandler} that a property has changed on the bean. An aspect provide interception of
+	 * setters to notify existing handlers.
+	 * @param property
+	 */
 	public void updated(PropertyInfo property) {
 		if (property.isReadable()) {
 			String name = property.getName();

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansAspect.aj
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansAspect.aj?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansAspect.aj (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansAspect.aj Tue Mar  3 16:18:06 2009
@@ -16,7 +16,15 @@
  */
 package org.apache.magma.beans;
 
-
+/**
+ * Injects the {@link MagmaBeanSupport} interface on beans recognized by Magma. Currently
+ * that means beans annotated with {@link MagmaBean} or classes contained in a package
+ * that contains "domain" in its name.
+ * 
+ * Also provides a default implementation for the two methods of {@link MagmaBeanSupport}.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 public aspect BeansAspect {
 	
 	declare parents: (*..domain..*) implements MagmaBeanSupport;

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansHandlerAspect.aj
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansHandlerAspect.aj?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansHandlerAspect.aj (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeansHandlerAspect.aj Tue Mar  3 16:18:06 2009
@@ -19,15 +19,33 @@
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Method;
 
+import org.apache.magma.basics.startup.Cycle;
 import org.apache.magma.basics.startup.CycleThreadLocal;
 import org.aspectj.lang.reflect.MethodSignature;
 
+/**
+ * Manages {@link BeanHandler}s on bean instances, so that each thread has a single
+ * handler if working on the same bean, and old handlers are cleaned up when the 
+ * {@link Cycle} ends.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 public aspect BeansHandlerAspect perthis(calledHandler(MagmaBeanSupport)) {
 
+	/**
+	 * A {@link CycleThreadHandler} holding (as SoftRerence) handlers on a bean. 
+	 */
 	private CycleThreadLocal<SoftReference<BeanHandler>> tl = new CycleThreadLocal<SoftReference<BeanHandler>>();
 	
+	/**
+	 * The call of the method {@link MagmaBeanSupport#handler()}.
+	 * @param bean the bean the method was called on.
+	 */
 	pointcut calledHandler(MagmaBeanSupport bean) : execution(public BeanHandler MagmaBeanSupport+.handler()) && this(bean);
 	
+	/**
+	 * Returns the existing handler or a new one.
+	 */
 	Object around(MagmaBeanSupport bean) : calledHandler(bean) {
 		SoftReference<BeanHandler> reference = tl.get();
 		if (reference != null) {
@@ -41,8 +59,15 @@
 		return handler;
 	}
 	
+	/**
+	 * Intercepts calls to a setter on a managed bean, to notify handlers.
+	 * @param bean
+	 */
 	pointcut calledSetter(MagmaBeanSupport bean) : execution(public void MagmaBeanSupport+.set*(..)) && !cflow(execution(* BeanHandler+.commit()) || execution(* BeanHandler+.rollback())) && this(bean);
 	
+	/**
+	 * Notifies handlers that a property on the bean has changed.
+	 */
 	after(MagmaBeanSupport bean) returning : calledSetter(bean) {
 		if (((MethodSignature)thisJoinPointStaticPart.getSignature()).getMethod().isSynthetic()) return;
 		Method method = ((MethodSignature)thisJoinPointStaticPart.getSignature()).getMethod();

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBean.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBean.java?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBean.java (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBean.java Tue Mar  3 16:18:06 2009
@@ -22,6 +22,11 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * Marker annotation for beans that should be handled using {@link BeanData} and {@link BeanHandler}.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Inherited

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBeanSupport.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBeanSupport.java?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBeanSupport.java (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MagmaBeanSupport.java Tue Mar  3 16:18:06 2009
@@ -16,11 +16,23 @@
  */
 package org.apache.magma.beans;
 
-import java.util.HashMap;
-import java.util.Map;
 
+/**
+ * Interface inferred on bean managed using {@link BeanData} and {@link BeanHandler}.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 public interface MagmaBeanSupport {
 	
+	/**
+	 * Retrieves the {@link BeanData} instance for this class.
+	 * @return BeanData for this class.
+	 */
 	public BeanData beanData();
+
+	/**
+	 * Retrieves the {@link BeanHandler} instance for this class.
+	 * @return BeanHandler for this class.
+	 */	
 	public BeanHandler handler();
 }

Modified: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/PropertyInfo.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/PropertyInfo.java?rev=749642&r1=749641&r2=749642&view=diff
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/PropertyInfo.java (original)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/PropertyInfo.java Tue Mar  3 16:18:06 2009
@@ -21,42 +21,110 @@
 import java.lang.reflect.Type;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.magma.basics.utils.GenericClass;
 import org.apache.magma.basics.utils.GenericClass.MethodDef;
 
+/**
+ * Holds informations about a property of a bean.
+ * 
+ * Other components can parse more annotation of meta informations intercepting the 
+ * {@link #init(PropertyDescriptor, Class)} method, to populate additional fields on this
+ * class. This is how, for example, validation and conversion works.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ */
 public class PropertyInfo implements Cloneable {
 
+	/**
+	 * Name of the property.
+	 */
 	private String name;
+	
+	/**
+	 * Type of the property
+	 */
 	private Class type;
+	
+	/**
+	 * Class of the bean this property is found on
+	 */
 	private Class beanClass;
+	
+	/**
+	 * Whether the property is readable
+	 */
 	private boolean readable;
+	
+	/**
+	 * Whether the property is writable 
+	 */
 	private boolean writeable;
 	
+	/**
+	 * Whether the property represents a collection (this includes {@link List}, {@link Set} and arrays, but not maps or tables).
+	 */
 	private boolean isCollection;
+	
+	/**
+	 * The type of elements contained in the collection (could be Object if it's not possible to deduce it)
+	 */
 	private Class collectionClass;
-	private int maxStringSize = -1;
 	
+	/**
+	 * If content of this property is rendered as a string, the maximum size of this string.
+	 */
+	private int maxStringSize = -1;
 	
+	/**
+	 * @return true if this property is readable from the bean, false otherwise
+	 */
 	public boolean isReadable() {
 		return readable;
 	}
+	/**
+	 * @param readable true if this property is readable from the bean, false otherwise
+	 */
 	public void setReadable(boolean readable) {
 		this.readable = readable;
 	}
+
+	/**
+	 * @return true if this property is writable to the bean, false otherwise
+	 */	
 	public boolean isWriteable() {
 		return writeable;
 	}
+	/**
+	 * @param writeable true if this property is writable to the bean, false otherwise
+	 */	
 	public void setWriteable(boolean writeable) {
 		this.writeable = writeable;
 	}
+	
+	/**
+	 * @return the name of the property.
+	 */		
 	public String getName() {
 		return name;
 	}
+	
+	/**
+	 * @return the type of the property.
+	 */
 	public Class getType() {
 		return type;
 	}
 	
+	/**
+	 * Initializes this class, parsing the {@link PropertyDescriptor} and eventually annotations found on the getter or setter methods.
+	 * 
+	 * This is the method to hook to when implementing additional parsing, like validation and conversion does.
+	 * 
+	 * @param descriptor the {@link PropertyDescriptor} of the property.
+	 * @param beanClass the class of the bean containing the property.
+	 */
 	public void init(PropertyDescriptor descriptor, Class beanClass) {
 		this.beanClass = beanClass;
 		this.name = descriptor.getName();
@@ -75,6 +143,9 @@
 		this.writeable = descriptor.getWriteMethod() != null;
 	}
 	
+	/**
+	 * Clones this {@link PropertyInfo}
+	 */
     public PropertyInfo clone() {
     	try {
 			return (PropertyInfo) super.clone();
@@ -82,39 +153,92 @@
 			return null;
 		}
     }
+    
+    /**
+     * @return Whether the property represents a collection (this includes {@link List}, {@link Set} and arrays, but not maps or tables).
+     */
 	public boolean isCollection() {
 		return isCollection;
 	}
+	
+	/**
+	 * @param isCollection Wether the property represents a collection.
+	 */
 	public void setCollection(boolean isCollection) {
 		this.isCollection = isCollection;
 	}
+	
+	/**
+	 * @return The type of elements contained in the collection (could be Object if it's not possible to deduce it)
+	 */
 	public Class getCollectionClass() {
 		return collectionClass;
 	}
+	
+	/**
+	 * @param collectionClass The type of elements contained in the collection (could be Object if it's not possible to deduce it)
+	 */	
 	public void setCollectionClass(Class collectionClass) {
 		this.collectionClass = collectionClass;
 	}
+	
+	/**
+	 * @return Class of the bean this property is found on
+	 */
 	public Class getBeanClass() {
 		return beanClass;
 	}
+	
+	/**
+	 * @param beanClass Class of the bean this property is found on
+	 */
 	public void setBeanClass(Class beanClass) {
 		this.beanClass = beanClass;
 	}
 	
+	/**
+	 * @return If content of this property is rendered as a string, the maximum size of this string.
+	 */
 	public int getMaximumStringSize() {
 		return this.maxStringSize;
 	}
+	
+	/**
+	 * @param size If content of this property is rendered as a string, the maximum size of this string.
+	 */
 	public void setMaximumStringSize(int size) {
 		this.maxStringSize = size;
 	}
+	
+	/**
+	 * Alters the string size, only reducing it.
+	 * @param size the proposed maximum size, or -1 to leave it unaltered.
+	 */
 	public void alterMaximumStringSize(int size) {
 		if (size == -1) return;
 		if (this.maxStringSize == -1 || this.maxStringSize > size) this.maxStringSize = size;
 	}
-    
+
+	/**
+	 * Converts the given value to a machine parsable string, considering the value coming from the property represented by this instance.
+	 * 
+	 * This means that other components may alter the way the value is converted, as conversion does.
+	 * 
+	 * @param value The value to convert to string.
+	 * @return the string machine parsable representation of value.
+	 */
 	public String toString(Object value) {
 		return value == null ? "" : value.toString();		
 	}
+	
+	/**
+	 * Converts the given value to a human friendly string, considering the value coming from the property represented by this instance.
+	 * 
+	 * This means that other components may alter the way the value is converted, as formatters and i18n do.
+	 * 
+	 * @param value The value to convert to string.
+	 * @return the string human friendly representation of value.
+	 */	
 	public String toUser(Object value) {
 		return toString(value);
 	}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org