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
/* 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
import java.util.Iterator;
31
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
    private static Set initialized = new HashSet();
48
    private static Set postInitialized = new HashSet();
49

    
50
    private static final int DEFAULT_PRIORITY = 0;
51

    
52
    private Set requireds = null;
53
    private Class library;
54
    private String type;
55
    private int priority = DEFAULT_PRIORITY;
56

    
57
    /**
58
     * Association between a library class and its type.
59
     * 
60
     * @author gvSIG team
61
     */
62
    public static class Required {
63

    
64
        Class library;
65
        String type;
66
        private boolean added = false;
67

    
68
        Required(Class library, String type) {
69
            this.library = library;
70
            this.type = type;
71
        }
72

    
73
        public Class getLibrary() {
74
            return this.library;
75
        }
76

    
77
        public String getType() {
78
            return this.type;
79
        }
80

    
81
        public String toString() {
82
            return this.library.toString() + ":"
83
                + (this.type == null ? "UNDEFINED" : this.type.toUpperCase());
84
        }
85

    
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
    }
101

    
102
    /**
103
     * Empty constructor.
104
     */
105
    protected AbstractLibrary() {
106
        // Nothing to do
107
    }
108

    
109
    /**
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

    
129
    /**
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

    
149
    public Set getRequireds() {
150
        return this.requireds;
151
    }
152

    
153
    /**
154
     * Returns the name of the current Library
155
     */
156
    public Class getLibrary() {
157
        return this.library;
158
    }
159

    
160
    public String getType() {
161
        return this.type;
162
    }
163

    
164
    public int getPriority() {
165
        return this.priority;
166
    }
167

    
168
    /**
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

    
183
    /**
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
        doRequire(library, null);
191
    }
192

    
193
    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

    
200
    /**
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

    
230
    /**
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

    
240
    /**
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

    
251
    /**
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

    
266
        registerAs(library, Library.TYPE.IMPL);
267
        this.priority = priority;
268
    }
269

    
270
    /**
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

    
280
    public synchronized final void initialize() throws LibraryException {
281
        Logger logger = null;
282

    
283
        // Check if we have been already initialized
284
        String name = getClass().getName();
285
        if (initialized.contains(name)) {
286
            return;
287
        }
288

    
289
        logger = LoggerFactory.getLogger(this.getClass());
290
        logger
291
            .info("Initializing library '" + this.getClass().getName() + "'.");
292

    
293
        // Set the current Library as initialized
294
        initialized.add(name);
295

    
296
        doInitialize();
297
    }
298

    
299
    public synchronized final void postInitialize() throws LibraryException {
300
        Logger logger = null;
301

    
302
        // Check if we have been already postInitialized
303
        String name = getClass().getName();
304
        if (postInitialized.contains(name)) {
305
            return;
306
        }
307

    
308
        logger = LoggerFactory.getLogger(this.getClass());
309
        logger.info("PostInitializing library '" + this.getClass().getName()
310
            + "'.");
311
        doPostInitialize();
312

    
313
        // 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
    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
    /**
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
}