1 /* 2 * Copyright 2010-2011 Stephen Colebourne 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.joda.convert; 17 18 import java.lang.reflect.InvocationTargetException; 19 import java.lang.reflect.Method; 20 21 /** 22 * Conversion to and from a string using two methods. 23 * <p> 24 * The toString method must meet the following signature:<br /> 25 * {@code String anyName()} on Class T. 26 * <p> 27 * The fromString method must meet the following signature:<br /> 28 * {@code static T anyName(String)} on any class. 29 * <p> 30 * MethodsStringConverter is thread-safe and immutable. 31 * 32 * @param <T> the type of the converter 33 */ 34 final class MethodsStringConverter<T> extends ReflectionStringConverter<T> { 35 36 /** Conversion from a string. */ 37 private final Method fromString; 38 39 /** 40 * Creates an instance using two methods. 41 * @param cls the class this converts for, not null 42 * @param toString the toString method, not null 43 * @param fromString the fromString method, not null 44 * @throws RuntimeException (or subclass) if the method signatures are invalid 45 */ 46 MethodsStringConverter(Class<T> cls, Method toString, Method fromString) { 47 super(cls, toString); 48 if (fromString.getParameterTypes().length != 1) { 49 throw new IllegalStateException("FromString method must have one parameter"); 50 } 51 Class<?> param = fromString.getParameterTypes()[0]; 52 if (param != String.class && param != CharSequence.class) { 53 throw new IllegalStateException("FromString method must take a String or CharSequence"); 54 } 55 if (fromString.getReturnType().isAssignableFrom(cls) == false) { 56 throw new IllegalStateException("FromString method must return specified class or a superclass"); 57 } 58 this.fromString = fromString; 59 } 60 61 //----------------------------------------------------------------------- 62 /** 63 * Converts the {@code String} to an object. 64 * @param cls the class to convert to, not null 65 * @param str the string to convert, not null 66 * @return the converted object, may be null but generally not 67 */ 68 public T convertFromString(Class<? extends T> cls, String str) { 69 try { 70 return cls.cast(fromString.invoke(null, str)); 71 } catch (IllegalAccessException ex) { 72 throw new IllegalStateException("Method is not accessible"); 73 } catch (InvocationTargetException ex) { 74 if (ex.getCause() instanceof RuntimeException) { 75 throw (RuntimeException) ex.getCause(); 76 } 77 throw new RuntimeException(ex.getMessage(), ex.getCause()); 78 } 79 } 80 81 }