Source code: net/jxta/ext/config/Configurator.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 without
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 disclaimer in
14 * the documentation and/or other materialsset 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."
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: Configurator.java,v 1.188 2005/03/09 04:09:50 gonzo Exp $
55 */
56 package net.jxta.ext.config;
57
58 import net.jxta.ext.config.optimizers.RelayOptimizer;
59 import net.jxta.ext.http.Dispatcher;
60 import net.jxta.ext.http.Message;
61
62 import java.io.Externalizable;
63 import java.io.File;
64 import java.io.FileNotFoundException;
65 import java.io.FileInputStream;
66 import java.io.FileOutputStream;
67 import java.io.FileReader;
68 import java.io.InputStreamReader;
69 import java.io.Reader;
70 import java.io.IOException;
71 import java.io.ObjectInput;
72 import java.io.ObjectOutput;
73 import java.io.StreamTokenizer;
74 import java.io.StringReader;
75 import java.net.MalformedURLException;
76 import java.net.URI;
77 import java.net.URISyntaxException;
78 import java.net.URL;
79 import java.security.cert.Certificate;
80 import java.security.cert.X509Certificate;
81 import java.text.MessageFormat;
82 import java.util.Arrays;
83 import java.util.ArrayList;
84 import java.util.Collections;
85 import java.util.Enumeration;
86 import java.util.HashMap;
87 import java.util.Iterator;
88 import java.util.List;
89 import java.util.Map;
90 import java.util.Map.Entry;
91 import java.util.NoSuchElementException;
92 import net.jxta.document.AdvertisementFactory;
93 import net.jxta.document.Attributable;
94 import net.jxta.document.Attribute;
95 import net.jxta.document.Element;
96 import net.jxta.document.MimeMediaType;
97 import net.jxta.document.StructuredDocument;
98 import net.jxta.document.StructuredDocumentFactory;
99 import net.jxta.document.StructuredDocumentUtils;
100 import net.jxta.document.StructuredTextDocument;
101 import net.jxta.document.TextElement;
102 import net.jxta.document.XMLDocument;
103 import net.jxta.exception.ConfiguratorException;
104 import net.jxta.id.ID;
105 import net.jxta.id.IDFactory;
106 import net.jxta.impl.membership.pse.PSEUtils;
107 import net.jxta.impl.peergroup.PlatformConfigurator;
108 import net.jxta.impl.protocol.HTTPAdv;
109 import net.jxta.impl.protocol.PlatformConfig;
110 import net.jxta.impl.protocol.PSEConfigAdv;
111 import net.jxta.impl.protocol.RdvConfigAdv;
112 import net.jxta.impl.protocol.RelayConfigAdv;
113 import net.jxta.impl.protocol.TCPAdv;
114 import net.jxta.protocol.ConfigParams;
115 import net.jxta.peer.PeerID;
116 import net.jxta.peergroup.PeerGroupFactory;
117 import net.jxta.protocol.TransportAdvertisement;
118 import org.apache.log4j.Level;
119 import org.apache.log4j.Logger;
120
121 /**
122 * A JXTA configurator.<br>
123 * <br>
124 * <code>Configurator<code> serves primarily as a JXTA property sheet and
125 * implements very little attribute association logic beyond that of what
126 * is required to perform integrity validation and address expansion. To
127 * the latter, All addresses are of the form URI. Addresses that do not
128 * specify a scheme will default accordingly. Further, <code>RendezVous</code>
129 * and <code>Relay</code> addresses that do not specify a host wil be replaced
130 * with the corresponding boostrap results. If a scheme is specified only
131 * bootstrap results with matching schemes will be maintained. All other
132 * addresses that do not specify a host will, in turn, be replaced with the
133 * local host. All fields have backing defaults enabling one to seed a
134 * configuration with a partial yet valid resource file.<br>
135 * <br>
136 * Configurator will parse an existing {@link Env#PLATFORM PlatformConfig} if
137 * one exists in the specified {@link Env#JXTA_HOME JXTA home} directory. If
138 * this is not the case, a {@link Env#PROFILE Configuration} file will be
139 * parsed it one such file exists. Lastly, if neither of the above are
140 * resolvable the {@link ResourceConfiguration.Profile#Default Default profile}
141 * will be used to seed the newly created instance.<br>
142 * <br>
143 * Resulting <code>PlatformConfig</code> instances can then be retrieved or
144 * persisted upon passing the integrity validation checks.
145 *
146 * @author james todd [gonzo at jxta dot org]
147 * @version $Id: Configurator.java,v 1.188 2005/03/09 04:09:50 gonzo Exp $
148 * @created November 13, 2003
149 */
150
151 public class Configurator
152 implements Externalizable, PlatformConfigurator {
153
154 private final static String COLON = ":";
155 private final static String EMPTY_STRING = "";
156 private final static int MILLISECONDS_PER_SECOND = 1000;
157 private final static char NULL_CHAR = '\0';
158 private final static long MAX_WAIT = 7 * 1000;
159
160 private final static Logger LOG = Logger.getLogger(Configurator.class.getName());
161
162 private static File HOME = Env.JXTA_HOME;
163
164 private String descriptor = Default.PEER_DESCRIPTOR;
165 private String peerName = null;
166 private String peerDescription = null;
167 private Trace trace = Trace.DEFAULT;
168 private PeerID peerId = null;
169 private boolean isSecurity = Default.SECURITY_IS_ENABLED;
170 private String principal = null;
171 private String password = null;
172 private URI rootCertificateAddress = null;
173 private PSEConfigAdv pse = null;
174 private URI peerProxy = null;
175 private URI rendezVousBootstrap = Default.RENDEZVOUS_BOOTSTRAP_ADDRESS;
176 private URI relaysBootstrap = Default.RELAYS_BOOTSTRAP_ADDRESS;
177 private boolean isRelaysDiscovery = Default.RELAYS_DISCOVERY_IS_ENABLED;
178 private URI reflectionBootstrap = Default.REFLECTION_BOOTSTRAP_ADDRESS;
179 private List transports = null;
180 // private List relays = null;
181 // private boolean isRelayEnabled = Default.RELAY_SERVICE_IS_ENABLED;
182 // private boolean isRelayIncomingEnabled = Default.RELAY_SERVICE_INCOMING_IS_ENABLED;
183 // private int maximumRelayIncoming = Default.INCOMING_MAXIMUM;
184 // private long incomingRelayLease = Default.INCOMING_LEASE;
185 // private boolean isRelayOutgoingEnabled = Default.RELAY_SERVICE_OUTGOING_IS_ENABLED;
186 // private int maximumRelayOutgoing = Default.OUTGOING_MAXIMUM;
187 // private long relayOutgoingLease = Default.OUTGOING_LEASE;
188 // private int relayQueueSize = Default.RELAY_SERVICE_QUEUE_SIZE;
189 private RelayConfigAdv relayConfig = null;
190 private int endpointQueueSize = Default.ENDPOINT_SERVICE_QUEUE_SIZE;
191 private boolean isProxyEnabled = Default.PROXY_SERVICE_IS_ENABLED;
192 private RdvConfigAdv rdvConfig = null;
193 private List optimizers = null;
194
195 private Map customParams = null;
196
197 {
198 customParams = new HashMap();
199
200 process((PlatformConfig)
201 AdvertisementFactory.newAdvertisement(PlatformConfig.getAdvertisementType()));
202 process(Profile.SEED, true);
203
204 setHome(Env.JXTA_HOME);
205 }
206
207 /**
208 * Gets base JXTA home.
209 *
210 * @return The home value
211 */
212 public static File getHome() {
213 return HOME;
214 }
215
216 /*
217 * Sets base JXTA home.
218 */
219 /**
220 * Sets the home attribute of the Configurator class
221 *
222 * @param home The new home value
223 */
224 public static void setHome(File home) {
225 if (home != null) {
226 HOME = home;
227 }
228 }
229
230 public static void setConfigurator(Class configurator) {
231 IllegalArgumentException rc = null;
232
233 if (configurator != null &&
234 PlatformConfigurator.class.isAssignableFrom(configurator)) {
235 try {
236 PeerGroupFactory.setConfiguratorClass(configurator);
237 } catch (Exception e) {
238 // xxx: needed for 1.4.x
239 //rc = new IllegalArgumentException("invalid configurator", e);
240 rc = new IllegalArgumentException("invalid configurator: " +
241 e.getMessage());
242
243 rc.initCause(e);
244 }
245 } else {
246 rc = new IllegalArgumentException("invalid configurator: " +
247 (configurator != null ? configurator.getName() : null));
248 }
249
250 if (rc != null) {
251 if (LOG.isEnabledFor(Level.ERROR)) {
252 LOG.error("invalid configurator: ", rc);
253 }
254
255 throw rc;
256 }
257 }
258
259 /**
260 * Method to transpose <code>URI</code> into one that represents all local
261 * interfaces.
262 *
263 * @param base The provided address
264 * @return Description of the Return Value
265 * @see Env.ALL_ADDRESSES
266 */
267 public static URI toAllAddresses(URI base) {
268 URI u = null;
269 URI b = base;
270 String a = Env.ALL_ADDRESSES.getHostAddress();
271
272 if (b != null) {
273 try {
274 u = new URI(b.getScheme(), EMPTY_STRING, a, b.getPort(),
275 b.getPath(), b.getPath(), b.getFragment());
276 } catch (URISyntaxException use) {
277 if (LOG.isEnabledFor(Level.ERROR)) {
278 LOG.error("invalid transformation", use);
279 }
280 }
281 } else {
282 try {
283 u = new URI(Default.ANY_TCP_ADDRESS.getScheme(), EMPTY_STRING,
284 a, Default.TCP_PORT, EMPTY_STRING, EMPTY_STRING,
285 EMPTY_STRING);
286 } catch (URISyntaxException use) {
287 if (LOG.isEnabledFor(Level.ERROR)) {
288 LOG.error("invalid transformation", use);
289 }
290 }
291 }
292
293 return u;
294 }
295
296 /**
297 * Constructor for the Configurator object.
298 *
299 * @deprecated It's recommended to use the four params constructor
300 *
301 */
302 public Configurator() {
303 this(null, null, null, null);
304 }
305
306 /**
307 * Constructor for the Configurator object.
308 *
309 * @param name peer name
310 * @param password peer password
311 */
312 public Configurator(String name, String password) {
313 this(name, null, name, password);
314 }
315
316 /**
317 * Constructor for the Configurator object.
318 *
319 * @deprecated It's recommended to use the four param constructor
320 *
321 * @param name peer name
322 * @param principal peer principal
323 * @param password peer password
324 */
325 public Configurator(String name, String principal, String password) {
326 this(name, null, principal, password);
327 }
328
329 /**
330 * Constructor for the Configurator object.<br>
331 * <br>
332 * If a {@link Env#PLATFORM_CONFIG Platform configuration file} is found
333 * residing in the {@link Env#JXTA_HOME JXTA home} directory it is used to
334 * seed this instance. If this fails and a {@link Env#PROFILEProfile} is
335 * found residing in the {@link Env#JXTA_HOME JXTA home} directory, it is,
336 * in turn, used to seed this instance. In the event neither of these
337 * configuration files are found the {@link Default defaults} are
338 * configured accordingly.
339 *
340 * @param name peer name
341 * @param description peer description
342 * @param principal peer principal
343 * @param password peer password
344 * @see net.jxta.impl.protocol.PlatformConfig
345 */
346 public Configurator(String name, String description, String principal,
347 String password) {
348 PlatformConfig pc = null;
349
350 try {
351 pc = (PlatformConfig)load();
352 } catch (ConfiguratorException ce) {
353 LOG.error("bad existing configuration");
354 }
355
356 File cf = new File(getHome(), Env.PROFILE);
357 Profile p = Profile.DEFAULT;
358
359 if (pc == null &&
360 cf.exists()) {
361 try {
362 p = new Profile(cf.toURL());
363 } catch (MalformedURLException mue) {
364 if (LOG.isEnabledFor(Level.ERROR)) {
365 LOG.error("invalid config", mue);
366 }
367 }
368 }
369
370 if (pc != null) {
371 process(pc);
372 } else if (p != null) {
373 process(p);
374 }
375
376 description = (description != null &&
377 description.trim().length() > 0) ?
378 description.trim() : Default.PEER_DESCRIPTION;
379
380 if (name != null &&
381 name.trim().length() > 0) {
382 setName(name);
383 }
384
385 if (description.trim().length() > 0) {
386 setDescription(description);
387 }
388
389 setSecurity(principal, password);
390 setTrace(getTrace());
391 }
392
393 /**
394 * Constructor for the Configurator object.<br>
395 * <br>
396 * If the provided <code>Profile</code> is null the {@link Profile#DDFAULT
397 * default profile} will be used in it's place.
398 *
399 * @param profile profile
400 */
401 public Configurator(Profile profile) {
402 process(profile);
403 }
404
405 /**
406 * Constructor for the Configurator object.<br>
407 * <br>
408 * If the provided <code>PlatformConfig</code> is null a default
409 * PlatformConfig will be used in it's place.
410 *
411 * @param config configuration
412 * @see net.jxta.impl.protocol.PlatformConfig
413 */
414 public Configurator(PlatformConfig config) {
415 process(config);
416 }
417
418 /**
419 * {@inheritDoc}
420 **/
421 public ConfigParams load()
422 throws ConfiguratorException {
423 return load(new File(getHome(), Env.PLATFORM_CONFIG));
424 }
425
426 /**
427 * {@inheritDoc}
428 **/
429 public PlatformConfig load(File loadFile)
430 throws ConfiguratorException {
431 if (LOG.isEnabledFor(Level.DEBUG)) {
432 LOG.debug("Reading Platform Config from : " +
433 loadFile.getAbsolutePath());
434 }
435
436 PlatformConfig pc = null;
437 FileInputStream advStream = null;
438
439 try {
440 advStream = new FileInputStream(loadFile);
441 Reader advReader = new InputStreamReader(advStream, "UTF-8");
442
443 pc = (PlatformConfig)AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8,
444 advReader);
445
446 if (LOG.isEnabledFor(Level.DEBUG)) {
447 LOG.debug("Recovered Platform Config from : " +
448 loadFile.getAbsolutePath());
449 }
450 } catch (FileNotFoundException e) {
451 if (LOG.isEnabledFor(Level.WARN)) {
452 LOG.warn("Platform Config not found : " +
453 loadFile.getAbsolutePath());
454 }
455 } catch (Exception e) {
456 if (LOG.isEnabledFor(Level.WARN)) {
457 LOG.warn("Failed to Recover '" + loadFile.getAbsolutePath() +
458 "' due to : ", e);
459 }
460
461 try {
462 // delete that bad file.
463 loadFile.delete();
464 } catch (Exception ex1) {
465 LOG.fatal("Could not remove bad Configuration file", ex1);
466
467 throw new ConfiguratorException( "Could not remove '" +
468 loadFile.getAbsolutePath() +
469 "'. Remove it by hand before retrying", ex1);
470 }
471
472 throw new ConfiguratorException("Failed to Recover PlatformConfig", e);
473 } finally {
474 try {
475 if (advStream != null) {
476 advStream.close();
477 }
478
479 advStream = null;
480 } catch (Exception ignored) {
481 }
482 }
483
484 return pc;
485 }
486
487 public URI getJXTAHome() {
488 return getHome().toURI();
489 }
490
491 /**
492 * Gets the descriptor.
493 *
494 * @return The descriptor value
495 */
496 public String getDescriptor() {
497 return this.descriptor;
498 }
499
500 /**
501 * Sets the descriptor
502 *
503 * @param descriptor The new descriptor value
504 */
505 public void setDescriptor(String descriptor) {
506 this.descriptor = descriptor;
507 }
508
509 /**
510 * Gets the <code>Peer</code> name.
511 *
512 * @return The peer name
513 */
514 public String getName() {
515 return this.peerName;
516 }
517
518
519 /**
520 * Sets the <code>Peer</code> name.
521 *
522 * @param name the peer name
523 */
524 public void setName(String name) {
525 this.peerName = (name != null && name.trim().length() > 0 ?
526 name.trim() : null);
527 }
528
529 /**
530 * Gets the <code>Peer</code> description.
531 *
532 * @return The peer description
533 */
534 public String getDescription() {
535 return this.peerDescription;
536 }
537
538 /**
539 * Sets the <code>Peer</code> description.
540 *
541 * @param description the peer description
542 */
543 public void setDescription(String description) {
544 this.peerDescription = (description != null &&
545 description.trim().length() > 0 ?
546 description.trim() : null);
547 }
548
549 /**
550 * Gets the <code>Trace</code>.
551 *
552 * @return The Trace
553 */
554 public Trace getTrace() {
555 return this.trace;
556 }
557
558 /**
559 * Sets the <code>Trace</code> level.
560 *
561 * @param trace the Trace
562 */
563 public void setTrace(Trace trace) {
564 if (trace != null) {
565 this.trace = trace;
566 }
567 }
568
569 /**
570 * Gets the <code>PeerID</code>.
571 *
572 * @return The PeerID
573 */
574 public PeerID getPeerId() {
575 return this.peerId;
576 }
577
578 /**
579 * Sets the <code>PeerID</code>.<br>
580 * <br>
581 * Unspecified PeerIDs will be generated by the <code>Platform</code>.
582 *
583 * @param peerId The PeerID
584 */
585 public void setPeerId(PeerID peerId) {
586 this.peerId = peerId;
587 }
588
589 /**
590 * Gets the <code>RendezVous</code> enabler.
591 *
592 * @return The RendezVous enabler
593 */
594 public boolean isRendezVous() {
595 return RdvConfigAdv.RendezVousConfiguration.RENDEZVOUS ==
596 rdvConfig.getConfiguration();
597 }
598
599 /**
600 * Sets the <code>RendezVous</code> enabler.
601 *
602 * @param isEnabled The RendezVous enabler
603 */
604 public void setRendezVous( boolean isEnabled) {
605 rdvConfig.setConfiguration(isEnabled ?
606 RdvConfigAdv.RendezVousConfiguration.RENDEZVOUS :
607 RdvConfigAdv.RendezVousConfiguration.EDGE);
608 }
609
610 /**
611 * Gets the <code>RendezVous</code> addresses.
612 *
613 * @return The RendezVous addresses
614 */
615 public List getRendezVous() {
616 return new ArrayList(Arrays.asList(rdvConfig.getSeedRendezvous()));
617 }
618
619 /**
620 * Sets the <code>RendezVous</code> addresses.<br>
621 * <br>
622 * RendezVous addresses with unspecified host information will be, upon
623 * <code>PlatformConfig</code> generation, be replaced with the associated
624 * bootstrap results. Further, if the scheme is provided.then only matching
625 * boostrap results will be retained.
626 *
627 * @param rendezVous The RendezVous address
628 * @exception ConfiguratorException Description of the Exception
629 */
630 public void setRendezVous(URI rendezVous)
631 throws ConfiguratorException {
632 setRendezVous(Collections.singletonList(rendezVous));
633 }
634
635 /**
636 * Sets the <code>RendezVous</code> addresses.<br>
637 * <br>
638 * RendezVous addresses with unspecified host information will be, upon
639 * <code>PlatformConfig</code> generation, be replaced with the associated
640 * bootstrap results. Further, if the scheme is provided.then only matching
641 * boostrap results will be retained.
642 *
643 * @param rendezVous The RendezVous addresses
644 * @exception ConfiguratorException Description of the Exception
645 */
646 public void setRendezVous(List seed)
647 throws ConfiguratorException {
648 this.rdvConfig.clearSeedRendezvous();
649 addRendezVous(seed);
650 }
651
652 /**
653 * Adds a <code>RendezVous</code> address.<br>
654 * <br>
655 * RendezVous addresses with unspecified host information will be, upon
656 * <code>PlatformConfig</code> generation, be replaced with the associated
657 * bootstrap results. Further, if the scheme is provided.then only matching
658 * boostrap results will be retained.
659 *
660 * @param rendezVous The RendezVous address
661 * @exception ConfiguratorException Description of the Exception
662 */
663 public void addRendezVous(URI seed)
664 throws ConfiguratorException {
665 addRendezVous(Collections.singletonList(seed));
666 }
667
668 /**
669 * Adds <code>RendezVous</code> addresses.<br>
670 * <br>
671 * RendezVous addresses with unspecified host information will be, upon
672 * <code>PlatformConfig</code> generation, be replaced with the associated
673 * bootstrap results. Further, if the scheme is provided.then only matching
674 * boostrap results will be retained.
675 *
676 * @param rendezVous The RendezVous addressses
677 * @exception ConfiguratorException Description of the Exception
678 */
679 public void addRendezVous(List seed)
680 throws ConfiguratorException {
681 for (Iterator r = seed.iterator(); r.hasNext();) {
682 URI u = (URI)r.next();
683
684 if (Util.validateAddress(u, false).trim().length() == 0) {
685 rdvConfig.addSeedRendezvous(u);
686 } else {
687 throw new ConfiguratorException("invalid address: " + u);
688 }
689 }
690 }
691
692 /**
693 * Remove the <code>RendezVous</code> address.
694 *
695 * @param rendezVous The RendezVous address
696 * @return Description of the Return Value
697 */
698 public URI removeRendezVous(URI rendezVous) {
699 return rdvConfig.removeSeedRendezvous(rendezVous) ? rendezVous : null;
700 }
701
702 /**
703 * Remove all <code>RendezVous</code> addresses.
704 */
705 public void clearRendezVous() {
706 rdvConfig.clearSeedRendezvous();
707 }
708
709 /**
710 * Get <code>RendezVousService</code> AutoStart status.
711 *
712 * @return The rendezVousAutoStart value
713 */
714 public boolean isRendezVousAutoStart() {
715 return (rdvConfig.getAutoRendezvousCheckInterval() != 0);
716 }
717
718 /**
719 * Set <code>RendezVousService</code> AutoStart status enabling the
720 * resulting <code>Peer</code> to become a <code>RendezVous</code> if the
721 * ascribed RendezVous are not accessible.
722 *
723 * @deprecated controlled via setting autostart interval.
724 *
725 * @param isAutoStart The new rendezVousAutoStart value
726 */
727 public void setRendezVousAutoStart(boolean isAutoStart) {}
728
729 /**
730 * Gets the <code>RendezVous</code> AutoStart delay in milliseconds.
731 *
732 * @return autoStart
733 */
734 public long getRendezVousAutoStart() {
735 return rdvConfig.getAutoRendezvousCheckInterval();
736 }
737
738 /**
739 * Sets the <code>RendezVous</code> AutoStart delay measured in
740 * milliseconds.
741 *
742 * @param autoStart autoStart delay in milliseconds
743 */
744 public void setRendezVousAutoStart(long autoStart) {
745 rdvConfig.setAutoRendezvousCheckInterval(autoStart);
746 }
747
748 /**
749 * Gets the <code>Relay</code> enabler.
750 *
751 * @return The Relay enabler.
752 */
753 public boolean isRelay() {
754 return this.relayConfig.isClientEnabled() || this.relayConfig.isServerEnabled();
755 }
756
757 /**
758 * Sets the <code>Relay</code> enabler.
759 *
760 * @param isEnabled The Relay enabler.
761 */
762 public void setRelay(boolean isEnabled) {
763 // throw new UnsupportedOperationException( "this doesn't work" );
764 }
765
766 /**
767 * Gets the <code>Relay</code> addresses.
768 *
769 * @return The relays value
770 */
771 public List getRelays() {
772 List allSeeds = Arrays.asList( this.relayConfig.getSeedRelays() );
773 List result = new ArrayList(allSeeds.size());
774
775 Iterator eachSeed = allSeeds.iterator();
776 while( eachSeed.hasNext() ) {
777 try {
778 result.add( new URI( eachSeed.next().toString() ));
779 } catch( URISyntaxException ignored ) {
780 ;
781 }
782 }
783
784 return result;
785 }
786
787 /**
788 * Sets the <code>Relay</code> address.<br>
789 * <br>
790 * Relays addresses with unspecified host information will be, upon
791 * <code>PlatformConfig</code> generation, be replaced with the
792 * associated bootstrap results. Further if the scheme is provided.then
793 * only matching boostrap results will be retained.
794 *
795 * @param relay The Relay address
796 * @exception ConfiguratorException Description of the Exception
797 */
798 public void setRelay(URI relay)
799 throws ConfiguratorException {
800 this.relayConfig.clearSeedRelays();
801 this.relayConfig.addSeedRelay( relay.toString() );
802 }
803
804 /**
805 * Sets the <code>Relay</code> addresses.<br>
806 * <br>
807 * Relays addresses with unspecified host information will be, upon
808 * <code>PlatformConfig</code> generation, be replaced with the
809 * associated bootstrap results. Further, if the scheme is provided
810 * then only matching boostrap results will be retained.
811 *
812 * @param relays The Relay addresses
813 * @exception ConfiguratorException Description of the Exception
814 */
815 public void setRelays(List relays) throws ConfiguratorException {
816 this.relayConfig.clearSeedRelays();
817
818 addRelays(relays);
819 }
820
821 /**
822 * Adds a <code>Relay</code> address.<br>
823 * <br>
824 * Relays addresses with unspecified host information will be, upon
825 * <code>PlatformConfig</code> generation, be replaced with the
826 * associated bootstrap results. Further if the scheme is provided
827 * then only matching boostrap results will be retained.
828 *
829 * @param relay The Relay address.
830 * @exception ConfiguratorException Description of the Exception
831 */
832 public void addRelay(URI relay) throws ConfiguratorException {
833 try {
834 this.relayConfig.addSeedRelay( relay.toString() );
835 } catch( Exception all ) {
836 throw new ConfiguratorException( "Bad relay", all );
837 }
838 }
839
840 /**
841 * Adds <code>Relay</code> addresses.<br>
842 * <br>
843 * Relays addresses with unspecified host information will be, upon
844 * <code>PlatformConfig</code> generation, be replaced with the
845 * associated bootstrap results. Further if the scheme is provided
846 * then only matching boostrap results will be retained.
847 *
848 * @param relays The Relay addresses
849 * @exception ConfiguratorException Description of the Exception
850 */
851 public void addRelays(List relays)
852 throws ConfiguratorException {
853 Iterator eachRelay = relays.iterator();
854 while( eachRelay.hasNext() ) {
855 addRelay( (URI) eachRelay.next() );
856 }
857 }
858
859 /**
860 * Remove the <code>Relay</code> address.
861 *
862 * @param relay The Relay address
863 * @return Description of the Return Value
864 */
865 public URI removeRelay(URI relay) {
866 throw new UnsupportedOperationException( "this doesn't work" );
867 }
868
869 /**
870 * Remove all <code>Relay</code> addresses.
871 */
872 public void clearRelays() {
873 this.relayConfig.clearSeedRelays();
874 }
875
876 /**
877 * Gets the <code>Relay</code> incoming enabler.
878 *
879 * @return The Relay enabler
880 */
881 public boolean isRelayIncoming() {
882 return this.relayConfig.isServerEnabled();
883 }
884
885 /**
886 * Sets the <code>Relay</code> enabler enabling inbound connections.
887 *
888 * @param isEnabled The Relay enabler
889 */
890 public void setRelayIncoming(boolean isEnabled) {
891 this.relayConfig.setServerEnabled( isEnabled );
892 }
893
894 /**
895 * Gets the <code>Relay</code> incoming maximum.
896 *
897 * @return The Relay incoming maximum
898 */
899 public int getRelayIncomingMaximum() {
900 return this.relayConfig.getMaxClients( );
901 }
902
903 /**
904 * Sets the <code>Relay</code> incoming maximum.
905 *
906 * @param maximumIncoming The Relay incoming maximum
907 */
908 public void setRelayIncomingMaximum(int maximumIncoming) {
909 this.relayConfig.setMaxClients( maximumIncoming );
910 }
911
912 /**
913 * Gets the <code>Relay</code> incoming lease measured in milliseconds.
914 *
915 * @return The Relay incoming lease
916 */
917 public long getRelayIncomingLease() {
918 return this.relayConfig.getServerLeaseDuration();
919 }
920
921 /**
922 * Sets the <code>Relay</code> incoming lease measured in milliseconds.
923 *
924 * @param incomingLease The Relay incoming lease
925 */
926 public void setRelayIncomingLease(long incomingLease) {
927 this.relayConfig.setServerLeaseDuration( incomingLease );
928 }
929
930 /**
931 * Gets the <code>Relay</code> outgoing enabler.
932 *
933 * @return The Relay outgoing enabler
934 */
935 public boolean isRelayOutgoing() {
936 return this.relayConfig.isClientEnabled();
937 }
938
939 /**
940 * Sets the <code>Relay</code> outgoing enabler enabling outbound
941 * connnections.
942 *
943 * @param isEnabled The Relay outgoing enabler
944 */
945 public void setRelayOutgoing(boolean isEnabled) {
946 this.relayConfig.setClientEnabled( isEnabled );
947 }
948
949 /**
950 * Gets the <code>Relay</code> outgoing maximum.
951 *
952 * @return The Relay outgoing maximum
953 */
954 public int getRelayOutgoingMaximum() {
955 return this.relayConfig.getMaxRelays();
956 }
957
958 /**
959 * Sets the <code>Relay</code> outgoing maximum.
960 *
961 * @param maximumOutgoing The Relay outgoing maximum
962 */
963 public void setRelayOutgoingMaximum(int maximumOutgoing) {
964 this.relayConfig.setMaxRelays( maximumOutgoing );
965 }
966
967 /**
968 * Gets the <code>Relay</code> outgoing lease measured in milliseconds.
969 *
970 * @return The Relay outgoing lease
971 */
972 public long getRelayOutgoingLease() {
973 return this.relayConfig.getClientLeaseDuration();
974 }
975
976 /**
977 * Sets the <code>Relay</code> outgoing lease measured in milliseconds.
978 *
979 * @param outgoingLease The Relay outgoing lease
980 */
981 public void setRelayOutgoingLease(long outgoingLease) {
982 this.relayConfig.setClientLeaseDuration( outgoingLease );
983 }
984
985 /**
986 * Gets the <code>Relay</code> queue size measured in messages.
987 *
988 * @return The Relay queue size
989 */
990 public int getRelayQueueSize() {
991 return this.relayConfig.getClientMessageQueueSize();
992 }
993
994 /**
995 * Sets the <code>Relay</code> queue size measured in messages.
996 *
997 * @param queueSize The Relay queue size
998 */
999 public void setRelayQueueSize(int queueSize) {
1000 this.relayConfig.setClientMessageQueueSize( queueSize );
1001 }
1002
1003 /**
1004 * Gets the transports attribute of the Configurator object
1005 *
1006 * @return The transports value
1007 */
1008 public List getTransports() {
1009 return this.transports != null ?
1010 (List)((ArrayList)this.transports).clone() :
1011 Collections.EMPTY_LIST;
1012 }
1013
1014 /**
1015 * Sets the transport attribute of the Configurator object
1016 *
1017 * @param transport The new transport value
1018 */
1019 public void setTransport(Transport transport) {
1020 List t = new ArrayList();
1021
1022 t.add(transport);
1023
1024 setTransports(t);
1025 }
1026
1027 /**
1028 * Sets the transports attribute of the Configurator object
1029 *
1030 * @param transports The new transports value
1031 */
1032 public void setTransports(List transports) {
1033 if (this.transports != null) {
1034 this.transports.clear();
1035 }
1036
1037 addTransports(transports);
1038 }
1039
1040 /**
1041 * Adds a feature to the Transport attribute of the Configurator object
1042 *
1043 * @param transport The feature to be added to the Transport attribute
1044 */
1045 public void addTransport(Transport transport) {
1046 List t = new ArrayList();
1047
1048 t.add(transport);
1049
1050 addTransports(t);
1051 }
1052
1053 /**
1054 * Adds a feature to the Transports attribute of the Configurator object
1055 *
1056 * @param transports The feature to be added to the Transports attribute
1057 */
1058 public void addTransports(List transports) {
1059 for (Iterator i = transports != null ?
1060 transports.iterator() : Collections.EMPTY_LIST.iterator();
1061 i.hasNext(); ) {
1062 Transport t = (Transport)i.next();
1063
1064 if (t != null &&
1065 (this.transports == null ||
1066 ! this.transports.contains(t))) {
1067 if (this.transports == null) {
1068 this.transports = new ArrayList();
1069 }
1070
1071 this.transports.add(t);
1072 }
1073 }
1074 }
1075
1076 /**
1077 * Description of the Method
1078 *
1079 * @param transport Description of the Parameter
1080 * @return Description of the Return Value
1081 */
1082 public Transport removeTransport(Transport transport) {
1083 Object o = null;
1084
1085 if (this.transports != null) {
1086 int i = this.transports.indexOf(transport);
1087
1088 if (i > -1) {
1089 o = this.transports.remove(i);
1090
1091 if (this.transports.size() == 0) {
1092 this.transports = null;
1093 }
1094 }
1095 }
1096
1097 return (Transport)o;
1098 }
1099
1100 /**
1101 * Description of the Method
1102 */
1103 public void clearTransports() {
1104 if (this.transports != null) {
1105 this.transports.clear();
1106
1107 this.transports = null;
1108 }
1109 }
1110
1111 /**
1112 * Gets the principal.
1113 *
1114 * @return The principal
1115 */
1116 public String getPrincipal() {
1117 return this.principal;
1118 }
1119
1120 /**
1121 * Gets the security enabler.
1122 *
1123 * @return security enabler
1124 */
1125 public boolean isSecurity() {
1126 return this.isSecurity;
1127 }
1128
1129 /**
1130 * Sets the security enabler.
1131 *
1132 * @param isEnabled The new security value
1133 */
1134 public void setSecurity(boolean isEnabled) {
1135 this.isSecurity = isEnabled;
1136 }
1137
1138 /**
1139 * Sets the principal and associated password.
1140 *
1141 * @param principal The principal
1142 * @param password The password
1143 */
1144 public void setSecurity(String principal, String password) {
1145 this.principal = (principal != null &&
1146 principal.trim().length() > 0 ? principal.trim() : null);
1147 this.password = (password != null &&
1148 password.trim().length() > 0 ? password.trim() : null);
1149 }
1150
1151 /**
1152 * Gets the Root Certificate address.
1153 *
1154 * @return The root certificate address
1155 */
1156 public URI getRootCertificateAddress() {
1157 return this.rootCertificateAddress;
1158 }
1159
1160 /**
1161 * Sets the Root Certificate address.
1162 *
1163 * @param rootCertificateAddress the root certificate address
1164 */
1165 public void setRootCertificateAddress(URI rootCertificateAddress) {
1166 this.rootCertificateAddress = rootCertificateAddress;
1167 }
1168
1169 /**
1170 * Gets the root certificate.
1171 *
1172 * @return The root certificate
1173 */
1174 public Certificate getRootCertificate() {
1175 return this.pse.getCertificate();
1176 }
1177
1178 /**
1179 * Gets the root certificate Base64 encoded.
1180 *
1181 * @return The root certificate
1182 */
1183 public String getRootCertificateBase64() {
1184 String s = null;
1185
1186 try {
1187 s = this.pse.getCert();
1188 } catch (Exception e) {
1189 if (LOG.isEnabledFor(Level.DEBUG)) {
1190 LOG.debug("can't get root cert");
1191 }
1192 }
1193
1194 return s;
1195 }
1196
1197 /**
1198 * Sets the root certificate
1199 *
1200 * @param rootCertificate root certificate
1201 */
1202 public void setRootCertificate(Certificate rootCertificate) {
1203 this.pse.setCertificate((X509Certificate) rootCertificate);
1204 }
1205
1206 /**
1207 * Sets the root certificate
1208 *
1209 * @param rootCertificate Base64 encoded root certificate
1210 */
1211 public void setRootCertificateBase64(String rootCertificate) {
1212 if (rootCertificate != null) {
1213 this.pse.setCert(rootCertificate);
1214 }
1215 }
1216
1217 /**
1218 * Gets the proxy used for configuration.
1219 *
1220 * @return The cofigurator proxy address value
1221 */
1222 public URI getPeerProxyAddress() {
1223 return this.peerProxy;
1224 }
1225
1226 /**
1227 * Sets the proxy used for configuration. If the address scheme is not
1228 * specified the appropriate value will be assigned.
1229 *
1230 * @param peerProxyAddress The new peerProxyAddress value
1231 * @exception ConfiguratorException if the address scheme is not "http" or
1232 * the port is invalid
1233 */
1234 public void setPeerProxyAddress(URI peerProxyAddress)
1235 throws ConfiguratorException {
1236 if (Util.validateAddress(peerProxyAddress, true).trim().length() == 0) {
1237 this.peerProxy = peerProxyAddress;
1238 } else {
1239 throw new ConfiguratorException("invalid proxy",
1240 new IllegalArgumentException("invalid proxy uri: " +
1241 peerProxyAddress));
1242 }
1243 }
1244
1245 /**
1246 * Gets the Endpoint queue size measured in messages
1247 *
1248 * @return The endpointOutgoingQueueSize value
1249 */
1250 public int getEndpointOutgoingQueueSize() {
1251 return this.endpointQueueSize;
1252 }
1253
1254 /**
1255 * Sets the Endpoint queue size measured in messages
1256 *
1257 * @param size The endpoint queue size
1258 */
1259 public void setEndpointOutgoingQueueSize(int size) {
1260 this.endpointQueueSize = size;
1261 }
1262
1263 /**
1264 * Gets the proxy service enabler.
1265 *
1266 * @return The proxy service enabler
1267 */
1268 public boolean isProxy() {
1269 return this.isProxyEnabled;
1270 }
1271
1272 /**
1273 * Sets the proxy service enabler.
1274 *
1275 * @param isEnabled The proxy service enabler
1276 */
1277 public void setProxy(boolean isEnabled) {
1278 this.isProxyEnabled = isEnabled;
1279 }
1280
1281 /**
1282 * Gets the <code>RendezVous</code> bootstrap address.
1283 *
1284 * @return The rendezVousBootstrap value
1285 */
1286 public URI getRendezVousBootstrapAddress() {
1287 //return this.rendezVousBootstrap;
1288 URI[] u = this.rdvConfig.getSeedingURIs();
1289
1290 return (u.length > 0 ? u[0] : null);
1291 }
1292
1293 /**
1294 * Sets the <code>RendezVous</code> bootstrap address that will be used to
1295 * resolve all addresses that do not specify a host.
1296 *
1297 * @param rendezVousBootstrapAddress The new rendezVousBootstrapAddress
1298 * value
1299 * @exception ConfiguratorException Description of the Exception
1300 */
1301 public void setRendezVousBootstrapAddress(URI rendezVousBootstrapAddress)
1302 throws ConfiguratorException {
1303 if (rendezVousBootstrapAddress != null &&
1304 Util.validateAddress(rendezVousBootstrapAddress, -1).trim().length() > 0) {
1305 throw new ConfiguratorException("invalid address: " +
1306 rendezVousBootstrapAddress);
1307 }
1308
1309 //this.rendezVousBootstrap = rendezVousBootstrapAddress;
1310 this.rdvConfig.addSeedingURI(rendezVousBootstrapAddress);
1311 }
1312
1313 /**
1314 * Gets the <code>RendezVous</code> discovery enabler.
1315 *
1316 * @return The rendezVousDiscovery value
1317 */
1318 public boolean isRendezVousDiscovery() {
1319 return !rdvConfig.getUseOnlySeeds();
1320 }
1321
1322 /**
1323 * Sets the <code>RendezVous</code> discovery enabler.
1324 *
1325 * @param isEnabled The new rendezVousDiscovery value
1326 */
1327 public void setRendezVousDiscovery(boolean discover ) {
1328 rdvConfig.setUseOnlySeeds( !discover );
1329 }
1330
1331 /**
1332 * Gets the <code>Relay</code> bootstrap address.
1333 *
1334 * @return The relaysBootstrap value
1335 */
1336 public URI getRelaysBootstrapAddress() {
1337 //return this.relaysBootstrap;
1338 URI[] u = this.relayConfig.getSeedingURIs();
1339
1340 return (u.length > 0 ? u[0] : null);
1341 }
1342
1343 /**
1344 * Sets the <code>Relay</code> bootstrap address that will be used to
1345 * resolve all addresses that do not specify a host.
1346 *
1347 * @param relaysBootstrapAddress The new relaysBootstrapAddress value
1348 * @exception ConfiguratorException Description of the Exception
1349 */
1350 public void setRelaysBootstrapAddress(URI relaysBootstrapAddress)
1351 throws ConfiguratorException {
1352 if (relaysBootstrapAddress != null &&
1353 Util.validateAddress(relaysBootstrapAddress, -1).trim().length() > 0) {
1354 throw new ConfiguratorException("invalid address: " +
1355 relaysBootstrapAddress);
1356 }
1357
1358 //this.relaysBootstrap = relaysBootstrapAddress;
1359 this.relayConfig.addSeedingURI(relaysBootstrapAddress);
1360 }
1361
1362 /**
1363 * Gets the <code>Relay</code> discovery enabler.
1364 *
1365 * @return The relayDiscovery value
1366 */
1367 public boolean isRelaysDiscovery() {
1368 return this.isRelaysDiscovery;
1369 }
1370
1371 /**
1372 * Sets the <code>Relay</code> discovery enabler.
1373 *
1374 * @param isEnabled The new relayDiscovery value
1375 */
1376 public void setRelayDiscovery(boolean isEnabled) {
1377 this.isRelaysDiscovery = isEnabled;
1378 }
1379
1380 /**
1381 * Gets the <code>Relay</code> discovery enabler.
1382 *
1383 * @return The relaysDiscovery value
1384 */
1385 public boolean getRelaysDiscovery() {
1386 return this.isRelaysDiscovery;
1387 }
1388
1389 /**
1390 * Sets the <code>Relays</code> discovery enabler.
1391 *
1392 * @param isEnabled The new relaysDiscovery value
1393 */
1394 public void setRelaysDiscovery(boolean isEnabled) {
1395 this.isRelaysDiscovery = isEnabled;
1396 }
1397
1398 /**
1399 * Gets the <code>Reflection</code> bootstrap address.
1400 *
1401 * @return The reflectionBootstrap value
1402 * @deprecated moved to {@link net.jxta.ext.config.optimizers.RelayOptimizer RelayOptimizer} property
1403 */
1404 public URI getReflectionBootstrapAddress() {
1405 return this.reflectionBootstrap;
1406 }
1407
1408 /**
1409 * Sets the <code>Reflection</code> bootstrap address that is used during
1410 * the optimization process.
1411 *
1412 * @param reflectionBootstrapAddress The new reflectionBootstrapAddress value
1413 * @exception ConfiguratorException Description of the Exception
1414 * @deprecated moved to {@link net.jxta.ext.config.optimizers.RelayOptimizer RelayOptimizer} property
1415 */
1416 public void setReflectionBootstrapAddress(URI reflectionBootstrapAddress)
1417 throws ConfiguratorException {
1418 if (reflectionBootstrapAddress != null &&
1419 Util.validateAddress(reflectionBootstrapAddress, -1).trim().length() > 0) {
1420 throw new ConfiguratorException("invalid address: " +
1421 reflectionBootstrapAddress);
1422 }
1423
1424 this.reflectionBootstrap = reflectionBootstrapAddress;
1425 }
1426
1427 /**
1428 * Gets the <code>PlatformConfig</code> that is comprised of the
1429 * constituent properties. Contingencies include the following integrity
1430 * validation checks:<br>
1431 * <br>
1432 *
1433 * <ul>
1434 * <li> specified Peer name</li>
1435 * <li> valid principal and password</li>
1436 * <li> at least one transport is enabled</li>
1437 * <li> transport host and port is specified</li>
1438 * <li> valid multicast port and size</li>
1439 * <li> for Relays at least one transport is specified</li>
1440 * <li> valid Http proxy, if requiired</li>
1441 * </ul>
1442 *
1443 *
1444 * @return The PlatformConfig
1445 * @exception ConfiguratorException if invalid configuration
1446 */
1447 public PlatformConfig getPlatformConfig()
1448