001: /*
002: * <copyright>
003: *
004: * Copyright 1997-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:
027: package org.cougaar.logistics.ui.inventory;
028:
029: import java.util.Stack;
030: import java.util.ArrayList;
031:
032: import org.cougaar.util.log.Logging;
033: import org.cougaar.util.log.Logger;
034:
035: import org.cougaar.logistics.plugin.inventory.LogisticsInventoryFormatter;
036: import org.cougaar.logistics.ui.inventory.data.*;
037:
038: /**
039: * <pre>
040: *
041: * The InventoryXMLParser is the class that parses the input xml
042: * string into data objects.
043: *
044: *
045: *
046: **/
047:
048: public class InventoryXMLParser {
049: protected int ctr;
050: protected String xmlInput;
051: protected String[] lines;
052: protected InventoryData inventory;
053: protected String currentString;
054: protected Stack tagStack;
055: protected Logger logger;
056:
057: public InventoryXMLParser() {
058: tagStack = new Stack();
059: logger = Logging.getLogger(this );
060: }
061:
062: public InventoryData parseString(String xmlInput) {
063: return parseString(xmlInput, false);
064: }
065:
066: public InventoryData parseHeader(String xmlInput) {
067: return parseString(xmlInput, true);
068: }
069:
070: protected InventoryData parseString(String xmlInput,
071: boolean justHeader) {
072: ctr = 0;
073: inventory = null;
074: this .xmlInput = xmlInput;
075: if ((xmlInput != null) && !(xmlInput.equals("null\n"))) {
076: lines = xmlInput.split("\\n");
077: if (logger.isDebugEnabled()) {
078: logger.debug("Number of Lines=" + lines.length);
079: }
080: parse(justHeader);
081: }
082: return inventory;
083: }
084:
085: protected void parse(boolean justHeader) {
086: while (ctr < lines.length) {
087: currentString = lines[ctr];
088: if (currentString.startsWith("</")) {
089: popTag();
090: } else if (currentString.startsWith("<")) {
091: tagStack.push(currentString);
092: String name = getTagName(currentString);
093: if (name
094: .equals(LogisticsInventoryFormatter.INVENTORY_DUMP_TAG)) {
095: ctr++;
096: } else if (name
097: .equals(LogisticsInventoryFormatter.INVENTORY_HEADER_PERSON_READABLE_TAG)) {
098: parseHumanReadable();
099: } else if (name
100: .equals(LogisticsInventoryFormatter.INVENTORY_HEADER_GUI_TAG)) {
101: parseHeader();
102: if (justHeader) {
103: return;
104: }
105: } else {
106: if (!justHeader) {
107: parseSchedule();
108: } else {
109: ctr++;
110: }
111: }
112: } else {
113: logger.warn("Unparseable line: " + currentString);
114: ctr++;
115: }
116: }
117: }
118:
119: protected String stripTag(String tag) {
120: int start = 0;
121: int end = tag.length();
122: if (tag.startsWith("</")) {
123: start = 2;
124: } else if (tag.startsWith("<")) {
125: start = 1;
126: }
127: if (tag.endsWith(">")) {
128: end--;
129: }
130: return tag.substring(start, end);
131: }
132:
133: protected String getTagName(String tag) {
134: tag = stripTag(tag);
135: String words[] = tag.split("\\s");
136: return words[0];
137: }
138:
139: protected void parseHeader() {
140: String header = stripTag(currentString);
141: String[] words = header.split("\\s");
142: String org = null;
143: String asset = null;
144: String unit = null;
145: String nomenclature = null;
146: String supplyType = null;
147: long cDay = 0L;
148: int i = 1;
149:
150: if (words[i].startsWith("org=")) {
151: org = words[i].substring("org=".length());
152: }
153: i++;
154: if (words[i].startsWith("item=")) {
155: asset = words[i].substring("item=".length());
156: }
157: i++;
158: if (words[i].startsWith("unit=")) {
159: unit = words[i].substring("unit=".length());
160: }
161: i++;
162: while (!(words[i].startsWith("nomenclature="))) {
163: unit = unit + " " + words[i];
164: i++;
165: }
166: if (words[i].startsWith("nomenclature=")) {
167: nomenclature = words[i].substring("nomenclature=".length());
168: }
169: i++;
170: while (!(words[i].startsWith("supplyType="))) {
171: nomenclature = nomenclature + " " + words[i];
172: i++;
173: }
174: if (words[i].startsWith("supplyType=")) {
175: supplyType = words[i].substring("supplyType=".length());
176: }
177: i++;
178: while (!(words[i].startsWith("cDay="))) {
179: supplyType = supplyType + " " + words[i];
180: i++;
181: }
182: if (words[i].startsWith("cDay=")) {
183: String cDayString = words[i].substring("cDay=".length());
184: cDay = (new Long(cDayString)).longValue();
185: }
186:
187: inventory = new InventoryData(asset, org, unit, nomenclature,
188: supplyType, cDay, xmlInput);
189: if (logger.isDebugEnabled()) {
190: logger.debug("Parsed header w/org=|" + org + "| item=|"
191: + asset + "| unit=|" + unit + "| nomenclature=|"
192: + nomenclature + "| supplyType=|" + supplyType
193: + "| cDay=|" + cDay + "|");
194: }
195: ctr++;
196: }
197:
198: protected String getScheduleType(String tag) {
199: tag = stripTag(tag);
200: String words[] = tag.split("type=");
201: return words[1].trim();
202: }
203:
204: protected void parseSchedule() {
205: String name = getTagName(currentString);
206: logger.debug("Parsing Schedule " + name);
207: String typeStr = getScheduleType(currentString);
208: logger.debug(" of type " + typeStr);
209: int type = InventoryScheduleHeader.getTypeInt(typeStr);
210: int ctrIn = ctr;
211: currentString = lines[++ctr];
212: ArrayList elements = new ArrayList();
213: while (!(currentString.startsWith("<"))) {
214: elements.add(parseString(currentString, type));
215: currentString = lines[++ctr];
216: }
217:
218: InventoryScheduleHeader header = new InventoryScheduleHeader(
219: name, type, elements);
220: inventory.addSchedule(header);
221:
222: if (logger.isDebugEnabled()) {
223: logger.debug("Parsed Schedule " + name + " there were "
224: + (ctr - ctrIn) + " lines of type " + typeStr);
225: }
226:
227: }
228:
229: protected void parseHumanReadable() {
230: //toss out this stuff
231: String name = getTagName(currentString);
232: logger.debug("Parsing: " + name);
233: String humanReadableEndTag = "</"
234: + LogisticsInventoryFormatter.INVENTORY_HEADER_PERSON_READABLE_TAG
235: + ">";
236: while (!(currentString.equals(humanReadableEndTag))) {
237: currentString = lines[++ctr];
238: }
239: }
240:
241: protected InventoryScheduleElement parseString(
242: String elementString, int type) {
243: switch (type) {
244: case InventoryScheduleHeader.TASKS_TYPE:
245: return InventoryTask.createFromCSV(elementString);
246: case InventoryScheduleHeader.PROJ_TASKS_TYPE:
247: return InventoryProjTask.createFromCSV(elementString);
248: case InventoryScheduleHeader.ARS_TYPE:
249: return InventoryAR.createFromCSV(elementString);
250: case InventoryScheduleHeader.PROJ_ARS_TYPE:
251: return InventoryProjAR.createProjFromCSV(elementString);
252: case InventoryScheduleHeader.LEVELS_TYPE:
253: return InventoryLevel.createFromCSV(elementString);
254: default:
255: throw new RuntimeException("Unparseable CSV "
256: + elementString + " Element Type " + type);
257: }
258: }
259:
260: protected void popTag() {
261: String lastTag = (String) tagStack.peek();
262: if (getTagName(lastTag).equals(getTagName(currentString))) {
263: tagStack.pop();
264: if (logger.isDebugEnabled()) {
265: logger.debug("Popping " + getTagName(currentString));
266: }
267: } else {
268: throw new RuntimeException(
269: "ERROR:Last pushed tag doesn't match this termination tag");
270: }
271: ctr++;
272: }
273:
274: }
|