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;
014
015import static org.apache.juneau.common.internal.StringUtils.*;
016import static org.apache.juneau.internal.ClassUtils.*;
017
018import java.util.*;
019
020import org.apache.juneau.annotation.*;
021
022/**
023 * Parent class for all non-bean filters.
024 *
025 * <p>
026 * Marshalled filters are used to control aspects of how POJOs are handled during serialization and parsing.
027 *
028 * <p>
029 * Marshalled filters are created by {@link Builder} which is the programmatic equivalent to the {@link Marshalled @Marshalled}
030 * annotation.
031 *
032 * <h5 class='section'>See Also:</h5><ul>
033
034 * </ul>
035 */
036public final class MarshalledFilter {
037
038   //-----------------------------------------------------------------------------------------------------------------
039   // Static
040   //-----------------------------------------------------------------------------------------------------------------
041
042   /**
043    * Create a new instance of this POJO filter.
044    *
045    * @param <T> The POJO class being filtered.
046    * @param marshalledClass The POJO class being filtered.
047    * @return A new {@link Builder} object.
048    */
049   public static <T> Builder create(Class<T> marshalledClass) {
050      return new Builder(marshalledClass);
051   }
052
053   //-----------------------------------------------------------------------------------------------------------------
054   // Builder
055   //-----------------------------------------------------------------------------------------------------------------
056
057   /**
058    * Builder class.
059    */
060   public static class Builder {
061
062      Class<?> marshalledClass;
063
064      Class<?> implClass;
065      String example;
066
067      /**
068       * Constructor.
069       *
070       * @param marshalledClass The class that this filter applies to.
071       */
072      protected Builder(Class<?> marshalledClass) {
073         this.marshalledClass = marshalledClass;
074      }
075
076      /**
077       * Applies the information in the specified list of {@link Marshalled @Marshalled} annotations to this filter.
078       *
079       * @param annotations The annotations to apply.
080       * @return This object.
081       */
082      public Builder applyAnnotations(List<Marshalled> annotations) {
083
084         annotations.forEach(x -> {
085            if (isNotVoid(x.implClass()))
086               implClass(x.implClass());
087            if (isNotEmpty(x.example()))
088               example(x.example());
089         });
090         return this;
091      }
092
093      /**
094       * Implementation class.
095       *
096       * @param value The new value for this setting.
097       * @return This object.
098       */
099      public Builder implClass(Class<?> value) {
100         this.implClass = value;
101         return this;
102      }
103
104      /**
105       * POJO example in Simplified JSON format.
106       *
107       * @param value The new value for this annotation.
108       * @return This object.
109       */
110      public Builder example(String value) {
111         this.example = value;
112         return this;
113      }
114
115      /**
116       * Creates a {@link MarshalledFilter} with settings in this builder class.
117       *
118       * @return A new {@link MarshalledFilter} instance.
119       */
120      public MarshalledFilter build() {
121         return new MarshalledFilter(this);
122      }
123   }
124
125   //-----------------------------------------------------------------------------------------------------------------
126   // Instance
127   //-----------------------------------------------------------------------------------------------------------------
128
129   private final Class<?> marshalledClass;
130   private final Class<?> implClass;
131   private final String example;
132
133   /**
134    * Constructor.
135    *
136    * @param builder The builder for this object.
137    */
138   protected MarshalledFilter(Builder builder) {
139      this.marshalledClass = builder.marshalledClass;
140      this.implClass = builder.implClass;
141      this.example = builder.example;
142   }
143
144   /**
145    * Returns the class that this filter applies to.
146    *
147    * @return The class that this filter applies to.
148    */
149   public Class<?> getMarshalledClass() {
150      return marshalledClass;
151   }
152
153   /**
154    * Returns the implementation class associated with this class.
155    *
156    * @return The implementation class associated with this class, or <jk>null</jk> if no implementation class is associated.
157    */
158   public Class<?> getImplClass() {
159      return implClass;
160   }
161
162   /**
163    * Returns the example string with this class.
164    *
165    * @return The example string associated with this class, or <jk>null</jk> if no example string is associated.
166    */
167   public String getExample() {
168      return example;
169   }
170}