Source code: er/directtoweb/ERDDelayedObjectCreationAssignment.java
1 //
2 // ERDObjectCreationDelegate.java
3 // ERDirectToWeb
4 //
5 // Created by Max Muller on Wed Nov 20 2002.
6 //
7 package er.directtoweb;
8
9 import com.webobjects.foundation.*;
10 import com.webobjects.eocontrol.*;
11 import com.webobjects.directtoweb.*;
12 import er.extensions.*;
13
14 import java.lang.reflect.*;
15
16 /**
17 * Assignment used to create objects on the fly. This assignment
18 * can be used in two different manner. The first is by just
19 * specifing the class name as a string, ie "foo.bar.MyClass". This
20 * will create an instance of the MyClass object. The second form
21 * allows one to specify the object to be created in a dictionary format:
22 * {
23 * className = "foo.bar.MyClass";
24 * arguments = ( {
25 * className = "com.webobjects.appserver.WOSession";
26 * contextKey = "session";
27 * }, {
28 * className = "java.lang.String";
29 * contextKey = "propertyKey";
30 * });
31 * }
32 *
33 * This will create an object of type MyClass using the constructor:
34 * MyClass(WOSession session, String key), using the arguments found
35 * by resolving the contextKey off of the current {@link D2WContext context}.
36 */
37 public class ERDDelayedObjectCreationAssignment extends ERDDelayedAssignment {
38
39 // ===========================================================================
40 // Class variable(s)
41 // ---------------------------------------------------------------------------
42
43 /** logging support */
44 public static final ERXLogger log = ERXLogger.getERXLogger(ERDDelayedObjectCreationAssignment.class);
45
46 // ===========================================================================
47 // Class method(s)
48 // ---------------------------------------------------------------------------
49
50 /**
51 * Static constructor required by the EOKeyValueUnarchiver
52 * interface. If this isn't implemented then the default
53 * behavior is to construct the first super class that does
54 * implement this method. Very lame.
55 * @param eokeyvalueunarchiver to be unarchived
56 * @return decoded assignment of this class
57 */
58 public static Object decodeWithKeyValueUnarchiver(EOKeyValueUnarchiver eokeyvalueunarchiver) {
59 return new ERDDelayedObjectCreationAssignment(eokeyvalueunarchiver);
60 }
61
62 // ===========================================================================
63 // Constructor(s)
64 // ---------------------------------------------------------------------------
65
66 /**
67 * Public constructor
68 * @param u key-value unarchiver used when unarchiving
69 * from rule files.
70 */
71 public ERDDelayedObjectCreationAssignment(EOKeyValueUnarchiver u) { super(u); }
72
73 /**
74 * Public constructor
75 * @param key context key
76 * @param value of the assignment
77 */
78 public ERDDelayedObjectCreationAssignment(String key, Object value) { super(key,value); }
79
80 // ===========================================================================
81 // Instance method(s)
82 // ---------------------------------------------------------------------------
83
84 /**
85 * Delayed firing of assignment. Creates an object
86 * for the specified class. See description of the
87 * class for the correct format.
88 * @param context current context
89 * @return newly created object
90 */
91 public Object fireNow(D2WContext context) {
92 Object createdObject = null;
93 try {
94 if (log.isDebugEnabled())
95 log.debug("Creating object for value: " + value());
96 if (value() instanceof String) {
97 Class c = Class.forName((String)value());
98 createdObject = c.newInstance();
99 } else if (value() instanceof NSDictionary) {
100 String mainClassName = (String)((NSDictionary)value()).objectForKey("className");
101 Class mainClass = Class.forName(mainClassName);
102 NSArray arguments = (NSArray)((NSDictionary)value()).objectForKey("arguments");
103 if (arguments != null && arguments.count() > 0) {
104 Class argumentClasses[] = new Class[arguments.count()];
105 Object argumentValues[] = new Object[arguments.count()];
106 int count = 0;
107 while (count < arguments.count()) {
108 NSDictionary anArgument = (NSDictionary)arguments.objectAtIndex(count);
109 String argumentClassName = (String)anArgument.objectForKey("className");
110 String argumentContextKey = (String)anArgument.objectForKey("contextKey");
111 argumentValues[count] = context.valueForKeyPath(argumentContextKey);
112 argumentClasses[count] = Class.forName(argumentClassName);
113 count++;
114 }
115 Constructor constructor = mainClass.getConstructor(argumentClasses);
116 if (constructor != null) {
117 createdObject = constructor.newInstance(argumentValues);
118 } else {
119 log.warn("Unable to find constructor on class: " + mainClass.getName()
120 + " for argument classes: " + argumentClasses);
121 }
122 } else {
123 createdObject = mainClass.newInstance();
124 }
125 } else {
126 log.warn("Unsupported value: " + value());
127 }
128 } catch (Exception e) {
129 log.warn("Exception happened when attempting to create object for value: " + value() + " exception: " + e);
130 }
131 return createdObject;
132 }
133 }