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 @Override 046 public Class<?> getType() { 047 return setter.getParameterTypes()[0]; 048 } 049 050 @Override 051 public void setValue(Object instance, Object value) { 052 try { 053 setter.invoke(instance, value); 054 } catch (IllegalAccessException e) { 055 throw new IllegalArgumentException(e); 056 } catch (InvocationTargetException e) { 057 if (e.getCause() instanceof RuntimeException) { 058 throw (RuntimeException) e.getCause(); 059 } 060 throw new IllegalArgumentException(e); 061 } 062 } 063 064 @Override 065 public String toString() { 066 return "XMethodSetter {method: " + setter + '}'; 067 } 068 069 @Override 070 public Object getValue(Object instance) { 071 // lazy initialization for getter to keep the compatibility 072 // with current xmap definition 073 if (getter == null) { 074 getter = findGetter(klass); 075 } 076 if (getter != null) { 077 try { 078 return getter.invoke(instance); 079 } catch (IllegalAccessException e) { 080 throw new IllegalArgumentException(e); 081 } catch (InvocationTargetException e) { 082 if (e.getCause() instanceof RuntimeException) { 083 throw (RuntimeException) e.getCause(); 084 } 085 throw new IllegalArgumentException(e); 086 } 087 } 088 return null; 089 } 090 091 private Method findGetter(Class<?> klass) { 092 String setterName = setter.getName(); 093 if (setterName.toLowerCase().startsWith("set")) { 094 String suffix = setterName.substring(3); 095 String prefix = null; 096 097 Class<?>[] classes = setter.getParameterTypes(); 098 Class<?> clazz = classes[0]; 099 // compute the getter name 100 if (clazz == Boolean.class || clazz == Boolean.TYPE) { 101 prefix = "is"; 102 } else { 103 prefix = "get"; 104 } 105 String getterName = prefix + suffix; 106 try { 107 return klass.getMethod(getterName, new Class[0]); 108 } catch (SecurityException e) { 109 throw new IllegalArgumentException(e); 110 } catch (NoSuchMethodException e) { 111 throw new IllegalArgumentException("there is NO getter defined for annotated setter: " + setterName, e); 112 } 113 } 114 return null; 115 } 116 117}