001: /*
002: * Copyright 2006 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.util.xml;
017:
018: import java.lang.reflect.Field;
019: import java.lang.reflect.Method;
020:
021: /**
022: * Represents metadata about a parameter in a handler method in a class derived
023: * from {@link Schema}.
024: */
025: public final class HandlerParam {
026:
027: /**
028: * Looks for a field of the form [methodName]_[paramIndex]_[attrName].
029: */
030: public static HandlerParam create(Method method,
031: String normalizedTagName, int paramIndex) {
032: Class paramType = method.getParameterTypes()[paramIndex];
033: Field[] fields = method.getDeclaringClass().getDeclaredFields();
034: String fieldNamePrefix = normalizedTagName + "_"
035: + (paramIndex + 1);
036: Field matchingField = null;
037: String fieldName = null;
038: for (int i = 0, n = fields.length; i < n; ++i) {
039: Field testField = fields[i];
040: fieldName = testField.getName();
041: if (fieldName.startsWith(fieldNamePrefix)) {
042: matchingField = testField;
043: break;
044: }
045: }
046:
047: if (matchingField == null) {
048: throw new IllegalArgumentException(
049: "Expecting a meta field with prefix '"
050: + fieldNamePrefix + "'");
051: }
052:
053: int under = fieldName.indexOf("_", fieldNamePrefix.length());
054: if (under == -1) {
055: // Not a valid signature.
056: //
057: throw new IllegalArgumentException(
058: "Expecting a normalized attribute name suffix (e.g. \"_attr_name\") on field '"
059: + fieldName + "'");
060: }
061:
062: // Infer the associated attribute name.
063: //
064: String normalizedAttrName = fieldName.substring(under + 1);
065:
066: // GWT fields values must be of type String.
067: //
068: if (!String.class.equals(matchingField.getType())) {
069: // Type mismatch.
070: //
071: throw new IllegalArgumentException("GWT field '"
072: + fieldName + "' must be of type String");
073: }
074:
075: // Instantiate one.
076: //
077: matchingField.setAccessible(true);
078: HandlerParam handlerParam = new HandlerParam(paramType,
079: matchingField, normalizedAttrName);
080: return handlerParam;
081: }
082:
083: private final Class paramType;
084:
085: private final Field metaField;
086:
087: private final String normalizedAttrName;
088:
089: private HandlerParam(Class paramType, Field metaField,
090: String normalizedAttrName) {
091: this .paramType = paramType;
092: this .metaField = metaField;
093: this .normalizedAttrName = normalizedAttrName;
094: }
095:
096: /**
097: * Called while parsing to get the default value for an attribute.
098: */
099: public String getDefaultValue(Schema schema) {
100: Throwable caught = null;
101: try {
102: return (String) metaField.get(schema);
103: } catch (IllegalArgumentException e) {
104: caught = e;
105: } catch (IllegalAccessException e) {
106: caught = e;
107: }
108:
109: throw new IllegalStateException(
110: "Unable to get attribute default value from meta field '"
111: + metaField.getName() + "'", caught);
112: }
113:
114: public String getNormalizedName() {
115: return normalizedAttrName;
116: }
117:
118: public Class getParamType() {
119: return paramType;
120: }
121: }
|