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.annotation;
014
015import static org.apache.juneau.BeanContext.*;
016import static org.apache.juneau.BeanTraverseContext.*;
017
018import java.util.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.http.*;
022import org.apache.juneau.marshall.*;
023import org.apache.juneau.parser.*;
024import org.apache.juneau.reflect.*;
025import org.apache.juneau.svl.*;
026
027/**
028 * Applies {@link BeanConfig} annotations to a {@link PropertyStoreBuilder}.
029 */
030public class BeanConfigApply extends ConfigApply<BeanConfig> {
031
032   /**
033    * Constructor.
034    *
035    * @param c The annotation class.
036    * @param r The resolver for resolving values in annotations.
037    */
038   public BeanConfigApply(Class<BeanConfig> c, VarResolverSession r) {
039      super(c, r);
040   }
041
042   @SuppressWarnings("deprecation")
043   @Override
044   public void apply(AnnotationInfo<BeanConfig> ai, PropertyStoreBuilder psb) {
045      BeanConfig a = ai.getAnnotation();
046
047      for (CS e : a.excludeProperties())
048         psb.putTo(BEAN_bpx, e.k().getName(), string(e.v()));
049      for (CS e : a.includeProperties())
050         psb.putTo(BEAN_bpi, e.k().getName(), string(e.v()));
051      if (a.beanDictionary().length != 0)
052         psb.prependTo(BEAN_beanDictionary, a.beanDictionary());
053      if (a.beanDictionary_replace().length != 0)
054         psb.set(BEAN_beanDictionary, a.beanDictionary_replace());
055      if (a.beanDictionary_remove().length != 0)
056         psb.removeFrom(BEAN_beanDictionary, a.beanDictionary_remove());
057
058      if (! a.beanClassVisibility().isEmpty())
059         psb.set(BEAN_beanClassVisibility, visibility(a.beanClassVisibility(), "beanClassVisibility"));
060      if (! a.beanConstructorVisibility().isEmpty())
061         psb.set(BEAN_beanConstructorVisibility, visibility(a.beanConstructorVisibility(), "beanConstructorVisibility"));
062      if (a.dictionary().length != 0)
063         psb.prependTo(BEAN_beanDictionary, a.dictionary());
064      if (a.dictionary_replace().length != 0)
065         psb.set(BEAN_beanDictionary, a.dictionary_replace());
066      if (a.dictionary_remove().length != 0)
067         psb.removeFrom(BEAN_beanDictionary, a.dictionary_remove());
068      if (! a.beanFieldVisibility().isEmpty())
069         psb.set(BEAN_beanFieldVisibility, visibility(a.beanFieldVisibility(), "beanFieldVisibility"));
070      if (a.beanFilters().length != 0)
071         psb.prependTo(BEAN_beanFilters, a.beanFilters());
072      if (a.beanFilters_replace().length != 0)
073         psb.prependTo(BEAN_beanFilters, a.beanFilters_replace());
074      if (a.beanFilters_remove().length != 0)
075         psb.removeFrom(BEAN_beanFilters, a.beanFilters_remove());
076      if (! a.beanMapPutReturnsOldValue().isEmpty())
077         psb.set(BEAN_beanMapPutReturnsOldValue, bool(a.beanMapPutReturnsOldValue()));
078      if (! a.beanMethodVisibility().isEmpty())
079         psb.set(BEAN_beanMethodVisibility, visibility(a.beanMethodVisibility(), "beanMethodVisibility"));
080      if (! a.beansRequireDefaultConstructor().isEmpty())
081         psb.set(BEAN_beansRequireDefaultConstructor, bool(a.beansRequireDefaultConstructor()));
082      if (! a.beansRequireSerializable().isEmpty())
083         psb.set(BEAN_beansRequireSerializable, bool(a.beansRequireSerializable()));
084      if (! a.beansRequireSettersForGetters().isEmpty())
085         psb.set(BEAN_beansRequireSettersForGetters, bool(a.beansRequireSettersForGetters()));
086      if (! a.beansRequireSomeProperties().isEmpty())
087         psb.set(BEAN_beansRequireSomeProperties, bool(a.beansRequireSomeProperties()));
088      if (! a.typePropertyName().isEmpty())
089         psb.set(BEAN_typePropertyName, string(a.typePropertyName()));
090      if (! a.debug().isEmpty())
091         psb.set(CONTEXT_debug, bool(a.debug()));
092      for (CS e : a.example())
093         psb.putTo(BEAN_examples, e.k().getName(), parse(e.k(), e.v(), "example"));
094      if (a.examples().length > 0)
095         psb.putAllTo(BEAN_examples, omap(a.examples(), "examples"));
096      if (! a.fluentSetters().isEmpty())
097         psb.set(BEAN_fluentSetters, bool(a.fluentSetters()));
098      if (! a.ignoreInvocationExceptionsOnGetters().isEmpty())
099         psb.set(BEAN_ignoreInvocationExceptionsOnGetters, bool(a.ignoreInvocationExceptionsOnGetters()));
100      if (! a.ignoreInvocationExceptionsOnSetters().isEmpty())
101         psb.set(BEAN_ignoreInvocationExceptionsOnSetters, bool(a.ignoreInvocationExceptionsOnSetters()));
102      if (! a.ignorePropertiesWithoutSetters().isEmpty())
103         psb.set(BEAN_ignorePropertiesWithoutSetters, bool(a.ignorePropertiesWithoutSetters()));
104      if (! a.ignoreTransientFields().isEmpty())
105         psb.set(BEAN_ignoreTransientFields, bool(a.ignoreTransientFields()));
106      if (! a.ignoreUnknownBeanProperties().isEmpty())
107         psb.set(BEAN_ignoreUnknownBeanProperties, bool(a.ignoreUnknownBeanProperties()));
108      if (! a.ignoreUnknownNullBeanProperties().isEmpty())
109         psb.set(BEAN_ignoreUnknownNullBeanProperties, bool(a.ignoreUnknownNullBeanProperties()));
110      for (CC e : a.implClasses())
111         psb.putTo(BEAN_implClasses, e.k().getName(), e.v());
112      for (Class<?> c : a.interfaces())
113         psb.prependTo(BEAN_annotations, new BeanAnnotation(c).interfaceClass(c));
114      if (! a.locale().isEmpty())
115         psb.set(CONTEXT_locale, locale(a.locale()));
116      if (! a.mediaType().isEmpty())
117         psb.set(CONTEXT_mediaType, mediaType(a.mediaType()));
118      if (a.notBeanClasses().length != 0)
119         psb.addTo(BEAN_notBeanClasses, a.notBeanClasses());
120      if (a.notBeanClasses_replace().length != 0)
121         psb.set(BEAN_notBeanClasses, a.notBeanClasses_replace());
122      if (a.notBeanClasses_remove().length != 0)
123         psb.removeFrom(BEAN_notBeanClasses, a.notBeanClasses_remove());
124      if (a.notBeanPackages().length != 0)
125         psb.addTo(BEAN_notBeanPackages, strings(a.notBeanPackages()));
126      if (a.notBeanPackages_replace().length != 0)
127         psb.set(BEAN_notBeanPackages, strings(a.notBeanPackages_replace()));
128      if (a.notBeanPackages_remove().length != 0)
129         psb.removeFrom(BEAN_notBeanPackages, strings(a.notBeanPackages_remove()));
130      if (a.pojoSwaps().length != 0)
131         psb.prependTo(BEAN_pojoSwaps, a.pojoSwaps());
132      if (a.pojoSwaps_replace().length != 0)
133         psb.set(BEAN_pojoSwaps, a.pojoSwaps_replace());
134      if (a.pojoSwaps_remove().length != 0)
135         psb.removeFrom(BEAN_pojoSwaps, a.pojoSwaps_remove());
136      if (a.propertyNamer() != PropertyNamer.Null.class)
137         psb.set(BEAN_propertyNamer, a.propertyNamer());
138      if (! a.sortProperties().isEmpty())
139         psb.set(BEAN_sortProperties, bool(a.sortProperties()));
140      if (a.swaps().length != 0)
141         psb.prependTo(BEAN_swaps, a.swaps());
142      if (a.swaps_replace().length != 0)
143         psb.set(BEAN_swaps, a.swaps_replace());
144      if (a.swaps_remove().length != 0)
145         psb.removeFrom(BEAN_swaps, a.swaps_remove());
146      if (! a.timeZone().isEmpty())
147         psb.set(CONTEXT_timeZone, timeZone(a.timeZone()));
148      if (! a.useEnumNames().isEmpty())
149         psb.set(BEAN_useEnumNames, bool(a.useEnumNames()));
150      if (! a.useInterfaceProxies().isEmpty())
151         psb.set(BEAN_useInterfaceProxies, bool(a.useInterfaceProxies()));
152      if (! a.useJavaBeanIntrospector().isEmpty())
153         psb.set(BEAN_useJavaBeanIntrospector, bool(a.useJavaBeanIntrospector()));
154      if (! a.detectRecursions().isEmpty())
155         psb.set(BEANTRAVERSE_detectRecursions, bool(a.detectRecursions()));
156      if (! a.ignoreRecursions().isEmpty())
157         psb.set(BEANTRAVERSE_ignoreRecursions, bool(a.ignoreRecursions()));
158      if (! a.initialDepth().isEmpty())
159         psb.set(BEANTRAVERSE_initialDepth, integer(a.initialDepth(), "initialDepth"));
160      if (! a.maxDepth().isEmpty())
161         psb.set(BEANTRAVERSE_maxDepth, integer(a.maxDepth(), "maxDepth"));
162
163      if (a.applyBean().length > 0)
164         psb.prependTo(BEAN_annotations, a.applyBean());
165      if (a.applyBeanp().length > 0)
166         psb.prependTo(BEAN_annotations, a.applyBeanp());
167      if (a.applyBeanc().length > 0)
168         psb.prependTo(BEAN_annotations, a.applyBeanc());
169      if (a.applyBeanIgnore().length > 0)
170         psb.prependTo(BEAN_annotations, a.applyBeanIgnore());
171      if (a.applyExample().length > 0)
172         psb.prependTo(BEAN_annotations, a.applyExample());
173      if (a.applyNameProperty().length > 0)
174         psb.prependTo(BEAN_annotations, a.applyNameProperty());
175      if (a.applyParentProperty().length > 0)
176         psb.prependTo(BEAN_annotations, a.applyParentProperty());
177      if (a.applyURI().length > 0)
178         psb.prependTo(BEAN_annotations, a.applyURI());
179      if (a.applySwap().length > 0)
180         psb.prependTo(BEAN_annotations, a.applySwap());
181
182      if (a.bpi().length > 0)
183         for (Map.Entry<String,String> e : stringsMap(a.bpi(), "bpi").entrySet())
184            psb.prependTo(BEAN_annotations, new BeanAnnotation(e.getKey()).bpi(e.getValue()));
185      for (CS e : a.bpiMap())
186         psb.prependTo(BEAN_annotations, new BeanAnnotation(e.k().getName()).bpi(e.v()));
187
188      if (a.bpx().length > 0)
189         for (Map.Entry<String,String> e : stringsMap(a.bpx(), "bpx").entrySet())
190            psb.prependTo(BEAN_annotations, new BeanAnnotation(e.getKey()).bpx(e.getValue()));
191      for (CS e : a.bpxMap())
192         psb.prependTo(BEAN_annotations, new BeanAnnotation(e.k().getName()).bpx(e.v()));
193
194      if (a.bpro().length > 0)
195         for (Map.Entry<String,String> e : stringsMap(a.bpro(), "bpro").entrySet())
196            psb.prependTo(BEAN_annotations, new BeanAnnotation(e.getKey()).bpro(e.getValue()));
197      for (CS e : a.bproMap())
198         psb.prependTo(BEAN_annotations, new BeanAnnotation(e.k().getName()).bpro(e.v()));
199
200      if (a.bpwo().length > 0)
201         for (Map.Entry<String,String> e : stringsMap(a.bpwo(), "bpwo").entrySet())
202            psb.prependTo(BEAN_annotations, new BeanAnnotation(e.getKey()).bpwo(e.getValue()));
203      for (CS e : a.bpwoMap())
204         psb.prependTo(BEAN_annotations, new BeanAnnotation(e.k().getName()).bpwo(e.v()));
205   }
206
207
208   private Locale locale(String in) {
209      return Locale.forLanguageTag(string(in));
210   }
211
212   private MediaType mediaType(String in) {
213      return MediaType.of(string(in));
214   }
215
216   private TimeZone timeZone(String in) {
217      return TimeZone.getTimeZone(string(in));
218   }
219
220   private <T> T parse(Class<T> c, String in, String loc) {
221      try {
222         return SimpleJson.DEFAULT.read(string(in), c);
223      } catch (ParseException e) {
224         throw new ConfigException("Invalid syntax for visibility on annotation @BeanConfig({0}): {1}", loc, in);
225      }
226   }
227}