gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / library / AbstractLibrary.java @ 655
History | View | Annotate | Download (11.2 KB)
1 | 18 | cordinyana | /* gvSIG. Geographic Information System of the Valencian Government
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2007-2008 Infrastructures and Transports Department
|
||
4 | * of the Valencian Government (CIT)
|
||
5 | *
|
||
6 | * This program is free software; you can redistribute it and/or
|
||
7 | * modify it under the terms of the GNU General Public License
|
||
8 | * as published by the Free Software Foundation; either version 2
|
||
9 | * of the License, or (at your option) any later version.
|
||
10 | *
|
||
11 | * This program is distributed in the hope that it will be useful,
|
||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
14 | * GNU General Public License for more details.
|
||
15 | *
|
||
16 | * You should have received a copy of the GNU General Public License
|
||
17 | * along with this program; if not, write to the Free Software
|
||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
19 | * MA 02110-1301, USA.
|
||
20 | *
|
||
21 | */
|
||
22 | |||
23 | /*
|
||
24 | * AUTHORS (In addition to CIT):
|
||
25 | * 2008 {DiSiD Technologies} {Create a base Locator implementation}
|
||
26 | */
|
||
27 | package org.gvsig.tools.library; |
||
28 | |||
29 | import java.util.HashSet; |
||
30 | 655 | cordinyana | import java.util.Iterator; |
31 | 18 | cordinyana | import java.util.Set; |
32 | |||
33 | import org.slf4j.Logger; |
||
34 | import org.slf4j.LoggerFactory; |
||
35 | |||
36 | /**
|
||
37 | * Base Library implementation, checking that a Library is initialized and
|
||
38 | * postInitialized only once.
|
||
39 | *
|
||
40 | * Also adds initialization logging.
|
||
41 | *
|
||
42 | * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
|
||
43 | * @author jjdelcerro
|
||
44 | */
|
||
45 | public abstract class AbstractLibrary implements Library { |
||
46 | |||
47 | 607 | cordinyana | private static Set initialized = new HashSet(); |
48 | private static Set postInitialized = new HashSet(); |
||
49 | 479 | cordinyana | |
50 | 607 | cordinyana | private static final int DEFAULT_PRIORITY = 0; |
51 | 479 | cordinyana | |
52 | 607 | cordinyana | private Set requireds = null; |
53 | private Class library; |
||
54 | private String type; |
||
55 | private int priority = DEFAULT_PRIORITY; |
||
56 | 479 | cordinyana | |
57 | 607 | cordinyana | /**
|
58 | * Association between a library class and its type.
|
||
59 | *
|
||
60 | * @author gvSIG team
|
||
61 | */
|
||
62 | public static class Required { |
||
63 | 479 | cordinyana | |
64 | 607 | cordinyana | Class library;
|
65 | String type;
|
||
66 | 654 | cordinyana | private boolean added = false; |
67 | 479 | cordinyana | |
68 | 607 | cordinyana | Required(Class library, String type) { |
69 | this.library = library;
|
||
70 | this.type = type;
|
||
71 | } |
||
72 | 479 | cordinyana | |
73 | 607 | cordinyana | public Class getLibrary() { |
74 | return this.library; |
||
75 | } |
||
76 | 479 | cordinyana | |
77 | 607 | cordinyana | public String getType() { |
78 | return this.type; |
||
79 | } |
||
80 | 655 | cordinyana | |
81 | 641 | cordinyana | public String toString() { |
82 | return this.library.toString() + ":" |
||
83 | + (this.type == null ? "UNDEFINED" : this.type.toUpperCase()); |
||
84 | } |
||
85 | 654 | cordinyana | |
86 | /**
|
||
87 | * @return the added
|
||
88 | */
|
||
89 | public boolean isAdded() { |
||
90 | return added;
|
||
91 | } |
||
92 | |||
93 | /**
|
||
94 | * @param added
|
||
95 | * the added to set
|
||
96 | */
|
||
97 | public void setAdded(boolean added) { |
||
98 | this.added = added;
|
||
99 | } |
||
100 | 607 | cordinyana | } |
101 | 358 | cmartin | |
102 | 607 | cordinyana | /**
|
103 | * Empty constructor.
|
||
104 | */
|
||
105 | protected AbstractLibrary() {
|
||
106 | // Nothing to do
|
||
107 | } |
||
108 | 479 | cordinyana | |
109 | 607 | cordinyana | /**
|
110 | * Creates a new library registering with type of library it is: API or
|
||
111 | * implementation of a library.
|
||
112 | * <p>
|
||
113 | * When it is an API library, the class will be itself.
|
||
114 | * </p>
|
||
115 | *
|
||
116 | * @param library
|
||
117 | * the library class we relate to
|
||
118 | * @param type
|
||
119 | * the library type. See {@link TYPE}.
|
||
120 | * @deprecated to be removed in the 4.x version. Use the
|
||
121 | * {@link #AbstractLibrary()} empty constructor and override the
|
||
122 | * {@link #doRegistration()} method instead.
|
||
123 | * @see #AbstractLibrary()
|
||
124 | */
|
||
125 | protected AbstractLibrary(Class library, String type) { |
||
126 | registerAs(library, type); |
||
127 | } |
||
128 | 18 | cordinyana | |
129 | 607 | cordinyana | /**
|
130 | * Creates a new library registering it as an implementation.
|
||
131 | * A priority is also provided just in case there is another
|
||
132 | * implementation available, so the one with the highest priority
|
||
133 | * will be the one used.
|
||
134 | *
|
||
135 | * @param library
|
||
136 | * the library class we relate to
|
||
137 | * @param priority
|
||
138 | * the priority of the library against other implementations
|
||
139 | * of the same library
|
||
140 | * @deprecated to be removed in the 4.x version. Use the
|
||
141 | * {@link #AbstractLibrary()} empty constructor and override the
|
||
142 | * {@link #doRegistration()} method instead.
|
||
143 | * @see #AbstractLibrary()
|
||
144 | */
|
||
145 | protected AbstractLibrary(Class library, int priority) { |
||
146 | registerAsImplementationOf(library, priority); |
||
147 | } |
||
148 | 479 | cordinyana | |
149 | 607 | cordinyana | public Set getRequireds() { |
150 | return this.requireds; |
||
151 | } |
||
152 | 479 | cordinyana | |
153 | 607 | cordinyana | /**
|
154 | * Returns the name of the current Library
|
||
155 | */
|
||
156 | public Class getLibrary() { |
||
157 | return this.library; |
||
158 | } |
||
159 | 479 | cordinyana | |
160 | 607 | cordinyana | public String getType() { |
161 | return this.type; |
||
162 | } |
||
163 | 485 | cordinyana | |
164 | 607 | cordinyana | public int getPriority() { |
165 | return this.priority; |
||
166 | } |
||
167 | 188 | jjdelcerro | |
168 | 607 | cordinyana | /**
|
169 | * Adds a required library, so it is initialized before the current one.
|
||
170 | *
|
||
171 | * @param library
|
||
172 | * the required library
|
||
173 | * @param type
|
||
174 | * the type of the required library
|
||
175 | * @deprecated use the {@link #require(Class)} method instead, as you may
|
||
176 | * have problems if the type specified is not correct. Moreover,
|
||
177 | * this is not needed.
|
||
178 | */
|
||
179 | public synchronized final void require(Class library, String type) { |
||
180 | doRequire(library, type); |
||
181 | } |
||
182 | 479 | cordinyana | |
183 | 607 | cordinyana | /**
|
184 | * Adds a required library, so it is initialized before the current one.
|
||
185 | *
|
||
186 | * @param library
|
||
187 | * the required library
|
||
188 | */
|
||
189 | public synchronized final void require(Class library) { |
||
190 | 641 | cordinyana | doRequire(library, null);
|
191 | 607 | cordinyana | } |
192 | 485 | cordinyana | |
193 | 607 | cordinyana | private void doRequire(Class library, String type) { |
194 | if (requireds == null) { |
||
195 | this.requireds = new HashSet(); |
||
196 | } |
||
197 | this.requireds.add(new Required(library, type)); |
||
198 | } |
||
199 | 485 | cordinyana | |
200 | 607 | cordinyana | /**
|
201 | * Registers the library with type of library it is: API or
|
||
202 | * implementation of a library.
|
||
203 | * <p>
|
||
204 | * When it is an API library, the class will be itself.
|
||
205 | * </p>
|
||
206 | *
|
||
207 | * @param library
|
||
208 | * the library class we relate to
|
||
209 | * @param type
|
||
210 | * the library type. See {@link TYPE}.
|
||
211 | */
|
||
212 | protected synchronized final void registerAs(Class library, String type) { |
||
213 | this.library = library;
|
||
214 | this.type = type;
|
||
215 | if (this.library != null) { |
||
216 | if (!Library.class.isAssignableFrom(library)) {
|
||
217 | throw new IllegalArgumentException( |
||
218 | "Given class is not a Library: " + library);
|
||
219 | } |
||
220 | // Add default dependencies between services, implementation and API
|
||
221 | if (!Library.TYPE.API.equals(type)) {
|
||
222 | doRequire(this.library, Library.TYPE.API);
|
||
223 | if (Library.TYPE.SERVICE.equals(type)) {
|
||
224 | doRequire(this.library, Library.TYPE.IMPL);
|
||
225 | } |
||
226 | } |
||
227 | } |
||
228 | } |
||
229 | 485 | cordinyana | |
230 | 607 | cordinyana | /**
|
231 | * Registers the library as an API one.
|
||
232 | *
|
||
233 | * @param library
|
||
234 | * the library class we relate to
|
||
235 | */
|
||
236 | protected synchronized final void registerAsAPI(Class library) { |
||
237 | registerAs(library, TYPE.API); |
||
238 | } |
||
239 | 485 | cordinyana | |
240 | 607 | cordinyana | /**
|
241 | * Registers the library as an implementation of an API library, with the
|
||
242 | * default priority.
|
||
243 | *
|
||
244 | * @param library
|
||
245 | * the library class we relate to
|
||
246 | */
|
||
247 | protected synchronized final void registerAsImplementationOf(Class library) { |
||
248 | registerAsImplementationOf(library, DEFAULT_PRIORITY); |
||
249 | } |
||
250 | 485 | cordinyana | |
251 | 607 | cordinyana | /**
|
252 | * Registers the library as an implementation of an API library.
|
||
253 | * A priority is also provided just in case there is another
|
||
254 | * implementation available, so the one with the highest priority
|
||
255 | * will be the one used.
|
||
256 | *
|
||
257 | * @param library
|
||
258 | * the library class we relate to
|
||
259 | * @param priority
|
||
260 | * the priority of the library against other implementations
|
||
261 | * of the same library
|
||
262 | */
|
||
263 | protected synchronized final void registerAsImplementationOf(Class library, |
||
264 | int priority) {
|
||
265 | 18 | cordinyana | |
266 | 607 | cordinyana | registerAs(library, Library.TYPE.IMPL); |
267 | this.priority = priority;
|
||
268 | } |
||
269 | 18 | cordinyana | |
270 | 607 | cordinyana | /**
|
271 | * Registers the library as a service or provider of an API library.
|
||
272 | *
|
||
273 | * @param library
|
||
274 | * the library class we relate to
|
||
275 | */
|
||
276 | protected synchronized final void registerAsServiceOf(Class library) { |
||
277 | registerAs(library, TYPE.SERVICE); |
||
278 | } |
||
279 | 479 | cordinyana | |
280 | 607 | cordinyana | public synchronized final void initialize() throws LibraryException { |
281 | Logger logger = null; |
||
282 | 150 | jjdelcerro | |
283 | 607 | cordinyana | // Check if we have been already initialized
|
284 | String name = getClass().getName();
|
||
285 | if (initialized.contains(name)) {
|
||
286 | return;
|
||
287 | } |
||
288 | 18 | cordinyana | |
289 | 607 | cordinyana | logger = LoggerFactory.getLogger(this.getClass());
|
290 | logger |
||
291 | .info("Initializing library '" + this.getClass().getName() + "'."); |
||
292 | 18 | cordinyana | |
293 | 607 | cordinyana | // Set the current Library as initialized
|
294 | initialized.add(name); |
||
295 | 18 | cordinyana | |
296 | 607 | cordinyana | doInitialize(); |
297 | } |
||
298 | 18 | cordinyana | |
299 | 607 | cordinyana | public synchronized final void postInitialize() throws LibraryException { |
300 | Logger logger = null; |
||
301 | 18 | cordinyana | |
302 | 607 | cordinyana | // Check if we have been already postInitialized
|
303 | String name = getClass().getName();
|
||
304 | if (postInitialized.contains(name)) {
|
||
305 | return;
|
||
306 | } |
||
307 | 18 | cordinyana | |
308 | 607 | cordinyana | logger = LoggerFactory.getLogger(this.getClass());
|
309 | logger.info("PostInitializing library '" + this.getClass().getName() |
||
310 | + "'.");
|
||
311 | doPostInitialize(); |
||
312 | 18 | cordinyana | |
313 | 607 | cordinyana | // Set the current Library as postInitialized
|
314 | postInitialized.add(name); |
||
315 | } |
||
316 | |||
317 | public void doRegistration() { |
||
318 | // Empty implementation so child classes may still use the registration
|
||
319 | // in its constructor
|
||
320 | } |
||
321 | |||
322 | public boolean equals(Object obj) { |
||
323 | return obj != null |
||
324 | && getClass().getName().equals(obj.getClass().getName()); |
||
325 | } |
||
326 | |||
327 | public int hashCode() { |
||
328 | return getClass().getName().hashCode();
|
||
329 | } |
||
330 | |||
331 | public String toString() { |
||
332 | if (getType() == null) { |
||
333 | return getClass().getName();
|
||
334 | } |
||
335 | String relatedLibName =
|
||
336 | library == null ? getClass().getName() : library.getName();
|
||
337 | return getClass().getName() + " (" + getType().toUpperCase() + " of " |
||
338 | + relatedLibName + ")";
|
||
339 | } |
||
340 | |||
341 | 655 | cordinyana | public boolean isRequired(Library lib) { |
342 | return isRequired(lib.getClass());
|
||
343 | } |
||
344 | |||
345 | public boolean isRequired(Class libClass) { |
||
346 | if (requireds != null) { |
||
347 | for (Iterator iterator = requireds.iterator(); iterator.hasNext();) { |
||
348 | Required req = (Required) iterator.next(); |
||
349 | if (libClass.equals(req.getLibrary())) {
|
||
350 | return true; |
||
351 | } |
||
352 | } |
||
353 | } |
||
354 | return false; |
||
355 | } |
||
356 | |||
357 | 607 | cordinyana | /**
|
358 | * Performs all the initializations of the library, only related to himself:
|
||
359 | * register implementation classes through the Locator, start services, etc.
|
||
360 | *
|
||
361 | * @throws LibraryException
|
||
362 | * if there is an error while performing the initialization of
|
||
363 | * the library
|
||
364 | */
|
||
365 | protected abstract void doInitialize() throws LibraryException; |
||
366 | |||
367 | /**
|
||
368 | * Performs all the initializations or validations related to the library
|
||
369 | * dependencies, as getting references to objects through other libraries
|
||
370 | * Locators.
|
||
371 | *
|
||
372 | * @throws LibraryException
|
||
373 | * if there is an error while loading an implementation of the
|
||
374 | * library
|
||
375 | */
|
||
376 | protected abstract void doPostInitialize() throws LibraryException; |
||
377 | |||
378 | } |