@@ -43,17 +43,18 @@ private static class ResourceFilterRegistryEntry {
4343 }
4444 }
4545
46- private static final Map <String , ResourceFilterRegistryEntry > REGISTRY = new HashMap <>() ;
46+ private Map <String , ResourceFilterRegistryEntry > registry ;
4747
48- static {
48+ private ResourceFilterFactory (ClassLoader cl ) {
49+ Map <String , ResourceFilterRegistryEntry > map = new HashMap <>();
4950 // Walk through available provider implementations
50- for (ResourceFilterProvider provider : ServiceLoader .load (ResourceFilterProvider .class )) {
51+ for (ResourceFilterProvider provider : ServiceLoader .load (ResourceFilterProvider .class , cl )) {
5152 Iterator <FilterInfo > filtItr = provider .getAvailableResourceFilters ();
5253 while (filtItr .hasNext ()) {
5354 FilterInfo filtInfo = filtItr .next ();
5455 String id = filtInfo .getId ().toUpperCase (Locale .ROOT );
55- if (!REGISTRY .containsKey (id )) {
56- REGISTRY .put (id , new ResourceFilterRegistryEntry (filtInfo , provider ));
56+ if (!map .containsKey (id )) {
57+ map .put (id , new ResourceFilterRegistryEntry (filtInfo , provider ));
5758 }
5859 }
5960 }
@@ -63,18 +64,50 @@ private static class ResourceFilterRegistryEntry {
6364 while (filtItr .hasNext ()) {
6465 FilterInfo filtInfo = filtItr .next ();
6566 String id = filtInfo .getId ().toUpperCase (Locale .ROOT );
66- if (!REGISTRY .containsKey (id )) {
67- REGISTRY .put (id , new ResourceFilterRegistryEntry (filtInfo , defaultProvider ));
67+ if (!map .containsKey (id )) {
68+ map .put (id , new ResourceFilterRegistryEntry (filtInfo , defaultProvider ));
6869 }
6970 }
71+ registry = Collections .unmodifiableMap (map );
72+ }
73+
74+ private static volatile ResourceFilterFactory DEFAULT_FACTORY = null ;
75+
76+ /**
77+ * Returns the default <code>ResourceFilterFactory</code> instance initialized
78+ * by the current thread's context class loader.
79+ *
80+ * @return The default <code>ResourceFilterFactory</code> instance.
81+ */
82+ public static ResourceFilterFactory getDefaultInstance () {
83+ if (DEFAULT_FACTORY == null ) {
84+ synchronized (ResourceFilterFactory .class ) {
85+ if (DEFAULT_FACTORY == null ) {
86+ DEFAULT_FACTORY = new ResourceFilterFactory (Thread .currentThread ().getContextClassLoader ());
87+ }
88+ }
89+ }
90+ return DEFAULT_FACTORY ;
91+ }
92+
93+ /**
94+ * Returns an instance of <code>ResourceFilterFactory</code> using the specified
95+ * <code>ClassLoader</code> to look up custom {@link ResourceFilterProvider} implementations.
96+ *
97+ * @param cl The <code>ClassLoader</code> used for looking up custom <code>ResourceFilterProvider</code>
98+ * implementations.
99+ * @return A new instance of <code>ResourceFilterFactory</code>.
100+ */
101+ public static ResourceFilterFactory getInstance (ClassLoader cl ) {
102+ return new ResourceFilterFactory (cl );
70103 }
71104
72105 /**
73106 * Returns an unmodifiable view of the set of all available resource filter IDs.
74107 * @return an unmodifiable view of the set of all available resource filter IDs.
75108 */
76- public static Set <String > getAvailableFilterIds () {
77- return Collections .unmodifiableSet (REGISTRY .keySet ());
109+ public Set <String > availableFilterIds () {
110+ return Collections .unmodifiableSet (registry .keySet ());
78111 }
79112
80113 /**
@@ -86,8 +119,8 @@ public static Set<String> getAvailableFilterIds() {
86119 * @return the resource filter information for the specified <code>filterId</code>,
87120 * or <code>null</code> if no matching filter is found.
88121 */
89- public static FilterInfo getFilterInfo (String filterId ) {
90- ResourceFilterRegistryEntry entry = REGISTRY .get (filterId .toUpperCase (Locale .ROOT ));
122+ public FilterInfo filterInfo (String filterId ) {
123+ ResourceFilterRegistryEntry entry = registry .get (filterId .toUpperCase (Locale .ROOT ));
91124 if (entry == null ) {
92125 return null ;
93126 }
@@ -103,8 +136,8 @@ public static FilterInfo getFilterInfo(String filterId) {
103136 * @return an instance of {@link ResourceFilter} for the specified <code>filterId</code>,
104137 * or <code>null</code> if no matching filter is found.
105138 */
106- public static ResourceFilter getResourceFilter (String filterId ) {
107- ResourceFilterRegistryEntry entry = REGISTRY .get (filterId .toUpperCase (Locale .ROOT ));
139+ public ResourceFilter resourceFilter (String filterId ) {
140+ ResourceFilterRegistryEntry entry = registry .get (filterId .toUpperCase (Locale .ROOT ));
108141 if (entry == null || entry .filterInfo .getType () != Type .SINGLE ) {
109142 return null ;
110143 }
@@ -120,11 +153,75 @@ public static ResourceFilter getResourceFilter(String filterId) {
120153 * @return an instance of {@link MultiBundleResourceFilter} for the specified <code>filterId</code>,
121154 * or <code>null</code> if no matching filter is found.
122155 */
123- public static MultiBundleResourceFilter getMultiBundleResourceFilter (String filterId ) {
124- ResourceFilterRegistryEntry entry = REGISTRY .get (filterId .toUpperCase (Locale .ROOT ));
156+ public MultiBundleResourceFilter multiBundleResourceFilter (String filterId ) {
157+ ResourceFilterRegistryEntry entry = registry .get (filterId .toUpperCase (Locale .ROOT ));
125158 if (entry == null || entry .filterInfo .getType () != Type .MULTI ) {
126159 return null ;
127160 }
128161 return entry .provider .getMultiBundleResourceFilter (entry .filterInfo .getId ());
129162 }
163+
164+ //
165+ // Following static methods were introduced in the initial implementation. These methods are
166+ // preserved for backward compatibility support.
167+ //
168+
169+ /**
170+ * Returns an unmodifiable view of the set of all available resource filter IDs by
171+ * the default factory.
172+ * <p>
173+ * This operation is equivalent to <code>getDefaultInstance().availableFilterIds()</code>.
174+ * @return an unmodifiable view of the set of all available resource filter IDs.
175+ */
176+ public static Set <String > getAvailableFilterIds () {
177+ return getDefaultInstance ().availableFilterIds ();
178+ }
179+
180+ /**
181+ * Returns the resource filter information for the specified <code>filterId</code> by
182+ * the default factory.
183+ * <code>filterId</code> is case insensitive. If no matching filter is found, this
184+ * method returns <code>null</code>.
185+ * <p>
186+ * This operation is equivalent to <code>getDefaultInstance().filterInfo(filterId)</code>.
187+ *
188+ * @param filterId The resource filter ID, case insensitive.
189+ * @return the resource filter information for the specified <code>filterId</code>,
190+ * or <code>null</code> if no matching filter is found.
191+ */
192+ public static FilterInfo getFilterInfo (String filterId ) {
193+ return getDefaultInstance ().filterInfo (filterId );
194+ }
195+
196+ /**
197+ * Returns an instance of {@link ResourceFilter} for the specified <code>filterId</code>
198+ * by the default factory.
199+ * <code>filterId</code> is case insensitive. If no matching filter is found, this
200+ * method returns <code>null</code>.
201+ * <p>
202+ * This operation is equivalent to <code>getDefaultInstance().resourceFilter(filterId)</code>.
203+ *
204+ * @param filterId The resource filter ID, case insensitive.
205+ * @return an instance of {@link ResourceFilter} for the specified <code>filterId</code>,
206+ * or <code>null</code> if no matching filter is found.
207+ */
208+ public static ResourceFilter getResourceFilter (String filterId ) {
209+ return getDefaultInstance ().resourceFilter (filterId );
210+ }
211+
212+ /**
213+ * Returns an instance of {@link MultiBundleResourceFilter} for the specified <code>filterId</code>
214+ * by the default factory.
215+ * <code>filterId</code> is case insensitive. If no matching filter is found, this
216+ * method returns <code>null</code>.
217+ * <p>
218+ * This operation is equivalent to <code>getDefaultInstance().multiBundleResourceFilter(filterId)</code>.
219+ *
220+ * @param filterId The resource filter ID, case insensitive.
221+ * @return an instance of {@link MultiBundleResourceFilter} for the specified <code>filterId</code>,
222+ * or <code>null</code> if no matching filter is found.
223+ */
224+ public static MultiBundleResourceFilter getMultiBundleResourceFilter (String filterId ) {
225+ return getDefaultInstance ().multiBundleResourceFilter (filterId );
226+ }
130227}
0 commit comments