KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > schema > rules > AddToMapRule


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.schema.rules;
16
17 import java.lang.reflect.Method JavaDoc;
18
19 import org.apache.hivemind.ApplicationRuntimeException;
20 import org.apache.hivemind.Element;
21 import org.apache.hivemind.schema.SchemaProcessor;
22 import org.apache.hivemind.util.PropertyUtils;
23
24 /**
25  * Rule used to connect a child object to its parent that is a map,
26  * by invoking a method on the parent,
27  * passing the child and a key that is taken from a childs attribute.
28  *
29  * @author Achim Huegen
30  */

31 public class AddToMapRule extends BaseRule
32 {
33     private String JavaDoc _methodName;
34
35     private String JavaDoc _keyAttribute;
36     
37     public AddToMapRule(String JavaDoc keyAttribute)
38     {
39         this("put", keyAttribute);
40     }
41
42     public AddToMapRule(String JavaDoc methodName, String JavaDoc keyAttribute)
43     {
44         _methodName = methodName;
45         _keyAttribute = keyAttribute;
46     }
47
48     /**
49      * Invokes the named method on the parent object (using reflection).
50      */

51     public void begin(SchemaProcessor processor, Element element)
52     {
53         Object JavaDoc parent = processor.peek(1);
54         Object JavaDoc child = processor.peek();
55
56         // Get all parameters from the stack in the order they where pushed on it
57
Object JavaDoc[] parameters = new Object JavaDoc[2];
58         parameters[0] = getKeyValue(child);
59         parameters[1] = child;
60             
61         Class JavaDoc[] parameterTypes = new Class JavaDoc[2];
62         parameterTypes[0] = getKeyType(child);
63         parameterTypes[1] = child.getClass();
64         
65         try
66         {
67             Method JavaDoc m = findMethod(parent, _methodName, parameterTypes);
68
69             m.invoke(parent, parameters);
70         }
71         catch (Exception JavaDoc ex)
72         {
73             throw new ApplicationRuntimeException(RulesMessages.errorInvokingMethod(
74                     _methodName,
75                     parent,
76                     getLocation(),
77                     ex), getLocation(), ex);
78         }
79     }
80
81     public String JavaDoc getMethodName()
82     {
83         return _methodName;
84     }
85
86     public void setMethodName(String JavaDoc string)
87     {
88         _methodName = string;
89     }
90
91     /**
92      * Searches for the *first* public method the has the right name, and takes a single parameter
93      * that is compatible with the parameter type.
94      *
95      * @throws NoSuchMethodException
96      * if a method can't be found
97      */

98     private Method JavaDoc findMethod(Object JavaDoc target, String JavaDoc name, Class JavaDoc[] parameterTypes)
99             throws NoSuchMethodException JavaDoc
100     {
101         Method JavaDoc[] methods = target.getClass().getMethods();
102
103         for (int i = 0; i < methods.length; i++)
104         {
105             Method JavaDoc m = methods[i];
106             Class JavaDoc[] actualParameterTypes = m.getParameterTypes();
107
108             if (actualParameterTypes.length != parameterTypes.length)
109                 continue;
110
111             if (!m.getName().equals(name))
112                 continue;
113
114             for (int j = 0; j < actualParameterTypes.length; j++)
115             {
116                 Class JavaDoc actualParameterType = actualParameterTypes[j];
117                 Class JavaDoc expectedParameterType = parameterTypes[j];
118                 if ((expectedParameterType != null && actualParameterType.isAssignableFrom(expectedParameterType))
119                         || (expectedParameterType == null && !actualParameterType.isPrimitive()))
120                     return m;
121                 
122             }
123         }
124
125         throw new NoSuchMethodException JavaDoc(name);
126     }
127
128     /**
129      * @param child
130      * @return the type of the attribute of the child that is used as key
131      */

132     private Class JavaDoc getKeyType(Object JavaDoc child)
133     {
134         return PropertyUtils.getPropertyType(child, _keyAttribute);
135     }
136
137     /**
138      * @param child
139      * @return the value of the attribute of the child that is used as key
140      */

141     private Object JavaDoc getKeyValue(Object JavaDoc child)
142     {
143         return PropertyUtils.read(child, _keyAttribute);
144     }
145
146 }
147
Popular Tags