001: /*
002: * CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
003: * NETSCAPE COMMUNICATIONS CORPORATION
004: *
005: * Copyright (c) 1996 Netscape Communications Corporation.
006: * All Rights Reserved.
007: * Use of this Source Code is subject to the terms of the applicable
008: * license agreement from Netscape Communications Corporation.
009: */
010:
011: package soif;
012:
013: import util.AltSTokenizer;
014: import util.ReportError;
015:
016: /**
017: * SOIF handling class.
018: * <p>
019: * The SOIF class is used as a list,
020: * where each SOIF statement gets it's own node.
021: * The first node is a header node
022: * which has the full SOIF text in it,
023: * the successor nodes have the variable but don't use it.
024: * The SOIF list is created by creating the initial SOIF
025: * instance and passing the SOIF string to it.
026: * The full SOIF list is then created by running the parser
027: * methods which iteratively create new SOIF instances (this
028: * was originally done in a more elegant recursive fashion,
029: * but that was a performance hog (passing the string).
030: */
031: public class SOIF implements Cloneable {
032: /**
033: * The SOIF schemaName.
034: */
035: protected String schemaName;
036:
037: /**
038: * The SOIF URL.
039: */
040: protected String URL;
041:
042: /**
043: * The attribute value pairs for this SOIF.
044: */
045: public AVPairs list;
046:
047: /**
048: * Count of unique attributes: Bob-1, Bob-2, Jim-1 = 2.
049: * Kept because it's costly to get directly from the
050: * AVPairs class.
051: */
052: private int attributeCount;
053:
054: /**
055: * Whether this is a valid SOIF object.
056: */
057: protected boolean valid;
058:
059: /**
060: * Next SOIF object on list.
061: */
062: public SOIF next;
063:
064: /**
065: * Constructor.
066: */
067: public SOIF() {
068: schemaName = "";
069: URL = "";
070: list = null;
071: attributeCount = 0;
072: valid = false;
073: next = null;
074: }
075:
076: /**
077: * Constructor.
078: */
079: public SOIF(String schemaName, String URL) {
080: this .schemaName = schemaName;
081: this .URL = URL;
082: list = null;
083: attributeCount = 0;
084: valid = false;
085: next = null;
086: }
087:
088: /**
089: * Adds a new AVPair to this list.
090: * @param att the attribute
091: * @param val the value
092: */
093: public void addAVPairs(String att, String val) throws Exception {
094: if (list == null) {
095: attributeCount++;
096: list = new AVPairs(att, val);
097: } else {
098: AVPairs avp = new AVPairs(att, val);
099: if (!list.attributeNameExists(avp.getAttributeName()))
100: attributeCount++;
101: else if (!avp.isMV())
102: // Not MV - don't allow duplicate
103: throw new Exception(Messages.INVALIDSOIF);
104: list.insertAfter(avp);
105: }
106: }
107:
108: /**
109: * Set a value by non-multivalue attribute.
110: * Ignores case of attribute name.
111: * @param s the attribute
112: */
113: public boolean setValue(String s, String v) {
114: return list.setValue(s, v);
115: }
116:
117: /**
118: * Set a value by attribute and multivalue index.
119: * Ignores case of attribute name.
120: * @param s the attribute
121: * @param n the index
122: */
123: public boolean setValue(String s, int n, String v) {
124: return list.setValue(s, n, v);
125: }
126:
127: /**
128: * Find a value by non-multivalue attribute.
129: * Ignores case of attribute name.
130: * @param s the attribute
131: */
132: public String getValue(String s) {
133: return list.getValue(s, -1);
134: }
135:
136: /**
137: * Find a value by attribute and multivalue index.
138: * Ignores case of attribute name.
139: * @param s the attribute
140: * @param n the index
141: */
142: public String getValue(String s, int n) {
143: return list.getValue(s, n);
144: }
145:
146: /**
147: * Find a values by attribute. Return an array of strings for
148: * multiple values for an attribute, e.g., for Bob, return
149: * values for Bob-1 and Bob-2.
150: * Ignores case of attribute name.
151: * @param s the attribute
152: */
153: public String[] getValues(String s) {
154: return list.getValues(s);
155: }
156:
157: /**
158: * Return a unique list of attributes w/out multi value,
159: * e.g. for Bob-1, Bob-2, Jim-1, return Bob, Jim.
160: */
161: public String[] getAttributes() {
162: return list.getAttributes();
163: }
164:
165: /**
166: * Get number of values for an attribute, e.g. if Bob has
167: * Bob-1 and Bob-2, the answer is 2.
168: * Ignores case of attribute name.
169: * @param s the attribute
170: */
171: public int attributeValueCount(String s) {
172: return list.attributeValueCount(s);
173: }
174:
175: /**
176: * Get a copy of all the AVPairs.
177: */
178: public AVPairs getAVPairs() {
179: return list;
180: }
181:
182: /**
183: * Clone the AVPairs w/ the specified MV.
184: * @param mv multivalue value
185: */
186: public AVPairs getAVPairsByMV(int mv) {
187: return list.getAVPairsByMV(mv);
188: }
189:
190: /**
191: * Clone the AVPairs w/ the specified attribute.
192: * @param s attribute
193: */
194: public AVPairs getAVPairsByAttribute(String s) {
195: return list.getAVPairsByAttribute(s);
196: }
197:
198: /**
199: * Unduplicate values on the AVPairs list.
200: */
201: public AVPairs unduplicateValues() {
202: return list.unduplicateValues();
203: }
204:
205: /**
206: * Get the max attribute index (multivalue) from AVPairs list.
207: */
208: public int getMaxAttributeIndex() {
209: return list.getMaxAttributeIndex();
210: }
211:
212: /**
213: * Return the pairs of the list that are not multivalue.
214: */
215: public AVPairs getSingleValuePairs() {
216: return list.getSingleValuePairs();
217: }
218:
219: /**
220: * Return the schemaName.
221: */
222: public String getSchemaName() {
223: return schemaName;
224: }
225:
226: /**
227: * Return the URL.
228: */
229: public String getURL() {
230: return URL;
231: }
232:
233: /**
234: * Number of SOIF nodes in a list.
235: */
236: public int count() {
237: int n = 0;
238: for (SOIF i = this ; i != null; i = i.next)
239: n++;
240: return n;
241: }
242:
243: /**
244: * Get the number of unique attributes with this SOIF.
245: */
246: public int getAttributeCount() {
247: return attributeCount;
248: }
249:
250: /**
251: * Whether a SOIF node is valid.
252: */
253: public boolean isValid() {
254: return valid;
255: }
256:
257: /**
258: * Print out SOIF.
259: * @param schemaName schema name
260: * @param URL URL
261: * @param a string array of attributes
262: * @param v string array of values
263: * @exception IllegalArgumentException If att an val arrays not same size
264: */
265: public static String toSOIF(String schemaName, String URL,
266: String a[], String v[]) {
267: if (a.length != v.length)
268: throw new IllegalArgumentException("a.length(" + a.length
269: + ") != v.length(" + v.length + ")");
270: StringBuffer sb = new StringBuffer("@" + schemaName + " { "
271: + URL + "\n");
272: for (int i = 0; i < a.length; i = i++)
273: sb.append(AVPairs.toSOIF(a[i], v[i]) + "\n");
274: sb.append("}\n");
275: return sb.toString();
276: }
277:
278: /**
279: * Return a single SOIF as a string.
280: * @deprecated Use {@link #toString()}
281: */
282: public String toSOIFString() {
283: return toString();
284: }
285:
286: /**
287: * Return entire SOIF list as a string.
288: * @deprecated Use {@link #toStringList()}
289: */
290: public String toSOIFList() {
291: return toStringList();
292: }
293:
294: /**
295: * Return a single SOIF as a string.
296: */
297: public String toString() {
298: StringBuffer sb = new StringBuffer("@" + schemaName + " { "
299: + URL + "\n");
300: for (AVPairs i = list; i != null; i = i.next)
301: sb.append(i.toSOIF());
302: sb.append("}\n\n");
303: return sb.toString();
304: }
305:
306: /**
307: * Return entire SOIF list as a string.
308: */
309: public String toStringList() {
310: StringBuffer sb = new StringBuffer();
311: for (SOIF i = this; i != null; i = i.next)
312: sb.append(i.toString());
313: return sb.toString();
314: }
315:
316: }
|