/* * Copyright 2006 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.dev.util.xml; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Represents metadata about a parameter in a handler method in a class derived * from {@link Schema}. */ public final class HandlerParam { /** * Looks for a field of the form [methodName]_[paramIndex]_[attrName]. */ public static HandlerParam create(Method method, String normalizedTagName, int paramIndex) { Class<?> paramType = method.getParameterTypes()[paramIndex]; Field[] fields = method.getDeclaringClass().getDeclaredFields(); String fieldNamePrefix = normalizedTagName + "_" + (paramIndex + 1); Field matchingField = null; String fieldName = null; for (int i = 0, n = fields.length; i < n; ++i) { Field testField = fields[i]; fieldName = testField.getName(); if (fieldName.startsWith(fieldNamePrefix)) { matchingField = testField; break; } } if (matchingField == null) { throw new IllegalArgumentException("Expecting a meta field with prefix '" + fieldNamePrefix + "'"); } int under = fieldName.indexOf("_", fieldNamePrefix.length()); if (under == -1) { // Not a valid signature. // throw new IllegalArgumentException( "Expecting a normalized attribute name suffix (e.g. \"_attr_name\") on field '" + fieldName + "'"); } // Infer the associated attribute name. // String normalizedAttrName = fieldName.substring(under + 1); // GWT fields values must be of type String. // if (!String.class.equals(matchingField.getType())) { // Type mismatch. // throw new IllegalArgumentException("GWT field '" + fieldName + "' must be of type String"); } // Instantiate one. // matchingField.setAccessible(true); HandlerParam handlerParam = new HandlerParam(paramType, matchingField, normalizedAttrName); return handlerParam; } private final Class<?> paramType; private final Field metaField; private final boolean isOptional; private final String normalizedAttrName; private HandlerParam(Class<?> paramType, Field metaField, String normalizedAttrName) { this.isOptional = normalizedAttrName.endsWith("$"); if (isOptional) { normalizedAttrName = normalizedAttrName.substring(0, normalizedAttrName.length() - 1); } this.paramType = paramType; this.metaField = metaField; this.normalizedAttrName = normalizedAttrName; } /** * Called while parsing to get the default value for an attribute. */ public String getDefaultValue(Schema schema) { Throwable caught = null; try { return (String) metaField.get(schema); } catch (IllegalArgumentException e) { caught = e; } catch (IllegalAccessException e) { caught = e; } throw new IllegalStateException( "Unable to get attribute default value from meta field '" + metaField.getName() + "'", caught); } public String getNormalizedName() { return normalizedAttrName; } public Class<?> getParamType() { return paramType; } public boolean isOptional() { return isOptional; } }