Statistics
| Revision:

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
}