View Javadoc

1   package org.xmlfield.core;
2   
3   import java.util.Map;
4   
5   /**
6    * Factory used to create XmlField instances.
7    * <p>
8    * This factory is thread safe and can be configured to use ThreadLocal to reuse
9    * XmlField instances for performance reasons.
10   * <p>
11   * When using ThreadLocal, configuration ( parserConfiguration and getter cache)
12   * is unique (static) across all XmlFieldFactory instances.
13   * 
14   * 
15   * @see CleanThreadLocalFilter
16   * 
17   * @author Nicolas Richeton
18   * 
19   */
20  public class XmlFieldFactory {
21  
22  	private static Boolean staticGetterCache = null;
23  	private static Map<String, String> staticParserConfiguration = null;
24  	/**
25  	 * XmlFiled instances associated to threads. Used only if useThreadLocal is
26  	 * true.
27  	 */
28  	private static final ThreadLocal<XmlField> xmlFieldInstances = new ThreadLocal<XmlField>() {
29  		@Override
30  		protected XmlField initialValue() {
31  			XmlField xf = new XmlField(staticParserConfiguration);
32  			if (staticGetterCache != null) {
33  				xf.setGetterCache(staticGetterCache);
34  			}
35  			return xf;
36  		}
37  	};
38  
39  	private Boolean getterCache = null;
40  	private Map<String, String> parserConfiguration = null;
41  
42  	private final boolean useThreadLocal;
43  
44  	public XmlFieldFactory() {
45  		this(false);
46  	}
47  
48  	/**
49  	 * @param useThreadLocal
50  	 *            When enabled, the factory will create only one XmlField object
51  	 *            per thread and reuse it each time {@link #getXmlField()} is
52  	 *            called.
53  	 *            <p>
54  	 *            This improves performance if {@link #getXmlField()} is called
55  	 *            several times in the same thread. But it is still better to
56  	 *            keep the XmlField object and reuse it because it it not
57  	 *            subject to synchronization.
58  	 * 
59  	 *            <p>
60  	 *            When used in a web application, it is recommended to use a
61  	 *            servlet filter which clears the context after each call to
62  	 *            prevent leaks in application servers.
63  	 * 
64  	 * @see CleanThreadLocalFilter
65  	 */
66  	public XmlFieldFactory(boolean useThreadLocal) {
67  		this.useThreadLocal = useThreadLocal;
68  	}
69  
70  	/**
71  	 * Clean the XmlField instance of the current thread.
72  	 */
73  	public void cleanThreadLocal() {
74  		if (useThreadLocal) {
75  			xmlFieldInstances.remove();
76  		}
77  	}
78  
79  	/**
80  	 * Get a new XmlField instance, or the instance associated with the current
81  	 * thread if {@link #setUseThreadLocal(boolean)} is enabled.
82  	 * 
83  	 * @return
84  	 */
85  	public XmlField getXmlField() {
86  		if (useThreadLocal) {
87  			return xmlFieldInstances.get();
88  		}
89  
90  		XmlField xf = new XmlField(parserConfiguration);
91  		if (getterCache != null) {
92  			xf.setGetterCache(getterCache);
93  		}
94  
95  		return xf;
96  	}
97  
98  	/**
99  	 * Enable Getter cache.
100 	 * 
101 	 * @see XmlField#setGetterCache(boolean)
102 	 * @param enabled
103 	 */
104 	public void setGetterCache(boolean enabled) {
105 		if (useThreadLocal) {
106 			staticGetterCache = enabled;
107 		} else {
108 			this.getterCache = enabled;
109 		}
110 	}
111 
112 	/**
113 	 * Set parser configuration. All XmlField instances will use this
114 	 * configuration.
115 	 * 
116 	 * @param configuration
117 	 */
118 	public void setParserConfiguration(Map<String, String> configuration) {
119 		if (useThreadLocal) {
120 			staticParserConfiguration = configuration;
121 		} else {
122 			parserConfiguration = configuration;
123 		}
124 	}
125 
126 }