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 java.util.*;
016
017/**
018 * Builder class for building instances of serializers and parsers.
019 */
020public abstract class ContextBuilder {
021
022   /** Contains all the modifiable settings for the implementation class. */
023   protected final PropertyStoreBuilder psb;
024
025   /**
026    * Constructor.
027    * Default settings.
028    */
029   public ContextBuilder() {
030      this.psb = PropertyStore.create();
031   }
032
033   /**
034    * Constructor.
035    *
036    * @param ps The initial configuration settings for this builder.
037    */
038   public ContextBuilder(PropertyStore ps) {
039      if (ps == null)
040         ps = PropertyStore.DEFAULT;
041      this.psb = ps.builder();
042   }
043
044   /**
045    * Constructor.
046    *
047    * <p>
048    * Used in cases where multiple context builder are sharing the same property store builder.
049    * <br>(e.g. <code>HtlmlDocBuilder</code>)
050    *
051    * @param psb The property store builder to use.
052    */
053   protected ContextBuilder(PropertyStoreBuilder psb) {
054      this.psb = psb;
055   }
056
057   /**
058    * Returns access to the inner property store builder.
059    *
060    * <p>
061    * Used in conjunction with {@link #ContextBuilder(PropertyStoreBuilder)} when builders share property store builders.
062    *
063    * @return The inner property store builder.
064    */
065   protected PropertyStoreBuilder getPropertyStoreBuilder() {
066      return psb;
067   }
068
069   /**
070    * Build the object.
071    *
072    * @return The built object.
073    * Subsequent calls to this method will create new instances.
074    */
075   public abstract Context build();
076
077   /**
078    * Copies the settings from the specified property store into this builder.
079    *
080    * @param copyFrom The factory whose settings are being copied.
081    * @return This object (for method chaining).
082    */
083   public ContextBuilder apply(PropertyStore copyFrom) {
084      this.psb.apply(copyFrom);
085      return this;
086   }
087
088   /**
089    * Build a new instance of the specified object.
090    *
091    * @param c The subclass of {@link Context} to instantiate.
092    * @return A new object using the settings defined in this builder.
093    */
094
095   public <T extends Context> T build(Class<T> c) {
096      return ContextCache.INSTANCE.create(c, getPropertyStore());
097   }
098
099   /**
100    * Returns a read-only snapshot of the current property store on this builder.
101    *
102    * @return A property store object.
103    */
104   public PropertyStore getPropertyStore() {
105      return psb.build();
106   }
107
108   //-----------------------------------------------------------------------------------------------------------------
109   // Properties
110   //-----------------------------------------------------------------------------------------------------------------
111
112   /**
113    * Sets a configuration property on this object.
114    *
115    * @param name The property name.
116    * @param value The property value.
117    * @return This object (for method chaining).
118    * @see PropertyStoreBuilder#set(String, Object)
119    */
120   public ContextBuilder set(String name, Object value) {
121      psb.set(name, value);
122      return this;
123   }
124
125   /**
126    * Sets or adds to a SET or LIST property.
127    *
128    * @param append
129    *    If <jk>true</jk>, the previous value is appended to.  Otherwise, the previous value is replaced.
130    * @param name The property name.
131    * @param value The property value.
132    * @return This object (for method chaining).
133    * @see PropertyStoreBuilder#set(String, Object)
134    */
135   public ContextBuilder set(boolean append, String name, Object value) {
136      if (append)
137         psb.addTo(name, value);
138      else
139         psb.set(name, value);
140      return this;
141   }
142
143   /**
144    * Sets multiple configuration properties on this object.
145    *
146    * @param properties The properties to set on this class.
147    * @return This object (for method chaining).
148    * @see PropertyStoreBuilder#set(java.util.Map)
149    */
150   public ContextBuilder set(Map<String,Object> properties) {
151      psb.set(properties);
152      return this;
153   }
154
155   /**
156    * Adds multiple configuration properties on this object.
157    *
158    * @param properties The properties to set on this class.
159    * @return This object (for method chaining).
160    * @see PropertyStoreBuilder#add(java.util.Map)
161    */
162   public ContextBuilder add(Map<String,Object> properties) {
163      psb.add(properties);
164      return this;
165   }
166
167   /**
168    * Adds a value to a SET or LIST property.
169    *
170    * @param name The property name.
171    * @param value The new value to add to the SET property.
172    * @return This object (for method chaining).
173    * @throws ConfigException If property is not a SET property.
174    */
175   public ContextBuilder addTo(String name, Object value) {
176      psb.addTo(name, value);
177      return this;
178   }
179
180   /**
181    * Adds or overwrites a value to a SET, LIST, or MAP property.
182    *
183    * @param name The property name.
184    * @param key The property value map key.
185    * @param value The property value map value.
186    * @return This object (for method chaining).
187    * @throws ConfigException If property is not a MAP property.
188    */
189   public ContextBuilder addTo(String name, String key, Object value) {
190      psb.addTo(name, key, value);
191      return this;
192   }
193
194   /**
195    * Removes a value from a SET, LIST, or MAP property.
196    *
197    * @param name The property name.
198    * @param value The property value in the SET property.
199    * @return This object (for method chaining).
200    * @throws ConfigException If property is not a SET property.
201    */
202   public ContextBuilder removeFrom(String name, Object value) {
203      psb.removeFrom(name, value);
204      return this;
205   }
206}