Source code: org/jbpm/util/client/Relations.java
1 package org.jbpm.util.client;
2
3 import java.util.*;
4 import java.lang.reflect.*;
5 import org.apache.log4j.*;
6
7 /**
8 * specifies which related objects should be resolved for data-transfer-objects,
9 * returned from a session-facade.
10 *
11 * <p>A session facade is supposed to collect data from the persistency-layer
12 * and return data-transfer-objects to the client. If the datamodel has a lot
13 * of relations, a problem arises : Which related objects should be resolved in
14 * the object that is returned to the client. A Relations-object is a convenient way of specifying
15 * which related objects you want to be resolve on the objects returned by the session facade.
16 * You can specify these Relations with dot-separated property-names.
17 * E.g. if the returned object is a Flow, "attributeInstance.attribute" specifies that
18 * for every returned Flow-object the methods Collection getAttributeInstance() must
19 * be resolved and that these AttributeInstances have the Attribute getAttribute()
20 * resolved.
21 * </p>
22 *
23 * @author Tom Baeyens
24 */
25 public class Relations {
26
27 /**
28 * creates a Relation from one dot-separated property descriptor.
29 * @param property is a dot-separated property descriptor.
30 */
31 public Relations( String property ) {
32 if ( property != null ) add(property);
33 }
34
35 /**
36 * creates a Relation from multiple dot-separated property descriptor.
37 * @param property is a dot-separated property descriptor.
38 */
39 public Relations( String[] properties ) {
40 if ( properties != null ) {
41 for ( int i = 0; i < properties.length; i++ ) {
42 add( properties[ i ] );
43 }
44 }
45 }
46
47 private void add( String fullyQualifiedProperty ) {
48 String atomicProperty = null;
49 String subProperty = null;
50
51 int dotIndex = fullyQualifiedProperty.indexOf( '.' );
52
53 if ( dotIndex != -1 ) {
54 atomicProperty = fullyQualifiedProperty.substring( 0, dotIndex );
55 subProperty = fullyQualifiedProperty.substring( dotIndex + 1 );
56 } else {
57 atomicProperty = fullyQualifiedProperty;
58 }
59
60 Relations subRelation = (Relations) relationsMap.get( atomicProperty );
61 if ( subRelation != null ) {
62 subRelation.add( subProperty );
63 } else {
64 if ( subProperty != null ) {
65 subRelation = new Relations( subProperty );
66 }
67 }
68
69 relationsMap.put( atomicProperty, subRelation );
70 }
71
72 public Map getRelationsMap() {
73 return relationsMap;
74 }
75
76 public void resolve( Object object ) {
77 resolve( object, relationsMap );
78 }
79
80 private static void resolve( Object object, Map relationsMap ) {
81 if ( object == null ) return;
82 if ( object instanceof Collection ) {
83 Iterator iter = ((Collection)object).iterator();
84 while (iter.hasNext()) {
85 Object element = (Object) iter.next();
86 resolveObject( element, relationsMap );
87 }
88 } else if ( object instanceof Object[] ) {
89 Object[] objectArray = (Object[]) object;
90 for ( int i = 0; i < objectArray.length; i++ ) {
91 resolveObject( objectArray[i], relationsMap );
92 }
93 } else {
94 resolveObject( object, relationsMap );
95 }
96 }
97
98 private static void resolveObject( Object persistentObject, Map relationsMap ) {
99 if ( relationsMap == null ) return;
100
101 Iterator iter = relationsMap.entrySet().iterator();
102 while (iter.hasNext()) {
103 Map.Entry entry = (Map.Entry) iter.next();
104 String propertyName = (String) entry.getKey();
105
106 Map rest = null;
107 Relations relations = (Relations) entry.getValue();
108 if ( relations != null ) {
109 rest = relations.relationsMap;
110 }
111
112 try {
113 String getterName = "get" + propertyName.substring( 0, 1 ).toUpperCase() + propertyName.substring( 1 );
114 Method getter = persistentObject.getClass().getMethod( getterName, null );
115 Object agreggatedObject = getter.invoke( persistentObject, null );
116 // log.debug( "agreggatedObject: " + agreggatedObject );
117 if ( agreggatedObject != null ) {
118 resolve(agreggatedObject, rest);
119 }
120 } catch (Exception e) {
121 log.error( "can't resolve property " + propertyName + " for object " + persistentObject + " : " + e.getMessage() );
122 e.printStackTrace();
123 }
124 }
125 }
126
127 private Map relationsMap = new HashMap();
128 private static final Logger log = Logger.getLogger(Relations.class);
129 }