001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of 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, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.common.xmap; 023 024import java.lang.reflect.InvocationTargetException; 025import java.lang.reflect.Method; 026 027/** 028 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 029 */ 030public class XMethodAccessor implements XAccessor { 031 032 private final Method setter; 033 034 private final Class klass; 035 036 Method getter; 037 038 public XMethodAccessor(Method method, Class klass) { 039 setter = method; 040 setter.setAccessible(true); 041 // 042 this.klass = klass; 043 } 044 045 public Class getType() { 046 return setter.getParameterTypes()[0]; 047 } 048 049 public void setValue(Object instance, Object value) { 050 try { 051 setter.invoke(instance, value); 052 } catch (IllegalAccessException e) { 053 throw new IllegalArgumentException(e); 054 } catch (InvocationTargetException e) { 055 if (e.getCause() instanceof RuntimeException) { 056 throw (RuntimeException) e.getCause(); 057 } 058 throw new IllegalArgumentException(e); 059 } 060 } 061 062 @Override 063 public String toString() { 064 return "XMethodSetter {method: " + setter + '}'; 065 } 066 067 public Object getValue(Object instance) { 068 // lazy initialization for getter to keep the compatibility 069 // with current xmap definition 070 if (getter == null) { 071 getter = findGetter(klass); 072 } 073 if (getter != null) { 074 try { 075 return getter.invoke(instance); 076 } catch (IllegalAccessException e) { 077 throw new IllegalArgumentException(e); 078 } catch (InvocationTargetException e) { 079 if (e.getCause() instanceof RuntimeException) { 080 throw (RuntimeException) e.getCause(); 081 } 082 throw new IllegalArgumentException(e); 083 } 084 } 085 return null; 086 } 087 088 private Method findGetter(Class klass) { 089 String setterName = setter.getName(); 090 if (setterName.toLowerCase().startsWith("set")) { 091 String suffix = setterName.substring(3); 092 String prefix = null; 093 094 Class<?>[] classes = setter.getParameterTypes(); 095 Class<?> clazz = classes[0]; 096 // compute the getter name 097 if (clazz == Boolean.class || clazz == Boolean.TYPE) { 098 prefix = "is"; 099 } else { 100 prefix = "get"; 101 } 102 String getterName = prefix + suffix; 103 try { 104 return klass.getMethod(getterName, new Class[0]); 105 } catch (SecurityException e) { 106 throw new IllegalArgumentException(e); 107 } catch (NoSuchMethodException e) { 108 throw new IllegalArgumentException("there is NO getter defined for annotated setter: " + setterName, e); 109 } 110 } 111 return null; 112 } 113 114}