01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
03: */
04: package com.tc.config.schema.dynamic;
05:
06: import org.apache.xmlbeans.XmlObject;
07: import org.apache.xmlbeans.impl.common.XPath;
08:
09: import com.tc.config.schema.context.ConfigContext;
10: import com.tc.util.Assert;
11:
12: import java.lang.reflect.InvocationTargetException;
13: import java.lang.reflect.Method;
14: import java.lang.reflect.Modifier;
15:
16: /**
17: * An {@link XPathBasedConfigItem} that returns a {@link String} array. The {@link XPath} should point to the top-level
18: * element (i.e., the one that has child elements that contain nothing but {@link String}s).
19: */
20: public class StringArrayXPathBasedConfigItem extends
21: XPathBasedConfigItem implements StringArrayConfigItem {
22:
23: public StringArrayXPathBasedConfigItem(ConfigContext context,
24: String xpath) {
25: super (context, xpath);
26: }
27:
28: protected Object fetchDataFromXmlObject(XmlObject xmlObject) {
29: if (xmlObject == null)
30: return null;
31:
32: // This is a little tricky; the name of the method that returns String[] can be variable. However, there seems to be
33: // only one such method declared in the class itself, so we can find it by reflection. If this assumption ever
34: // proves to be false, we'll need to re-visit this logic.
35: Method targetMethod = null;
36: Method[] allMethods = xmlObject.getClass().getMethods();
37:
38: for (int i = 0; i < allMethods.length; ++i) {
39: Method candidate = allMethods[i];
40: if (candidate.getReturnType().equals(String[].class)
41: && candidate.getParameterTypes().length == 0
42: && Modifier.isPublic(candidate.getModifiers())
43: && candidate.getName().startsWith("get")
44: && candidate.getName().endsWith("Array")) {
45: if (targetMethod != null) {
46: // formatting
47: throw Assert
48: .failure("Whoa! There are multiple public methods that start with 'get', end with 'Array', take no parameters, "
49: + "and return String[] on class "
50: + xmlObject.getClass().getName()
51: + ". One is "
52: + targetMethod
53: + ", and another is "
54: + candidate
55: + ". We should fix "
56: + "the program to account for this.");
57: }
58:
59: targetMethod = candidate;
60: }
61: }
62:
63: if (targetMethod == null) {
64: // formatting
65: throw Assert
66: .failure("Class "
67: + xmlObject.getClass().getName()
68: + " has no public methods that start with 'get', "
69: + "end with 'Array', take no parameters, and return String[].");
70: }
71:
72: try {
73: return targetMethod.invoke(xmlObject, new Object[0]);
74: } catch (IllegalArgumentException iae) {
75: throw Assert.failure("Couldn't invoke method "
76: + targetMethod + " on object " + xmlObject + ": ",
77: iae);
78: } catch (IllegalAccessException iae) {
79: throw Assert.failure("Couldn't invoke method "
80: + targetMethod + " on object " + xmlObject + ": ",
81: iae);
82: } catch (InvocationTargetException ite) {
83: throw Assert.failure("Couldn't invoke method "
84: + targetMethod + " on object " + xmlObject + ": ",
85: ite);
86: }
87: }
88:
89: public String[] getStringArray() {
90: return (String[]) getObject();
91: }
92:
93: }
|