001: /*
002: * <copyright>
003: *
004: * Copyright 2000-2004 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: package org.cougaar.tools.csmart.society.file;
027:
028: import org.cougaar.core.component.ComponentDescription;
029: import org.cougaar.tools.csmart.core.cdata.ComponentConnector;
030: import org.cougaar.tools.csmart.society.AgentComponent;
031: import org.cougaar.tools.csmart.society.SocietyBase;
032:
033: import java.io.File;
034:
035: public class SocietyFileComponent extends SocietyBase {
036:
037: protected static final String DESCRIPTION_RESOURCE_NAME = "/org/cougaar/tools/csmart/society/society-base-description.html";
038: protected static final String BACKUP_DESCRIPTION = "A Society created from files: Agents, Binders, Plugins, etc.";
039:
040: private String name;
041: private ComponentDescription[] desc;
042: private String[] filenames = null;
043: private String singleFilename = null;
044: private boolean filesParsed = false;
045:
046: /**
047: * Construct a society from a single file which
048: * enumerates the agents in the society.
049: * The names of files that define individual agents are assumed
050: * to be of the form: <agentname>.ini
051: * @param filename the name of the file that enumerates the agents
052: */
053: public SocietyFileComponent(String filename) {
054: super (filename);
055: this .name = filename;
056: this .singleFilename = filename;
057: }
058:
059: /**
060: * Creates a new <code>SocietyFileComponent</code> from the given
061: * Node file, with the given (different) name.
062: *
063: * @param filename a <code>String</code> name of a Node file on the ConfigPath
064: * @param socname a <code>String</code> name for the new society
065: */
066: public SocietyFileComponent(String filename, String socname) {
067: super (socname);
068: this .name = socname;
069:
070: // Must store the filename for use in initproperties
071: this .singleFilename = filename;
072: }
073:
074: /**
075: * Construct a <code>SocietyFileComponent</code> from files,
076: * each of which defines an agent in the society.
077: * @param name Name of the society
078: * @param filenames Names of the files that define the agents
079: */
080: public SocietyFileComponent(String name, String[] filenames) {
081: super (name);
082: this .filenames = filenames;
083: }
084:
085: /**
086: * Initialize all local properties
087: *
088: */
089: public void initProperties() {
090: if (!filesParsed) {
091: filesParsed = true;
092: initFromFiles();
093: }
094: }
095:
096: private void initFromFiles() {
097: if (filenames == null)
098: initFromSingleFile();
099: else
100: initFromMultiFiles();
101: }
102:
103: private void initFromSingleFile() {
104: String filename = singleFilename;
105: if (log.isDebugEnabled()) {
106: log.debug("Parse File: " + filename);
107: }
108:
109: // FIXME: Must handle getting non-Agents in the file
110:
111: desc = ComponentConnector.parseFile(filename);
112: if (desc == null)
113: return;
114: for (int i = 0; i < desc.length; i++) {
115: String agentName = ComponentConnector.getAgentName(desc[i]);
116: if (log.isDebugEnabled()) {
117: log.debug("Name: " + agentName + " Class: "
118: + desc[i].getClassname());
119: }
120: // construct agent filename as:
121: // path of singleFilename + agentName + ".ini"
122: String agentFilename = filename;
123: int index = agentFilename.lastIndexOf(File.separatorChar);
124: if (index != -1)
125: agentFilename = agentFilename.substring(0, index + 1);
126: agentFilename = agentFilename + agentName + ".ini";
127: AgentComponent agent = (AgentComponent) new AgentFileComponent(
128: agentName, agentFilename, desc[i].getClassname());
129: agent.initProperties();
130: addChild(agent);
131: }
132: }
133:
134: private void initFromMultiFiles() {
135: for (int i = 0; i < filenames.length; i++) {
136: if (log.isDebugEnabled()) {
137: log.debug("Parse File: " + filenames[i]);
138: }
139: // derive agent name from filename
140: String agentName = filenames[i];
141: if (agentName.endsWith(".ini"))
142: agentName = agentName.substring(0,
143: agentName.length() - 4);
144: int index = agentName.lastIndexOf(File.separatorChar);
145: if (index != -1)
146: agentName = agentName.substring(index + 1);
147:
148: // FIXME: I'd like to handle non binders of Agents, etc
149:
150: AgentComponent agent = (AgentComponent) new AgentFileComponent(
151: agentName, filenames[i],
152: "org.cougaar.core.agent.SimpleAgent");
153: agent.initProperties();
154: addChild(agent);
155: }
156: }
157:
158: // /**
159: // * Copies this component.
160: // * @param name Name to use in the copy
161: // * @return a <code>ModifiableComponent</code> which is a copy of this object
162: // */
163: // public ModifiableComponent copy(String name) {
164: // if (log.isDebugEnabled()) {
165: // log.debug("Copying society " + this.getSocietyName() + " with assembly " + getAssemblyId() + " into new name " + name);
166: // }
167: // ModifiableComponent societyCopy;
168:
169: // // FIXME: I'd like to just call the parent, But I'm not
170: // // sure it would work. When the super calls initProperties
171: // // it will try to re-parse from files
172: // // The only way to stop that would be between the constructor
173: // // and the initProperties, to set that flag
174: // // But even then, the children agents wouldnt exist to
175: // // be copied...
176: // //societyCopy = super.copy(name);
177: // if (filenames != null)
178: // societyCopy = new SocietyFileComponent(name, filenames);
179: // else
180: // societyCopy = new SocietyFileComponent(singleFilename, name);
181:
182: // societyCopy.initProperties();
183:
184: // // If I re-init from files, it is not modified, per se.
185: // // But we're putting it under a new assembly ID, and not saving it
186: // // so to that extent, it is modified.
187: // // Otherwise, set to the old value (= this.modified)
188: // ((SocietyBase)societyCopy).modified = true;
189:
190: // // copy the assembly ID - the one under which this societies'
191: // // data is currently in the DB, but must be copied
192: // ((SocietyBase)societyCopy).oldAssemblyId = getAssemblyId();
193:
194: // return societyCopy;
195: // }
196:
197: }
|