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 @ 654

History | View | Annotate | Download (10.7 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.Set;
31

    
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34

    
35
/**
36
 * Base Library implementation, checking that a Library is initialized and
37
 * postInitialized only once.
38
 * 
39
 * Also adds initialization logging.
40
 * 
41
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
42
 * @author jjdelcerro
43
 */
44
public abstract class AbstractLibrary implements Library {
45

    
46
    private static Set initialized = new HashSet();
47
    private static Set postInitialized = new HashSet();
48

    
49
    private static final int DEFAULT_PRIORITY = 0;
50

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

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

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

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

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

    
76
        public String getType() {
77
            return this.type;
78
        }
79
        
80
        public String toString() {
81
            return this.library.toString() + ":"
82
                + (this.type == null ? "UNDEFINED" : this.type.toUpperCase());
83
        }
84

    
85
        /**
86
         * @return the added
87
         */
88
        public boolean isAdded() {
89
            return added;
90
        }
91

    
92
        /**
93
         * @param added
94
         *            the added to set
95
         */
96
        public void setAdded(boolean added) {
97
            this.added = added;
98
        }
99
    }
100

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

    
108
    /**
109
     * Creates a new library registering with type of library it is: API or
110
     * implementation of a library.
111
     * <p>
112
     * When it is an API library, the class will be itself.
113
     * </p>
114
     * 
115
     * @param library
116
     *            the library class we relate to
117
     * @param type
118
     *            the library type. See {@link TYPE}.
119
     * @deprecated to be removed in the 4.x version. Use the
120
     *             {@link #AbstractLibrary()} empty constructor and override the
121
     *             {@link #doRegistration()} method instead.
122
     * @see #AbstractLibrary()
123
     */
124
    protected AbstractLibrary(Class library, String type) {
125
        registerAs(library, type);
126
    }
127

    
128
    /**
129
     * Creates a new library registering it as an implementation.
130
     * A priority is also provided just in case there is another
131
     * implementation available, so the one with the highest priority
132
     * will be the one used.
133
     * 
134
     * @param library
135
     *            the library class we relate to
136
     * @param priority
137
     *            the priority of the library against other implementations
138
     *            of the same library
139
     * @deprecated to be removed in the 4.x version. Use the
140
     *             {@link #AbstractLibrary()} empty constructor and override the
141
     *             {@link #doRegistration()} method instead.
142
     * @see #AbstractLibrary()
143
     */
144
    protected AbstractLibrary(Class library, int priority) {
145
        registerAsImplementationOf(library, priority);
146
    }
147

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

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

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

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

    
167
    /**
168
     * Adds a required library, so it is initialized before the current one.
169
     * 
170
     * @param library
171
     *            the required library
172
     * @param type
173
     *            the type of the required library
174
     * @deprecated use the {@link #require(Class)} method instead, as you may
175
     *             have problems if the type specified is not correct. Moreover,
176
     *             this is not needed.
177
     */
178
    public synchronized final void require(Class library, String type) {
179
        doRequire(library, type);
180
    }
181

    
182
    /**
183
     * Adds a required library, so it is initialized before the current one.
184
     * 
185
     * @param library
186
     *            the required library
187
     */
188
    public synchronized final void require(Class library) {
189
        doRequire(library, null);
190
    }
191

    
192
    private void doRequire(Class library, String type) {
193
        if (requireds == null) {
194
            this.requireds = new HashSet();
195
        }
196
        this.requireds.add(new Required(library, type));
197
    }
198

    
199
    /**
200
     * Registers the library with type of library it is: API or
201
     * implementation of a library.
202
     * <p>
203
     * When it is an API library, the class will be itself.
204
     * </p>
205
     * 
206
     * @param library
207
     *            the library class we relate to
208
     * @param type
209
     *            the library type. See {@link TYPE}.
210
     */
211
    protected synchronized final void registerAs(Class library, String type) {
212
        this.library = library;
213
        this.type = type;
214
        if (this.library != null) {
215
            if (!Library.class.isAssignableFrom(library)) {
216
                throw new IllegalArgumentException(
217
                    "Given class is not a Library: " + library);
218
            }
219
            // Add default dependencies between services, implementation and API
220
            if (!Library.TYPE.API.equals(type)) {
221
                doRequire(this.library, Library.TYPE.API);
222
                if (Library.TYPE.SERVICE.equals(type)) {
223
                    doRequire(this.library, Library.TYPE.IMPL);
224
                }
225
            }
226
        }
227
    }
228

    
229
    /**
230
     * Registers the library as an API one.
231
     * 
232
     * @param library
233
     *            the library class we relate to
234
     */
235
    protected synchronized final void registerAsAPI(Class library) {
236
        registerAs(library, TYPE.API);
237
    }
238

    
239
    /**
240
     * Registers the library as an implementation of an API library, with the
241
     * default priority.
242
     * 
243
     * @param library
244
     *            the library class we relate to
245
     */
246
    protected synchronized final void registerAsImplementationOf(Class library) {
247
        registerAsImplementationOf(library, DEFAULT_PRIORITY);
248
    }
249

    
250
    /**
251
     * Registers the library as an implementation of an API library.
252
     * A priority is also provided just in case there is another
253
     * implementation available, so the one with the highest priority
254
     * will be the one used.
255
     * 
256
     * @param library
257
     *            the library class we relate to
258
     * @param priority
259
     *            the priority of the library against other implementations
260
     *            of the same library
261
     */
262
    protected synchronized final void registerAsImplementationOf(Class library,
263
        int priority) {
264

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

    
269
    /**
270
     * Registers the library as a service or provider of an API library.
271
     * 
272
     * @param library
273
     *            the library class we relate to
274
     */
275
    protected synchronized final void registerAsServiceOf(Class library) {
276
        registerAs(library, TYPE.SERVICE);
277
    }
278

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

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

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

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

    
295
        doInitialize();
296
    }
297

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

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

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

    
312
        // Set the current Library as postInitialized
313
        postInitialized.add(name);
314
    }
315

    
316
    public void doRegistration() {
317
        // Empty implementation so child classes may still use the registration
318
        // in its constructor
319
    }
320

    
321
    public boolean equals(Object obj) {
322
        return obj != null
323
            && getClass().getName().equals(obj.getClass().getName());
324
    }
325

    
326
    public int hashCode() {
327
        return getClass().getName().hashCode();
328
    }
329

    
330
    public String toString() {
331
        if (getType() == null) {
332
            return getClass().getName();
333
        }
334
        String relatedLibName =
335
            library == null ? getClass().getName() : library.getName();
336
        return getClass().getName() + " (" + getType().toUpperCase() + " of "
337
            + relatedLibName + ")";
338
    }
339

    
340
    /**
341
     * Performs all the initializations of the library, only related to himself:
342
     * register implementation classes through the Locator, start services, etc.
343
     * 
344
     * @throws LibraryException
345
     *             if there is an error while performing the initialization of
346
     *             the library
347
     */
348
    protected abstract void doInitialize() throws LibraryException;
349

    
350
    /**
351
     * Performs all the initializations or validations related to the library
352
     * dependencies, as getting references to objects through other libraries
353
     * Locators.
354
     * 
355
     * @throws LibraryException
356
     *             if there is an error while loading an implementation of the
357
     *             library
358
     */
359
    protected abstract void doPostInitialize() throws LibraryException;
360

    
361
}