001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.woody.datatype.convertor;
018:
019: import java.lang.reflect.Field;
020: import java.lang.reflect.Method;
021: import java.lang.reflect.Modifier;
022: import java.util.Locale;
023:
024: import org.apache.avalon.framework.CascadingRuntimeException;
025:
026: /**
027: * A {@link org.apache.cocoon.woody.datatype.convertor.Convertor Convertor}
028: * implementation for types implementing Joshua Bloch's
029: * <a href="http://developer.java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums">
030: * typesafe enum</a> pattern.
031: *
032: * @see org.apache.cocoon.woody.datatype.typeimpl.EnumType
033: * @version CVS $Id: EnumConvertor.java 433543 2006-08-22 06:22:54Z crossley $
034: */
035: public class EnumConvertor implements Convertor {
036:
037: private Class clazz;
038:
039: /**
040: * Construct a new EnumConvertor for a class
041: * @param className The package-qualified name of the class implementing
042: * the typesafe enum pattern.
043: */
044: public EnumConvertor(String className) {
045: try {
046: clazz = Class.forName(className);
047: } catch (ClassNotFoundException e) {
048: throw new CascadingRuntimeException("Class " + className
049: + " not found", e);
050: }
051: }
052:
053: /* (non-Javadoc)
054: * @see org.apache.cocoon.woody.datatype.convertor.Convertor#convertFromString(java.lang.String, java.util.Locale, org.apache.cocoon.woody.datatype.convertor.Convertor.FormatCache)
055: */
056: public Object convertFromString(String value, Locale locale,
057: FormatCache formatCache) {
058: try {
059: // If the enum provides a "fromString" method, use it
060: try {
061: Method method = getTypeClass().getMethod("fromString",
062: new Class[] { String.class, Locale.class });
063: return method.invoke(null,
064: new Object[] { value, locale });
065: } catch (NoSuchMethodException nsme) {
066: // fromString method was not found, try to convert
067: // the value to a field via reflection.
068: // Strip the class name
069: int pos = value.lastIndexOf('.');
070: if (pos >= 0) {
071: value = value.substring(pos + 1);
072: }
073: Class clazz = getTypeClass();
074: Field field = clazz.getField(value);
075: return field.get(null);
076: }
077: } catch (Exception e) {
078: throw new CascadingRuntimeException(
079: "Got exception trying to convert " + value, e);
080: }
081: }
082:
083: /* (non-Javadoc)
084: * @see org.apache.cocoon.woody.datatype.convertor.Convertor#convertToString(java.lang.Object, java.util.Locale, org.apache.cocoon.woody.datatype.convertor.Convertor.FormatCache)
085: */
086: public String convertToString(Object value, Locale locale,
087: FormatCache formatCache) {
088: Class clazz = getTypeClass();
089: Field fields[] = clazz.getDeclaredFields();
090: for (int i = 0; i < fields.length; ++i) {
091: try {
092: int mods = fields[i].getModifiers();
093: if (Modifier.isPublic(mods) && Modifier.isStatic(mods)
094: && Modifier.isFinal(mods)
095: && fields[i].get(null).equals(value)) {
096: return clazz.getName() + "." + fields[i].getName();
097: }
098: } catch (Exception e) {
099: throw new CascadingRuntimeException(
100: "Got exception trying to get value of field "
101: + fields[i], e);
102: }
103: }
104: // Fall back on toString
105: return value.toString();
106: }
107:
108: /* (non-Javadoc)
109: * @see org.apache.cocoon.woody.datatype.convertor.Convertor#getTypeClass()
110: */
111: public Class getTypeClass() {
112: return clazz;
113: }
114: }
|