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 015import java.util.*; 016 017import static org.apache.juneau.internal.ClassUtils.*; 018 019import org.apache.juneau.*; 020import org.apache.juneau.annotation.*; 021 022/** 023 * Parent class for all bean filters. 024 * 025 * <p> 026 * Bean filters are used to control aspects of how beans are handled during serialization and parsing. 027 * 028 * <p> 029 * Bean filters are created by {@link BeanFilterBuilder} which is the programmatic equivalent to the {@link Bean @Bean} 030 * annotation. 031 * 032 * <ul class='seealso'> 033 * <li class='link'>{@doc BeanFilters} 034 * </ul> 035 */ 036public final class BeanFilter { 037 038 private final Class<?> beanClass; 039 private final Set<String> bpi, bpx, bpro, bpwo; 040 private final PropertyNamer propertyNamer; 041 private final Class<?> interfaceClass, stopClass; 042 private final boolean sortProperties, fluentSetters; 043 private final String typeName; 044 private final Class<?>[] beanDictionary; 045 @SuppressWarnings("rawtypes") 046 private final BeanInterceptor interceptor; 047 048 /** 049 * Constructor. 050 */ 051 BeanFilter(BeanFilterBuilder<?> builder) { 052 this.beanClass = builder.beanClass; 053 this.typeName = builder.typeName; 054 this.bpi = new LinkedHashSet<>(builder.bpi); 055 this.bpx = new LinkedHashSet<>(builder.bpx); 056 this.bpro = new LinkedHashSet<>(builder.bpro); 057 this.bpwo = new LinkedHashSet<>(builder.bpwo); 058 this.interfaceClass = builder.interfaceClass; 059 this.stopClass = builder.stopClass; 060 this.sortProperties = builder.sortProperties; 061 this.fluentSetters = builder.fluentSetters; 062 this.propertyNamer = castOrCreate(PropertyNamer.class, builder.propertyNamer); 063 this.beanDictionary = 064 builder.dictionary == null 065 ? null 066 : builder.dictionary.toArray(new Class<?>[builder.dictionary.size()]); 067 this.interceptor = 068 builder.interceptor == null 069 ? BeanInterceptor.DEFAULT 070 : castOrCreate(BeanInterceptor.class, builder.interceptor); 071 } 072 073 /** 074 * Static creator. 075 * 076 * @param <T> The class being filtered. 077 * @param c The class being filtered. 078 * @return A new instance of BeanFilterBuilder. 079 */ 080 public static <T> BeanFilterBuilder<T> create(Class<T> c) { 081 return new BeanFilterBuilder<>(c); 082 } 083 084 /** 085 * Returns the bean class that this filter applies to. 086 * 087 * @return The bean class that this filter applies to. 088 */ 089 public Class<?> getBeanClass() { 090 return beanClass; 091 } 092 093 /** 094 * Returns the dictionary name associated with this bean. 095 * 096 * @return The dictionary name associated with this bean, or <jk>null</jk> if no name is defined. 097 */ 098 public String getTypeName() { 099 return typeName; 100 } 101 102 /** 103 * Returns the bean dictionary defined on this bean. 104 * 105 * @return The bean dictionary defined on this bean, or <jk>null</jk> if no bean dictionary is defined. 106 */ 107 public Class<?>[] getBeanDictionary() { 108 return beanDictionary; 109 } 110 111 /** 112 * Returns the set and order of names of properties associated with a bean class. 113 * 114 * @return 115 * The names of the properties associated with a bean class, or and empty set if all bean properties should 116 * be used. 117 */ 118 public Set<String> getBpi() { 119 return bpi; 120 } 121 122 /** 123 * Returns the list of properties to ignore on a bean. 124 * 125 * @return The names of the properties to ignore on a bean, or an empty set to not ignore any properties. 126 */ 127 public Set<String> getBpx() { 128 return bpx; 129 } 130 131 /** 132 * Returns the list of read-only properties on a bean. 133 * 134 * @return The names of the read-only properties on a bean, or an empty set to not have any read-only properties. 135 */ 136 public Set<String> getBpro() { 137 return bpro; 138 } 139 140 /** 141 * Returns the list of write-only properties on a bean. 142 * 143 * @return The names of the write-only properties on a bean, or an empty set to not have any write-only properties. 144 */ 145 public Set<String> getBpwo() { 146 return bpwo; 147 } 148 149 /** 150 * Returns <jk>true</jk> if the properties defined on this bean class should be ordered alphabetically. 151 * 152 * <p> 153 * This method is only used when the {@link #getBpi()} method returns <jk>null</jk>. 154 * Otherwise, the ordering of the properties in the returned value is used. 155 * 156 * @return <jk>true</jk> if bean properties should be sorted. 157 */ 158 public boolean isSortProperties() { 159 return sortProperties; 160 } 161 162 /** 163 * Returns <jk>true</jk> if we should find fluent setters. 164 * 165 * @return <jk>true</jk> if fluent setters should be found. 166 */ 167 public boolean isFluentSetters() { 168 return fluentSetters; 169 } 170 171 /** 172 * Returns the {@link PropertyNamer} associated with the bean to tailor the names of bean properties. 173 * 174 * @return The property namer class, or <jk>null</jk> if no property namer is associated with this bean property. 175 */ 176 public PropertyNamer getPropertyNamer() { 177 return propertyNamer; 178 } 179 180 /** 181 * Returns the interface class associated with this class. 182 * 183 * @return The interface class associated with this class, or <jk>null</jk> if no interface class is associated. 184 */ 185 public Class<?> getInterfaceClass() { 186 return interfaceClass; 187 } 188 189 /** 190 * Returns the stop class associated with this class. 191 * 192 * @return The stop class associated with this class, or <jk>null</jk> if no stop class is associated. 193 */ 194 public Class<?> getStopClass() { 195 return stopClass; 196 } 197 198 /** 199 * Calls the {@link BeanInterceptor#readProperty(Object, String, Object)} method on the registered property filters. 200 * 201 * @param bean The bean from which the property was read. 202 * @param name The property name. 203 * @param value The value just extracted from calling the bean getter. 204 * @return The value to serialize. Default is just to return the existing value. 205 */ 206 @SuppressWarnings("unchecked") 207 public Object readProperty(Object bean, String name, Object value) { 208 return interceptor.readProperty(bean, name, value); 209 } 210 211 /** 212 * Calls the {@link BeanInterceptor#writeProperty(Object, String, Object)} method on the registered property filters. 213 * 214 * @param bean The bean from which the property was read. 215 * @param name The property name. 216 * @param value The value just parsed. 217 * @return The value to serialize. Default is just to return the existing value. 218 */ 219 @SuppressWarnings("unchecked") 220 public Object writeProperty(Object bean, String name, Object value) { 221 return interceptor.writeProperty(bean, name, value); 222 } 223}