001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2007 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.domain;
028:
029: import java.io.BufferedReader;
030: import java.io.FileNotFoundException;
031: import java.io.InputStream;
032: import java.io.InputStreamReader;
033: import java.io.Reader;
034: import java.net.URL;
035: import java.util.ArrayList;
036: import java.util.Collection;
037: import java.util.Collections;
038: import java.util.Enumeration;
039: import java.util.Iterator;
040: import java.util.List;
041: import java.util.Properties;
042: import java.util.Set;
043: import org.cougaar.bootstrap.SystemProperties;
044: import org.cougaar.core.agent.Agent; // inlined
045: import org.cougaar.core.blackboard.Blackboard;
046: import org.cougaar.core.blackboard.DirectiveMessage;
047: import org.cougaar.core.blackboard.EnvelopeTuple;
048: import org.cougaar.core.component.ComponentDescription;
049: import org.cougaar.core.component.ComponentDescriptions;
050: import org.cougaar.core.component.ContainerSupport;
051: import org.cougaar.core.component.ServiceBroker;
052: import org.cougaar.core.component.ServiceProvider;
053: import org.cougaar.core.component.ServiceRevokedListener;
054: import org.cougaar.core.mts.MessageAddress;
055: import org.cougaar.core.node.ComponentInitializerService;
056: import org.cougaar.core.service.AgentIdentificationService;
057: import org.cougaar.core.service.DomainForBlackboardService;
058: import org.cougaar.core.service.DomainService;
059: import org.cougaar.core.service.LoggingService;
060: import org.cougaar.util.ConfigFinder;
061:
062: /**
063: * This component is a container for {@link Domain}s.
064: *
065: * @property org.cougaar.core.load.planning
066: * If enabled, the domain manager will load the planning-specific
067: * PlanningDomain. See bug 2522. Defaults to <em>true</em>.
068: *
069: * @property org.cougaar.core.domain.config.enable
070: * Enable the "-Dorg.cougaar.core.domain.config.filename" option
071: * to read the <i>LDMDomains.ini</i> file. Defaults to <em>true</em>.
072: *
073: * @property org.cougaar.core.domain.config.filename
074: * The domain manager will read the specified ".ini" configuration
075: * file (using the config finder) to load domains. See bug 2977.
076: * Defaults to <i>LDMDomains.ini</i>.
077: */
078: public class DomainManager extends ContainerSupport {
079:
080: private static final boolean READ_CONFIG_FILE = SystemProperties
081: .getBoolean("org.cougaar.core.domain.config.enable", true);
082:
083: private static final String FILENAME = SystemProperties
084: .getProperty("org.cougaar.core.domain.config.filename",
085: "LDMDomains.ini");
086:
087: private static final boolean LOAD_PLANNING = SystemProperties
088: .getBoolean("org.cougaar.core.load.planning", true);
089:
090: private final static String PREFIX = "org.cougaar.domain.";
091: private final static int PREFIXLENGTH = PREFIX.length();
092:
093: /** Insertion point for a DomainManager, defined relative to its parent, Agent. */
094: public static final String INSERTION_POINT = Agent.INSERTION_POINT
095: + ".DomainManager";
096: private final static String CONTAINMENT_POINT = INSERTION_POINT;
097:
098: // set parameter defaults
099: private boolean readConfigFile = READ_CONFIG_FILE;
100: private String filename = FILENAME;
101: private boolean loadPlanning = LOAD_PLANNING;
102:
103: private final Object lock = new Object();
104: private List delayedXPlans = Collections.EMPTY_LIST;
105: private List domains = Collections.EMPTY_LIST;
106: private Blackboard blackboard = null;
107:
108: private MessageAddress self;
109: private AgentIdentificationService agentIdService;
110: private LoggingService loggingService = LoggingService.NULL;
111:
112: private DomainRegistryServiceProvider domainRegistrySP;
113: private XPlanServiceProvider xplanSP;
114: private DomainServiceProvider domainSP;
115: private DomainForBlackboardServiceProvider domainForBlackboardSP;
116:
117: public void setParameter(Object o) {
118: List l = (List) o;
119: for (int i = 0; i < l.size(); i++) {
120: String si = (String) l.get(i);
121: int sep = si.indexOf('=');
122: if (sep <= 0) {
123: throw new IllegalArgumentException(
124: "Expecting a \"name=value\" parameter, not "
125: + si);
126: }
127: String name = si.substring(0, sep).trim();
128: String value = si.substring(sep + 1).trim();
129: if ("load_planning".equals(name)) {
130: loadPlanning = "true".equals(value);
131: } else if ("read_config_file".equals(name)) {
132: readConfigFile = "true".equals(value);
133: } else if ("filename".equals(name)) {
134: filename = value;
135: } else {
136: throw new IllegalArgumentException(
137: "Unknown parameter name: " + name);
138: }
139: }
140: }
141:
142: public void setAgentIdentificationService(
143: AgentIdentificationService ais) {
144: this .agentIdService = ais;
145: if (ais != null) {
146: this .self = ais.getMessageAddress();
147: }
148: }
149:
150: public void load() {
151: ServiceBroker sb = getServiceBroker();
152: ServiceBroker csb = getChildServiceBroker();
153:
154: LoggingService ls = (LoggingService) sb.getService(this ,
155: LoggingService.class, null);
156: if (ls != null) {
157: loggingService = ls;
158: }
159:
160: xplanSP = new XPlanServiceProvider();
161: csb.addService(XPlanService.class, xplanSP);
162:
163: domainSP = new DomainServiceProvider();
164: sb.addService(DomainService.class, domainSP);
165:
166: domainRegistrySP = new DomainRegistryServiceProvider();
167: csb.addService(DomainRegistryService.class, domainRegistrySP);
168:
169: domainForBlackboardSP = new DomainForBlackboardServiceProvider();
170: sb.addService(DomainForBlackboardService.class,
171: domainForBlackboardSP);
172:
173: // display the agent id
174: if (loggingService.isDebugEnabled()) {
175: loggingService.debug("DomainManager " + this
176: + " loading Domains for agent " + self);
177: }
178:
179: super .load();
180: }
181:
182: private Iterator delayedXPlansIterator() {
183: synchronized (lock) {
184: // the list is immutable, since we replace it when modified
185: return delayedXPlans.iterator();
186: }
187: }
188:
189: private XPlan getXPlan(String domainName) {
190: Domain d = getDomain(domainName);
191: return (d == null ? null : d.getXPlan());
192: }
193:
194: private XPlan getXPlan(Class domainClass) {
195: Domain d = getDomain(domainClass);
196: return (d == null ? null : d.getXPlan());
197: }
198:
199: private void registerDomain(Domain d) {
200: String domainName = d.getDomainName();
201: XPlan xplan = d.getXPlan();
202: synchronized (lock) {
203: Domain origD = getDomain(domainName);
204: if (origD != null) {
205: if (loggingService.isWarnEnabled()) {
206: loggingService.warn("Domain \"" + domainName
207: + "\" multiply defined!"
208: + " Already loaded " + origD
209: + ". Ignoring " + d);
210: }
211: return;
212: }
213: // replace the list, treat it as immutable.
214: // this makes the blackboard access more efficient
215: List l = new ArrayList(domains.size() + 1);
216: l.addAll(domains);
217: l.add(d);
218: domains = l;
219: // add xplan
220: if (xplan instanceof SupportsDelayedLPActions
221: && (!delayedXPlans.contains(xplan))) {
222: l = new ArrayList(delayedXPlans.size() + 1);
223: l.addAll(delayedXPlans);
224: l.add(xplan);
225: delayedXPlans = l;
226: }
227: }
228:
229: if (loggingService.isDebugEnabled()) {
230: loggingService.debug("Registering " + domainName);
231: }
232:
233: if ((xplan != null) && (blackboard != null)) {
234: xplan.setupSubscriptions(blackboard);
235: }
236: }
237:
238: private void unregisterDomain(Domain d) {
239: String domainName = d.getDomainName();
240: synchronized (lock) {
241: // find index
242: int i;
243: int n;
244: for (i = 0, n = domains.size(); i < n; i++) {
245: Domain di = (Domain) domains.get(i);
246: if (di.getDomainName().equals(domainName)) {
247: break;
248: }
249: }
250: if (i >= n) {
251: // not registered?
252: return;
253: }
254: // remove entry, replace list
255: // fix domains
256: List l = new ArrayList(n - 1);
257: for (int j = 0; j < i; j++) {
258: l.add(domains.get(j));
259: }
260: for (int j = i + 1; j < n; j++) {
261: l.add(domains.get(j));
262: }
263: domains = l;
264: // fix delayed xplans
265: XPlan xplan = d.getXPlan();
266: if (xplan instanceof SupportsDelayedLPActions
267: && delayedXPlans.contains(xplan)) {
268: l = new ArrayList(delayedXPlans);
269: l.remove(xplan);
270: delayedXPlans = l;
271: }
272: }
273: }
274:
275: private Iterator domainIterator() {
276: synchronized (lock) {
277: // the list is immutable, since we replace it when modified
278: return domains.iterator();
279: }
280: }
281:
282: private Domain getDomain(String name) {
283: for (Iterator iter = domainIterator(); iter.hasNext();) {
284: Domain d = (Domain) iter.next();
285: if (d.getDomainName().equals(name)) {
286: return d;
287: }
288: }
289: return null;
290: }
291:
292: private Domain getDomain(Class clazz) {
293: for (Iterator iter = domainIterator(); iter.hasNext();) {
294: Domain d = (Domain) iter.next();
295: if (d.getClass().equals(clazz)) {
296: return d;
297: }
298: }
299: return null;
300: }
301:
302: private void setBlackboard(Blackboard blackboard) {
303: if (this .blackboard != null) {
304: if (loggingService.isWarnEnabled()) {
305: loggingService
306: .warn("DomainManager: ignoring duplicate call to setBlackboard. "
307: + "Blackboard can only be set once.");
308: }
309: return;
310: }
311: this .blackboard = blackboard;
312: for (Iterator iter = domainIterator(); iter.hasNext();) {
313: Domain d = (Domain) iter.next();
314: XPlan xplan = d.getXPlan();
315: if (xplan != null) {
316: xplan.setupSubscriptions(blackboard);
317: }
318: }
319: }
320:
321: private Factory getFactory(String domainName) {
322: Domain d = getDomain(domainName);
323: return (d == null ? null : d.getFactory());
324: }
325:
326: private Factory getFactory(Class domainClass) {
327: Domain d = getDomain(domainClass);
328: return (d == null ? null : d.getFactory());
329: }
330:
331: /** return a List of all domain-specific factories */
332: private List getFactories() {
333: ArrayList factories = new ArrayList(size());
334: for (Iterator iter = domainIterator(); iter.hasNext();) {
335: Domain d = (Domain) iter.next();
336: Factory f = d.getFactory();
337: if (f != null) {
338: factories.add(f);
339: }
340: }
341: return factories;
342: }
343:
344: private void invokeDelayedLPActions() {
345: for (Iterator iter = delayedXPlansIterator(); iter.hasNext();) {
346: SupportsDelayedLPActions xplan = (SupportsDelayedLPActions) iter
347: .next();
348: xplan.executeDelayedLPActions();
349: }
350: }
351:
352: /** invoke EnvelopeLogicProviders across all currently loaded domains */
353: private void invokeEnvelopeLogicProviders(EnvelopeTuple tuple,
354: boolean persistenceEnv) {
355: for (Iterator iter = domainIterator(); iter.hasNext();) {
356: Domain d = (Domain) iter.next();
357: d.invokeEnvelopeLogicProviders(tuple, persistenceEnv);
358: }
359: }
360:
361: /** invoke MessageLogicProviders across all currently loaded domains */
362: private void invokeMessageLogicProviders(DirectiveMessage message) {
363: for (Iterator iter = domainIterator(); iter.hasNext();) {
364: Domain d = (Domain) iter.next();
365: d.invokeMessageLogicProviders(message);
366: }
367: }
368:
369: /** invoke RestartLogicProviders across all currently loaded domains */
370: private void invokeRestartLogicProviders(MessageAddress cid) {
371: for (Iterator iter = domainIterator(); iter.hasNext();) {
372: Domain d = (Domain) iter.next();
373: d.invokeRestartLogicProviders(cid);
374: }
375: }
376:
377: /** invoke ABAChangeLogicProviders across all currently loaded domains */
378: private void invokeABAChangeLogicProviders(Set communities) {
379: for (Iterator iter = domainIterator(); iter.hasNext();) {
380: Domain d = (Domain) iter.next();
381: d.invokeABAChangeLogicProviders(communities);
382: }
383: }
384:
385: //
386: // binding services
387: //
388:
389: protected String specifyContainmentPoint() {
390: return CONTAINMENT_POINT;
391: }
392:
393: protected ComponentDescriptions findInitialComponentDescriptions() {
394: // display the agent id
395: String cname = agentIdService.getMessageAddress().toString();
396: ServiceBroker sb = getServiceBroker();
397: ComponentInitializerService cis = (ComponentInitializerService) sb
398: .getService(this , ComponentInitializerService.class,
399: null);
400: try {
401: List l = new ArrayList(5);
402:
403: // setup the root domain
404: addDomain(l, "root", "org.cougaar.core.domain.RootDomain");
405:
406: if (loadPlanning) {
407: // setup the planning domain
408: addDomain(l, "planning",
409: "org.cougaar.planning.ldm.PlanningDomain");
410: }
411:
412: /* read domain file */
413: initializeFromProperties(l);
414: initializeFromConfigFiles(l);
415:
416: /* read agent.ini */
417: try {
418: String cp = specifyContainmentPoint();
419: ComponentDescription[] cds = cds = cis
420: .getComponentDescriptions(cname, cp);
421: for (int i = 0; i < cds.length; i++) {
422: l.add(cds[i]);
423: }
424: } catch (ComponentInitializerService.InitializerException cise) {
425: if (loggingService.isWarnEnabled()) {
426: loggingService.warn(
427: "Cannot find DomainManager configuration for "
428: + cname, cise);
429: }
430: }
431:
432: return new ComponentDescriptions(l);
433: } catch (Exception e) {
434: loggingService.error("Unable to add " + cname
435: + "'s child Components", e);
436: return null;
437: } finally {
438: sb.releaseService(this , ComponentInitializerService.class,
439: cis);
440: }
441: }
442:
443: public void unload() {
444: ServiceBroker sb = getServiceBroker();
445: ServiceBroker csb = getChildServiceBroker();
446:
447: sb.revokeService(DomainForBlackboardService.class,
448: domainForBlackboardSP);
449: csb
450: .revokeService(DomainRegistryService.class,
451: domainRegistrySP);
452: sb.revokeService(DomainService.class, domainSP);
453: csb.revokeService(XPlanService.class, xplanSP);
454:
455: csb = null;
456:
457: super .unload();
458:
459: if (loggingService != LoggingService.NULL) {
460: sb.releaseService(this , LoggingService.class,
461: loggingService);
462: loggingService = LoggingService.NULL;
463: }
464:
465: if (agentIdService != null) {
466: sb.releaseService(this , AgentIdentificationService.class,
467: agentIdService);
468: agentIdService = null;
469: }
470: }
471:
472: //
473: // service providers
474: //
475:
476: private class DomainRegistryServiceProvider implements
477: ServiceProvider {
478: public Object getService(ServiceBroker sb, Object requestor,
479: Class serviceClass) {
480: if (DomainRegistryService.class
481: .isAssignableFrom(serviceClass)) {
482: return new DomainRegistryServiceImpl();
483: }
484: return null;
485: }
486:
487: public void releaseService(ServiceBroker sb, Object requestor,
488: Class serviceClass, Object service) {
489: if (service instanceof DomainRegistryServiceImpl) {
490: DomainRegistryServiceImpl srv = (DomainRegistryServiceImpl) service;
491: srv.onRelease();
492: }
493: }
494:
495: private class DomainRegistryServiceImpl implements
496: DomainRegistryService {
497: public void registerDomain(Domain d) {
498: DomainManager.this .registerDomain(d);
499: }
500:
501: public void unregisterDomain(Domain d) {
502: DomainManager.this .unregisterDomain(d);
503: }
504:
505: private void onRelease() {
506: // unregister all registered domains?
507: }
508: }
509: }
510:
511: private class XPlanServiceProvider implements ServiceProvider {
512: private final XPlanServiceImpl xps = new XPlanServiceImpl();
513:
514: public Object getService(ServiceBroker sb, Object requestor,
515: Class serviceClass) {
516: if (XPlanService.class.isAssignableFrom(serviceClass)) {
517: return xps;
518: }
519: return null;
520: }
521:
522: public void releaseService(ServiceBroker sb, Object requestor,
523: Class serviceClass, Object service) {
524: }
525:
526: private class XPlanServiceImpl implements XPlanService {
527: public XPlan getXPlan(String domainName) {
528: return DomainManager.this .getXPlan(domainName);
529: }
530:
531: public XPlan getXPlan(Class domainClass) {
532: return DomainManager.this .getXPlan(domainClass);
533: }
534: }
535: }
536:
537: private class DomainServiceProvider implements ServiceProvider {
538: private final DomainServiceImpl ds = new DomainServiceImpl();
539:
540: public Object getService(ServiceBroker sb, Object requestor,
541: Class serviceClass) {
542: if (DomainService.class.isAssignableFrom(serviceClass)) {
543: return ds;
544: }
545: return null;
546: }
547:
548: public void releaseService(ServiceBroker sb, Object requestor,
549: Class serviceClass, Object service) {
550: }
551:
552: private class DomainServiceImpl implements DomainService {
553: public Factory getFactory(String domainName) {
554: return DomainManager.this .getFactory(domainName);
555: }
556:
557: public Factory getFactory(Class domainClass) {
558: return DomainManager.this .getFactory(domainClass);
559: }
560:
561: public List getFactories() {
562: return DomainManager.this .getFactories();
563: }
564: }
565: }
566:
567: private class DomainForBlackboardServiceProvider implements
568: ServiceProvider {
569: public Object getService(ServiceBroker sb, Object requestor,
570: Class serviceClass) {
571: if (DomainForBlackboardService.class
572: .isAssignableFrom(serviceClass)) {
573: Blackboard bb = (Blackboard) requestor;
574: return new DomainForBlackboardServiceImpl(bb);
575: }
576: return null;
577: }
578:
579: public void releaseService(ServiceBroker sb, Object requestor,
580: Class serviceClass, Object service) {
581: if (service instanceof DomainForBlackboardServiceImpl) {
582: DomainForBlackboardServiceImpl srv = (DomainForBlackboardServiceImpl) service;
583: srv.onRelease();
584: }
585: }
586:
587: private class DomainForBlackboardServiceImpl implements
588: DomainForBlackboardService {
589: public DomainForBlackboardServiceImpl(Blackboard bb) {
590: // ignore
591: }
592:
593: // blackboard registration
594: public void setBlackboard(Blackboard blackboard) {
595: DomainManager.this .setBlackboard(blackboard);
596: }
597:
598: // copy of DomainService
599: public Factory getFactory(String domainName) {
600: return DomainManager.this .getFactory(domainName);
601: }
602:
603: public Factory getFactory(Class domainClass) {
604: return DomainManager.this .getFactory(domainClass);
605: }
606:
607: public List getFactories() {
608: return DomainManager.this .getFactories();
609: }
610:
611: // new stuff for the blackboard
612: public void invokeDelayedLPActions() {
613: DomainManager.this .invokeDelayedLPActions();
614: }
615:
616: public void invokeEnvelopeLogicProviders(
617: EnvelopeTuple tuple, boolean persistenceEnv) {
618: DomainManager.this .invokeEnvelopeLogicProviders(tuple,
619: persistenceEnv);
620: }
621:
622: public void invokeMessageLogicProviders(
623: DirectiveMessage message) {
624: DomainManager.this .invokeMessageLogicProviders(message);
625: }
626:
627: public void invokeRestartLogicProviders(MessageAddress cid) {
628: DomainManager.this .invokeRestartLogicProviders(cid);
629: }
630:
631: public void invokeABAChangeLogicProviders(Set communities) {
632: DomainManager.this
633: .invokeABAChangeLogicProviders(communities);
634: }
635:
636: // cleanup
637: private void onRelease() {
638: // set the domain manager's blackboard to null?
639: }
640: }
641: }
642:
643: //
644: // other services
645: //
646:
647: public String toString() {
648: return self + "/DomainManager";
649: }
650:
651: /**
652: * Set up a Domain from the argument strings.
653: *
654: * @param descs a list of component-descriptions for all
655: * previously added domains
656: * @param domainName the name to register the domain under.
657: * @param className the name of the class to instantiate as the domain.
658: */
659: private void addDomain(List descs, String domainName,
660: String className) {
661: // Unique?
662: ComponentDescription found_desc = null;
663: for (int i = 0, n = descs.size(); i < n; i++) {
664: ComponentDescription cd = (ComponentDescription) descs
665: .get(i);
666: if (cd != null && (cd.getParameter() instanceof List)) {
667: List l = (List) cd.getParameter();
668: if (l.size() > 0 && domainName.equals(l.get(0))) {
669: found_desc = cd;
670: break;
671: }
672: }
673: }
674: if (found_desc != null) {
675: if (loggingService.isWarnEnabled()) {
676: loggingService.warn("Domain \"" + domainName
677: + "\" multiply defined! "
678: + found_desc.getClassname() + " and "
679: + className);
680: }
681: return;
682: }
683:
684: // pass the domain-name as a parameter
685: Object parameter = Collections.singletonList(domainName);
686:
687: ComponentDescription desc = new ComponentDescription(className
688: + "(" + domainName + ")",
689: CONTAINMENT_POINT + ".Domain", className, null, // codebase
690: parameter, null, // certificate
691: null, // lease
692: null); // policy
693:
694: descs.add(desc);
695:
696: if (loggingService.isDebugEnabled()) {
697: loggingService.debug("Will add domain \"" + domainName
698: + "\" from class \"" + className + "\".");
699: }
700: }
701:
702: private void initializeFromProperties(List descs) {
703: Properties props = SystemProperties
704: .getSystemPropertiesWithPrefix(PREFIX);
705: for (Enumeration names = props.propertyNames(); names
706: .hasMoreElements();) {
707: String key = (String) names.nextElement();
708: if (key.startsWith(PREFIX)) {
709: String name = key.substring(PREFIXLENGTH);
710: // domain names have no extra "." characters, so we can
711: // use -D arguments to control domain-related facilities.
712: if (name.indexOf('.') < 0) {
713: String value = props.getProperty(key);
714: addDomain(descs, name, value);
715: }
716: }
717: }
718: }
719:
720: private void initializeFromConfigFiles(List descs) {
721: if (!readConfigFile || filename == null || filename.equals("")) {
722: return;
723: }
724: InputStream in = null;
725: try {
726: in = org.cougaar.util.ConfigFinder.getInstance().open(
727: filename);
728: InputStreamReader isr = new InputStreamReader(in);
729: BufferedReader br = new BufferedReader(isr);
730:
731: String line;
732: int lc = 0;
733: for (line = br.readLine(); line != null; line = br
734: .readLine()) {
735: lc++;
736: line = line.trim();
737: if (line.length() == 0)
738: continue;
739: char c;
740: if ((c = line.charAt(0)) == ';' || c == '#') {
741: continue;
742: }
743: int l = line.indexOf('=');
744: if (l == -1) {
745: loggingService.error(filename
746: + " syntax error: line " + lc);
747: continue;
748: }
749: String name = line.substring(0, l).trim();
750: String val = line.substring(l + 1).trim();
751: if (name.length() == 0 || val.length() == 0) {
752: loggingService.error(filename
753: + " syntax error: line " + lc);
754: continue;
755: }
756: addDomain(descs, name, val);
757: }
758: } catch (Exception ex) {
759: if (!(ex instanceof FileNotFoundException)) {
760: loggingService.error(filename + " exception: " + ex);
761: ex.printStackTrace();
762: }
763: } finally {
764: if (in != null) {
765: try {
766: in.close();
767: } catch (Exception e) {
768: if (loggingService.isDebugEnabled())
769: loggingService.debug(
770: "Failed closing input stream for "
771: + filename, e);
772: }
773: in = null;
774: }
775: }
776: }
777: }
|