Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/hivemind/schema/rules/InvokeParentRule.java


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;
18  
19  import org.apache.hivemind.ApplicationRuntimeException;
20  import org.apache.hivemind.Element;
21  import org.apache.hivemind.schema.SchemaProcessor;
22  
23  /**
24   * Rule used to connect a child object to its parent by invoking a method on the parent, passing the
25   * child. The child object is the top object on the stack and the parent object is the next object
26   * down on the stack. Created from the <code>&lt;invoke-parent&gt;</code> element. Generally, this
27   * is the last rule in a sequence of rules.
28   * 
29   * @author Howard Lewis Ship
30   */
31  public class InvokeParentRule extends BaseRule
32  {
33      private String _methodName;
34  
35      private int _depth = 1;
36  
37      public InvokeParentRule()
38      {
39  
40      }
41  
42      public InvokeParentRule(String methodName)
43      {
44          _methodName = methodName;
45      }
46  
47      /**
48       * Invokes the named method on the parent object (using reflection).
49       */
50      public void begin(SchemaProcessor processor, Element element)
51      {
52          Object child = processor.peek();
53          Class childClass = child == null ? null : child.getClass();
54          Object parent = processor.peek(_depth);
55  
56          try
57          {
58              Method m = findMethod(parent, _methodName, childClass);
59  
60              m.invoke(parent, new Object[]
61              { child });
62          }
63          catch (Exception ex)
64          {
65              throw new ApplicationRuntimeException(RulesMessages.errorInvokingMethod(
66                      _methodName,
67                      parent,
68                      getLocation(),
69                      ex), getLocation(), ex);
70          }
71      }
72  
73      public String getMethodName()
74      {
75          return _methodName;
76      }
77  
78      public void setMethodName(String string)
79      {
80          _methodName = string;
81      }
82  
83      /**
84       * @since 1.1
85       */
86      public int getDepth()
87      {
88          return _depth;
89      }
90  
91      /**
92       * Sets the depth of the parent object. The default is 1.
93       */
94      public void setDepth(int i)
95      {
96          _depth = i;
97      }
98  
99      /**
100      * Searches for the *first* public method the has the right name, and takes a single parameter
101      * that is compatible with the parameter type.
102      * 
103      * @throws NoSuchMethodException
104      *             if a method can't be found
105      */
106     private Method findMethod(Object target, String name, Class parameterType)
107             throws NoSuchMethodException
108     {
109         Method[] methods = target.getClass().getMethods();
110 
111         for (int i = 0; i < methods.length; i++)
112         {
113             Method m = methods[i];
114             Class[] parameterTypes = m.getParameterTypes();
115 
116             if (parameterTypes.length != 1)
117                 continue;
118 
119             if (!m.getName().equals(name))
120                 continue;
121 
122             if ((parameterType != null && parameterTypes[0].isAssignableFrom(parameterType))
123                     || (parameterType == null && !parameterTypes[0].isPrimitive()))
124                 return m;
125         }
126 
127         throw new NoSuchMethodException(name);
128     }
129 }