001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.transform; 014 015/** 016 * Bean interceptor. 017 * 018 * <p> 019 * Bean interceptors intercept calls to bean getters and setters to allow them to override values in transit. 020 * 021 * <h5 class='section'>Example:</h5> 022 * <p class='bcode w800'> 023 * <jc>// Interceptor that strips out sensitive information on Address beans.</jc> 024 * <jk>public class</jk> AddressInterceptor <jk>extends</jk> BeanInterceptor<Address> { 025 * 026 * <ja>@Override</ja> 027 * <jk>public</jk> Object readProperty(Address bean, String name, Object value) { 028 * <jk>if</jk> (<js>"taxInfo"</js>.equals(name)) 029 * <jk>return</jk> <js>"redacted"</js>; 030 * <jk>return</jk> value; 031 * } 032 * 033 * <ja>@Override</ja> 034 * <jk>public</jk> Object writeProperty(Address bean, String name, Object value) { 035 * <jk>if</jk> (<js>"taxInfo"</js>.equals(name) && <js>"redacted"</js>.equals(value)) 036 * <jk>return</jk> TaxInfoUtils.<jsm>lookup</jsm>(bean.getStreet(), bean.getCity(), bean.getState()); 037 * <jk>return</jk> value; 038 * } 039 * } 040 * </p> 041 * 042 * <p> 043 * Bean interceptors are registered in the following way: 044 * <ul class='javatree'> 045 * <li class='ja'>{@link org.apache.juneau.annotation.Bean#interceptor() @Bean(interceptor)} 046 * <li class='jm'>{@link org.apache.juneau.BeanContextBuilder#beanInterceptor(Class,Class)} 047 * </ul> 048 * 049 * <h5 class='section'>Example:</h5> 050 * <p class='bcode w800'> 051 * <jc>// Register interceptor on bean class.</jc> 052 * <ja>@Bean</ja>(interceptor=AddressInterceptor.<jk>class</jk>) 053 * <jk>public class</jk> Address { 054 * <jk>public</jk> String getTaxInfo() {...} 055 * <jk>public void</jk> setTaxInfo(String s) {...} 056 * } 057 * </p> 058 * @param <T> The bean type. 059 */ 060public class BeanInterceptor<T> { 061 062 /** Default interceptor */ 063 public static class Default extends BeanInterceptor<Object> {} 064 065 /** 066 * Default reusable property filter instance. 067 */ 068 public static final BeanInterceptor<Object> DEFAULT = new Default(); 069 070 /** 071 * Property read interceptor. 072 * 073 * <p> 074 * Subclasses can override this property to convert property values to some other object just before serialization. 075 * 076 * <h5 class='section'>Example:</h5> 077 * <p class='bcode w800'> 078 * <jc>// Address filter that strips out sensitive information.</jc> 079 * <jk>public class</jk> AddressInterceptor <jk>extends</jk> BeanInterceptor<Address> { 080 * 081 * <jk>public</jk> Object readProperty(Address bean, String name, Object value) { 082 * <jk>if</jk> (<js>"taxInfo"</js>.equals(name)) 083 * <jk>return</jk> <js>"redacted"</js>; 084 * <jk>return</jk> value; 085 * } 086 * } 087 * </p> 088 * 089 * @param bean The bean from which the property was read. 090 * @param name The property name. 091 * @param value The value just extracted from calling the bean getter. 092 * @return The value to serialize. Default is just to return the existing value. 093 */ 094 public Object readProperty(T bean, String name, Object value) { 095 return value; 096 } 097 098 /** 099 * Property write interceptor. 100 * 101 * <p> 102 * Subclasses can override this property to convert property values to some other object just before calling the 103 * bean setter. 104 * 105 * <h5 class='section'>Example:</h5> 106 * <p class='bcode w800'> 107 * <jc>// Address filter that strips out sensitive information.</jc> 108 * <jk>public class</jk> AddressInterceptor <jk>extends</jk> BeanInterceptor<Address> { 109 * 110 * <jk>public</jk> Object writeProperty(Address bean, String name, Object value) { 111 * <jk>if</jk> (<js>"taxInfo"</js>.equals(name) && <js>"redacted"</js>.equals(value)) 112 * <jk>return</jk> TaxInfoUtils.<jsm>lookup</jsm>(bean.getStreet(), bean.getCity(), bean.getState()); 113 * <jk>return</jk> value; 114 * } 115 * } 116 * </p> 117 * 118 * @param bean The bean from which the property was read. 119 * @param name The property name. 120 * @param value The value just parsed. 121 * @return The value to serialize. Default is just to return the existing value. 122 */ 123 public Object writeProperty(T bean, String name, Object value) { 124 return value; 125 } 126}