Source code: net/jxta/ext/config/AbstractConfigurator.java
1 /*
2 * Copyright (c) 2001 Sun Microsystems, Inc. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or withouta
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following discalimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The end-user documentation included with the redistribution,
18 * if any, must include the following acknowledgment:
19 * "This product includes software developed by the
20 * Sun Microsystems, Inc. for Project JXTA."dres
21 * Alternately, this acknowledgment may appear in the software itself,
22 * if and wherever such third-party acknowledgments normally appear.
23 *
24 * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
25 * must not be used to endorse or promote products derived from this
26 * software without prior written permission. For written
27 * permission, please contact Project JXTA at http://www.jxta.org.
28 *
29 * 5. Products derived from this software may not be called "JXTA",
30 * nor may "JXTA" appear in their name, without prior written
31 * permission of Sun.
32 *
33 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
37 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
40 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 * ====================================================================
46 *
47 * This software consists of voluntary contributions made by many
48 * individuals on behalf of Project JXTA. For more
49 * information on Project JXTA, please see
50 * <http://www.jxta.org/>.
51 *
52 * This license is based on the BSD license adopted by the Apache Foundation.
53 *
54 * $Id: AbstractConfigurator.java,v 1.1 2004/11/30 22:42:09 gonzo Exp $
55 */
56
57 package net.jxta.ext.config;
58
59 import net.jxta.exception.ConfiguratorException;
60 import net.jxta.protocol.ConfigParams;
61
62 import net.jxta.impl.peergroup.PlatformConfigurator;
63 import net.jxta.impl.protocol.PlatformConfig;
64
65 import java.io.BufferedOutputStream;
66 import java.io.File;
67 import java.io.FileOutputStream;
68 import java.io.InputStream;
69 import java.io.IOException;
70 import java.net.URI;
71
72 import java.util.Collections;
73 import java.util.Iterator;
74 import java.util.HashMap;
75 import java.util.Map;
76
77 import org.apache.log4j.Level;
78 import org.apache.log4j.Logger;
79
80
81 /**
82 * An abstract <code>PlatformConfigurator</code> implementation that provides
83 * application callbacks for <code>PlatformConfig</code> generation and
84 * update prior to Platform startup. The default backing configurator is
85 * <code>ext:config Configurator</code> that is overridable via a constructor.
86 *
87 * Applications can register their implementation with the Platform in addition
88 * to adding application specific resources that will be copied to the
89 * JXTA_HOME prior to startup.
90 *
91 * @author james todd [gonzo at jxta dot org]
92 * @version $Id: AbstractConfigurator.java,v 1.1 2004/11/30 22:42:09 gonzo Exp $
93 * @created 2004.11.14
94 */
95
96 public abstract class AbstractConfigurator
97 implements PlatformConfigurator {
98
99 /**
100 * ext:config profile resource name.
101 */
102
103 public static final String PROFILE_KEY = "profile.xml";
104
105 /**
106 * jxta.properties resource name.
107 */
108
109 public static final String JXTA_PROPERTIES_KEY = "jxta.properties";
110
111 private static final String DEFAULT_PROFILE =
112 "/net/jxta/ext/config/resources/edge.xml";
113 private static final String DEFAULT_JXTA_PROPERTIES = "/jxta.properties";
114 private static final Logger LOG =
115 Logger.getLogger(AbstractConfigurator.class.getName());
116
117 private static final Map resources = new HashMap();
118
119 static class ConfiguratorWrapper {
120 static PlatformConfigurator configurator = new Configurator();
121 }
122
123 static {
124 resources.put(PROFILE_KEY, DEFAULT_PROFILE);
125 resources.put(JXTA_PROPERTIES_KEY, DEFAULT_JXTA_PROPERTIES);
126 }
127
128 /**
129 * Registers a delgate <code>Configurator</code> class with the Platform
130 * that will manage configuration resources.
131 *
132 * @param configurator
133 */
134
135 public static void register(Class configurator) {
136 Configurator.setConfigurator(configurator);
137 }
138
139 /**
140 * Resource key iterator.
141 *
142 * note: not thread safe
143 *
144 * @deprecated resource management will be moved to instance members.
145 * @return resource keys
146 */
147
148 public static Iterator getResourceKeys() {
149 return resources.keySet().iterator();
150 }
151
152 /**
153 * Resource accessor.
154 *
155 * @deprecated resource management will be moved to instance members.
156 * @param key resource key
157 * @return resource value
158 */
159
160 public static String getResource(String key) {
161 return (String)resources.get(key);
162 }
163
164 /**
165 * Resource setter.
166 *
167 * @deprecated resource management will be moved to instance members.
168 * @param key resource key
169 * @param value resource value
170 * @return previous keyed value or null
171 */
172
173 public static String addResource(String key, String value) {
174 if (key == null ||
175 value == null) {
176 throw new IllegalArgumentException("invalid key|value");
177 }
178
179 return (String)resources.put(key, value);
180 }
181
182 /**
183 * Resource setter.
184 *
185 * @deprecated resource management will be moved to instance members.
186 * @param resources resource map
187 */
188
189 public static void addResources(Map resources) {
190 if (resources == null) {
191 throw new IllegalArgumentException("invalid resources");
192 }
193
194 resources.putAll(resources);
195 }
196
197 /**
198 * Resource remover.
199 *
200 * @deprecated resource management will be moved to instance members.
201 * @param key resource key
202 * @return resource value
203 */
204
205 public static String removeResource(String key) {
206 return (String)resources.remove(key);
207 }
208
209 /**
210 * Resource clearer.
211 *
212 * @deprecated resource management will be moved to instance members.
213 */
214
215 public static Map clearResources() {
216 Map r = new HashMap(resources);
217
218 resources.clear();
219
220 return r;
221 }
222
223 /**
224 * Constructor which overrides the backing <code>Configurator</code>.
225 *
226 * @param configurator configurator delegate
227 */
228
229 public AbstractConfigurator(PlatformConfigurator configurator) {
230 if (configurator == null) {
231 throw new IllegalArgumentException("null configurator");
232 }
233
234 ConfiguratorWrapper.configurator = configurator;
235 }
236
237 /**
238 * Application callback invoked upon registered <code>Configurators</code>
239 * prior to Platform startup when a newly created
240 * <code>PlatformConfig</config> is required.
241 *
242 * A <code>ConfiguratorException</code> will be thrown in the event the
243 * manufactured <code>PlatformConfig</code> is invalid.
244 *
245 * @param configurator delegate Configurator
246 * @return PlatformConfig generated PlatformConfig
247 */
248
249 public abstract PlatformConfig createPlatformConfig(PlatformConfigurator configurator)
250 throws ConfiguratorException;
251
252 /**
253 * Application callback invoked upon registered <code>Configurators</code>
254 * prior to Platform startup.
255 *
256 * A <code>ConfiguratorException</code> will be thrown in the event the
257 * manufactured <code>PlatformConfig</code> is invalid.
258 *
259 * @param configurator delegate Configurator
260 * @return PlatformConfig updated PlatformConfig
261 */
262
263 public PlatformConfig updatePlatformConfig(PlatformConfigurator configurator)
264 throws ConfiguratorException {
265 if (configurator == null) {
266 throw new ConfiguratorException("null configurator");
267 }
268
269 return configurator.getPlatformConfig();
270 }
271
272 /**
273 * {@inheritDoc}
274 */
275
276 public URI getJXTAHome() {
277 return ConfiguratorWrapper.configurator.getJXTAHome();
278 }
279
280 /**
281 * {@inheritDoc}
282 */
283
284 public PlatformConfig getPlatformConfig()
285 throws ConfiguratorException {
286 manageResources();
287
288 PlatformConfigurator configurator = ConfiguratorWrapper.configurator;
289 File cf = new File(getJXTAHomeFile(), Env.PLATFORM_CONFIG);
290 PlatformConfig pc = null;
291
292 try {
293 pc = configurator.load(cf);
294 } catch (ConfiguratorException ce) {
295 if (LOG.isEnabledFor(Level.INFO)) {
296 LOG.info("invalid platform config: " +
297 (cf != null ? cf.getAbsoluteFile() : null), ce);
298 }
299 }
300
301 if (pc == null) {
302 try {
303 pc = createPlatformConfig(configurator);
304 } catch (ConfiguratorException ce) {
305 if (LOG.isEnabledFor(Level.INFO)) {
306 LOG.info("invalid PlatformConfig creation", ce);
307 }
308
309 throw ce;
310 }
311 }
312
313 configurator.setPlatformConfig(pc);
314
315 try {
316 pc = updatePlatformConfig(configurator);
317 } catch (ConfiguratorException ce) {
318 if (LOG.isEnabledFor(Level.INFO)) {
319 LOG.info("invalid PlatformConfig update", ce);
320 }
321
322 throw ce;
323 }
324
325 try {
326 configurator.save(cf);
327 } catch (ConfiguratorException ce) {
328 if (LOG.isEnabledFor(Level.INFO)) {
329 LOG.info("unable to persist PlatformConfig: " +
330 (cf != null ? cf.toString() : null), ce);
331 }
332
333 throw ce;
334 }
335
336 return pc;
337 }
338
339 /**
340 * {@inheritDoc}
341 */
342
343 public void setPlatformConfig(PlatformConfig config) {
344 ConfiguratorWrapper.configurator.setPlatformConfig(config);
345 }
346
347 /**
348 * {@inheritDoc}
349 */
350
351 public ConfigParams getConfigParams()
352 throws ConfiguratorException {
353 return ConfiguratorWrapper.configurator.getConfigParams();
354 }
355
356 /**
357 * {@inheritDoc}
358 */
359
360 public void setConfigParams(ConfigParams cp) {
361 setPlatformConfig((PlatformConfig)cp);
362 }
363
364 /**
365 * {@inheritDoc}
366 */
367
368 public void setReconfigure(boolean reconfigure) {
369 ConfiguratorWrapper.configurator.setReconfigure(reconfigure);
370 }
371
372 /**
373 * {@inheritDoc}
374 */
375
376 public ConfigParams load()
377 throws ConfiguratorException {
378 return ConfiguratorWrapper.configurator.load();
379 }
380
381 /**
382 * {@inheritDoc}
383 */
384 public PlatformConfig load(File pc)
385 throws ConfiguratorException {
386 return ConfiguratorWrapper.configurator.load(pc);
387 }
388
389 /**
390 * {@inheritDoc}
391 */
392 public boolean isReconfigure() {
393 return ConfiguratorWrapper.configurator.isReconfigure();
394 }
395
396 /**
397 * {@inheritDoc}
398 */
399 public boolean save()
400 throws ConfiguratorException {
401 return ConfiguratorWrapper.configurator.save();
402 }
403
404 /**
405 * {@inheritDoc}
406 */
407 public boolean save(File f)
408 throws ConfiguratorException {
409 return ConfiguratorWrapper.configurator.save(f);
410 }
411
412 private void manageResources() {
413 for (Iterator r = getResourceKeys(); r.hasNext(); ) {
414 String key = (String)r.next();
415 String value = (String)getResource(key);
416 File f = new File(getJXTAHomeFile(), key);
417
418 if (! f.exists()) {
419 InputStream is = getClass().getResourceAsStream(value);
420
421 if (is != null) {
422 BufferedOutputStream bos = null;
423
424 try {
425 f.createNewFile();
426
427 bos = new BufferedOutputStream(new FileOutputStream(f));
428
429 int c = -1;
430
431 while ((c = is.read()) > -1) {
432 bos.write(c);
433 }
434
435 bos.flush();
436 } catch (IOException ioe) {
437 if (LOG.isEnabledFor(Level.ERROR)) {
438 LOG.error("can't persist resource: " + f.getName(), ioe);
439 }
440 } finally {
441 if (is != null) {
442 try {
443 is.close();
444 } catch (IOException ioe) {}
445 }
446
447 if (bos != null) {
448 try {
449 bos.close();
450 } catch (IOException ioe) {}
451 }
452 }
453 }
454 }
455 }
456 }
457
458 // xxx: assume file home for now
459 private File getJXTAHomeFile() {
460 return new File(getJXTAHome());
461 }
462 }