001/* 002 * JKNIV, utils - Helper utilities for jdk code. 003 * 004 * Copyright (C) 2017, the original author or authors. 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software Foundation, Inc., 018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 019 */ 020package net.sf.jkniv.reflect.beans; 021 022import java.lang.reflect.Field; 023import java.lang.reflect.Method; 024import java.util.Map; 025 026import net.sf.jkniv.exception.HandleableException; 027import net.sf.jkniv.exception.HandlerException; 028import net.sf.jkniv.reflect.ReflectionException; 029 030/** 031 * 032 * @author Alisson Gomes 033 * @since 0.6.0 034 */ 035public class PropertyAccess 036{ 037 private static final Capitalize CAPITAL_SETTER = CapitalNameFactory.getInstanceOfSetter(); 038 private static final Capitalize CAPITAL_GETTER = CapitalNameFactory.getInstanceOfGetter(); 039 040 private String fieldName; 041 private String writerMethodName; 042 private String readMethodName; 043 private Class<?> targetClass; 044 private boolean nestedField; 045 private Field field; 046 private Method writerMethod; 047 private Method readMethod; 048 049 public PropertyAccess(String fieldName) 050 { 051 this(fieldName, null); 052 } 053 054 public PropertyAccess(String fieldName, String readMethodName, String writerMethodName) 055 { 056 this.fieldName = fieldName; 057 this.readMethodName = readMethodName; 058 this.writerMethodName = writerMethodName; 059 } 060 061 public PropertyAccess(String fieldName, Class<?> targetClass) 062 { 063 this.fieldName = fieldName; 064 int index = fieldName.lastIndexOf("."); 065 if (index > 0) 066 { 067 this.nestedField = true; 068 this.writerMethodName = CAPITAL_SETTER.does(fieldName.substring(index+1)); 069 this.readMethodName = CAPITAL_GETTER.does(fieldName.substring(index+1)); 070 } 071 else 072 { 073 this.writerMethodName = CAPITAL_SETTER.does(fieldName); 074 this.readMethodName = CAPITAL_GETTER.does(fieldName); 075 } 076 resolve(targetClass); 077 } 078 079 public String getFieldName() 080 { 081 return this.fieldName; 082 } 083 084 public Field getField() 085 { 086 return this.field; 087 } 088 089 public Method getWriterMethod() 090 { 091 return this.writerMethod; 092 } 093 094 public Method getReadMethod() 095 { 096 return this.readMethod; 097 } 098 099 public String getWriterMethodName() 100 { 101 return writerMethodName; 102 } 103 104 public String getReadMethodName() 105 { 106 return readMethodName; 107 } 108 109 public Class<?> getTargetClass() 110 { 111 return this.targetClass; 112 } 113 114 private void setTargetClass(Class<?> targetClass) 115 { 116 if (this.targetClass != null) 117 throw new ReflectionException("Cannot re-define a new target class for PropertyAccess"); 118 119 this.targetClass = targetClass; 120 } 121 122 public boolean isNestedField() 123 { 124 return nestedField; 125 } 126 127 public boolean hasField() 128 { 129 return (this.field != null); 130 } 131 132 public boolean hasReadMethod() 133 { 134 return (this.readMethod != null); 135 } 136 137 public boolean hasWriterMethod() 138 { 139 return (this.writerMethod != null); 140 } 141 142 public void resolve(Class<?> targetClass) 143 { 144 setTargetClass(targetClass); 145 if (targetClass != null && 146 !Map.class.isAssignableFrom(targetClass)) 147 { 148 HandleableException handle = new HandlerException(); 149 handle.mute(NoSuchMethodException.class) 150 .mute(NoSuchFieldException.class) 151 .logInfoOff(); 152 153 ObjectProxy<?> proxy = ObjectProxyFactory.of(this.targetClass); 154 proxy.with(handle); 155 this.field = proxy.getDeclaredField(this.fieldName); 156 this.readMethod = new MethodReflect(handle).getMethod(this.fieldName, this.targetClass); 157 this.writerMethod = new MethodReflect(handle).getMethod(this.fieldName, this.targetClass, CapitalNameFactory.getInstanceOfSetter()); 158 } 159 } 160 161 @Override 162 public String toString() 163 { 164 return "PropertyAccess [fieldName=" + fieldName + ", readMethod=" + readMethod + ", writerMethod=" 165 + writerMethod + ", targetClass=" + targetClass + "]"; 166 } 167 168}