001: /*
002: * JFolder, Copyright 2001-2006 Gary Steinmetz
003: *
004: * Distributable under LGPL license.
005: * See terms of license at gnu.org.
006: */
007:
008: package org.jfolder.console.web.dictionary;
009:
010: //base classes
011: import java.io.IOException;
012: import java.util.ArrayList;
013: import java.util.Collections;
014: import java.util.HashMap;
015: import java.util.StringTokenizer;
016: import javax.servlet.http.HttpServletRequest;
017:
018: //project specific classes
019: import org.jfolder.common.StandardDataTypes;
020: import org.jfolder.common.UnexpectedSystemException;
021: import org.jfolder.common.tagging.CompoundConceptTagConstraintContext;
022: import org.jfolder.common.tagging.ConceptTag;
023: import org.jfolder.common.tagging.ConceptTagConstraint;
024: import org.jfolder.common.tagging.ConceptTagConstraintHolder;
025: import org.jfolder.common.tagging.ConceptTagConstraintOrTemplate;
026: import org.jfolder.common.tagging.ConceptTagConstraintTemplate;
027: import org.jfolder.common.tagging.ConceptTagFlags;
028: import org.jfolder.common.tagging.ConceptTagPreferences;
029: import org.jfolder.common.tagging.ConceptTagPreferencesHelper;
030: import org.jfolder.common.tagging.ConceptTagSetHolder;
031: import org.jfolder.common.tagging.DynamicConceptTagConstraintContext;
032: import org.jfolder.common.tagging.DynamicConceptTagValidator;
033: import org.jfolder.common.tagging.SelectionCriteriaForConceptTag;
034: import org.jfolder.common.tagging.SelectionCriteriaForReturnableConceptTag;
035: import org.jfolder.common.tagging.StaticConceptTagConstraintContext;
036: import org.jfolder.common.utils.misc.MiscHelper;
037: import org.jfolder.common.utils.web.ParameterHelper;
038: import org.jfolder.common.utils.web.ParameterSet;
039: import org.jfolder.common.utils.xml.LinearXPath;
040: import org.jfolder.common.utils.xml.XMLHelper;
041: import org.jfolder.common.web.template.ConsoleTemplateContext;
042: import org.jfolder.common.web.template.ConsoleTemplateParameters;
043: import org.jfolder.common.web.template.SubmitActionContext;
044: import org.jfolder.common.web.template.SubmitActionParameters;
045: import org.jfolder.config.instance.ConfigInstance;
046: import org.jfolder.config.instance.ConfigInstanceConfig;
047: import org.jfolder.console.base.ConsolePageParameters;
048: import org.jfolder.security.lifecycle.SecurityLifecycleHelper;
049: import org.jfolder.security.model.UserHolder;
050: import org.jfolder.services.config.ConfigService;
051: import org.jfolder.services.config.ConfigServiceCaller;
052: import org.jfolder.services.config.ConfigServiceCallerFactory;
053:
054: //other classes
055:
056: public class ConceptTagDictionaryDisplayContext extends
057: BaseConceptTagDictionaryContext {
058:
059: protected ConceptTagDictionaryDisplayContext(ParameterSet inPs) {
060: //
061: super (inPs);
062: }
063:
064: public String getFromPage() {
065: return ConsolePageParameters.SERVLET_DICTIONARY_DISPLAY;
066: }
067:
068: public String getHandle() {
069: return NULL_HANDLE;
070: }
071:
072: public String getHandleExtension() {
073: throw new UnexpectedSystemException(
074: "This function should not be called in this class");
075: }
076:
077: protected void renderConsolePage() throws IOException {
078:
079: ParameterSet ps = getParameterSet();
080:
081: //render content
082: startCommonPage();
083:
084: String prefHan = null;
085: String ctNs = null;
086: String ctName = null;
087:
088: //
089: if (ps.isParameterString(PARAMETER__PREF_HANDLE)) {
090: prefHan = ps.getParameter(PARAMETER__PREF_HANDLE);
091: }
092:
093: //
094: if (ps.isParameterString(PARAMETER__CT_NS)) {
095: ctNs = ps.getParameter(PARAMETER__CT_NS);
096: }
097:
098: //
099: if (ps.isParameterString(PARAMETER__CT_NAME)) {
100: ctName = ps.getParameter(PARAMETER__CT_NAME);
101: }
102:
103: if ((ctNs == null && ctName == null) || prefHan == null) {
104: //
105: startTable(3);
106: startRow();
107: startAndEndCell(3,
108: "Please choose a category (top left) and a "
109: + "concept tag (bottom left).",
110: getFontStyle(11, ARIAL, BLACK));
111: //startAndEndCell(2, "Hi");
112: endRow();
113: endTable();
114: } else {
115: ConceptTagPreferences localCtp = ConceptTagPreferencesHelper
116: .getPreferencesFromHandle(prefHan);
117: //
118: ConceptTagSetHolder localCtsh = localCtp.getSetHolder();
119: Class ctClass = localCtsh.getConceptTagClass(ctNs, ctName);
120: ConceptTag ct = (ConceptTag) MiscHelper
121: .newInstance(ctClass);
122: //
123: //MiscHelper.println(
124: // "ConTagDictDisCon ctClass = '" + ctClass.toString() + "'");
125: String ctTitle = localCtsh.getTypeTitle(ctClass.getName());
126: //
127: InspectorInitializeConceptTagContext iictc = InspectorInitializeConceptTagContext
128: .newInstance(localCtp, ct);
129: //
130: //
131: //Class ctClass = MiscHelper.getClassByName(ctClass);
132: ConceptTagConstraintHolder ctconh = iictc
133: .getConstraintHolder(ct);
134: //
135: createHorizontalRow(0);
136: //
137: startTable(3);
138: //
139: startRow();
140: String ctTitleLabel = ctTitle;
141: if (ctTitle == null) {
142: ctTitleLabel = "(No Title)";
143: }
144: startAndEndCell(3, XMLHelper
145: .fromStringToCData(ctTitleLabel), addStyle(
146: getFontStyle(18, ARIAL, BLACK), "text-decoration",
147: "underline"));
148: endRow();
149: endTable();
150: //
151: createHorizontalRow(0);
152: //
153: //
154: //
155: //String csNsLabel = ctNs;
156: //if (csNsLabel == null) {
157: // csNsLabel = "(No Namespace)";
158: //}
159: //
160: startTable(4);
161: startRow();
162: startAndEndCell(1, "XML Namespace", getFontStyle(12, ARIAL,
163: BLACK));
164: if (ctNs != null) {
165: startAndEndCell(3, XMLHelper.fromStringToCData(ctNs),
166: getFontStyle(8, ARIAL, BLACK));
167: } else {
168: startAndEndCell(3, "(No Namespace)", getFontStyle(12,
169: ARIAL, BLACK));
170: }
171: endRow();
172: endTable();
173: //
174: //
175: createHorizontalRow(1);
176: //
177: //
178: startTable(4);
179: startRow();
180: startAndEndCell(1, "XML Name", getFontStyle(12, ARIAL,
181: BLACK));
182: startAndEndCell(3, XMLHelper.fromStringToCData(ctName),
183: getFontStyle(12, ARIAL, BLACK));
184: endRow();
185: endTable();
186: //
187: //
188: createHorizontalRow(0);
189: //
190: startTable(4);
191: startRow();
192: startAndEndCell(1, "Example", addAttr(getFontStyle(12,
193: ARIAL, BLACK), "valign", "top"));
194: //startAndEndCell(3, XMLHelper.fromStringToCData(ctName),
195: // getFontStyle(12, ARIAL, BLACK));
196: startCell(3);
197: //
198: ArrayList exampleList = parseByCarriageReturn(iictc
199: .getExample());
200: displayArea(exampleList, 3);
201: //
202: endCell();
203: endRow();
204: endTable();
205: //
206: //
207: createHorizontalRow(0);
208: //
209: startTable(4);
210: startRow();
211: startAndEndCell(1, "Selection Criteria", addAttr(
212: getFontStyle(12, ARIAL, BLACK), "valign", "top"));
213: //startAndEndCell(3, XMLHelper.fromStringToCData(ctName),
214: // getFontStyle(12, ARIAL, BLACK));
215: startCell(3);
216: //
217: ArrayList flagSettings = parseSelectionCriteria(iictc
218: .getSelectionCriteria(), " ");
219: displayArea(flagSettings, 3);
220: //
221: endCell();
222: endRow();
223: endTable();
224: //
225: createHorizontalRow(0);
226: //
227: displayConstraints(ctconh);
228: //
229: createHorizontalRow(0);
230: //
231: }
232:
233: //startEnclosingTableAndRowAndCell(attrs);
234: //
235: //startAndEndStretchTableAndRowAndCell("<hr color=\"#FFFFF\"/>");
236: //
237: //
238: //startAndEndStretchTableAndRowAndCell("<hr/>");
239: //
240: //
241: //startAndEndStretchTableAndRowAndCell("<hr color=\"#FFFFF\"/>");
242: //
243: //
244: //endEnclosingTableAndRowAndCell();
245: //
246:
247: endCommonPage();
248: }
249:
250: private void displayArea(ArrayList inList, int inWidth)
251: throws IOException {
252: //
253: //
254: HashMap divStyles = getFontStyle(8, ARIAL, BLACK);
255: divStyles.put("overflow", "scroll");
256: divStyles.put("width", "" + inWidth * (getColumnWidth()));
257: //
258: divStyles.put("height", "" + 125);
259: divStyles.put("border-width", "" + 1);
260: divStyles.put("border-color", "#333333");
261: divStyles.put("border-style", "solid");
262: //
263: HashMap divAttrs = new HashMap();
264: divAttrs.put("style", XMLHelper.fromStylesToAttr(divStyles));
265: divAttrs.put("nowrap", "true");
266: //
267: printAndIndent("<div " + XMLHelper.convertAttrs(divAttrs) + ">");
268: //
269: //
270: for (int i = 0; i < inList.size(); i++) {
271: String nextList = (String) inList.get(i);
272: if (nextList.trim().length() > 0) {
273: simpleAndPrint(XMLHelper.fromStringToHTML(nextList)
274: + "<br/>");
275: }
276: //startRow();
277: //startAndEndCell(1, padNbsp(1));
278: //startAndEndCell(3, XMLHelper.fromStringToCData(ctName),
279: // getFontStyle(12, ARIAL, BLACK));
280: //startAndEndCell(3, XMLHelper.fromStringToHTML(nextList),
281: // getFontStyle(8, ARIAL, BLACK));
282: //endRow();
283: }
284: //
285: //
286: revertAndPrint("</div>");
287: }
288:
289: private void displayConstraints(ConceptTagConstraintHolder inCtconh)
290: throws IOException {
291: //
292: displayAttributesOrStyles(inCtconh.getAttributes());
293: displayAttributesOrStyles(inCtconh.getStyles());
294: //
295: for (int i = 0; i < inCtconh.getConstraintCount(); i++) {
296: //
297: ConceptTagConstraint nextCtcon = inCtconh.getConstraint(i);
298: displayConstraint(nextCtcon);
299: }
300: //
301: displayConstraint(inCtconh.getUndefinedConstraint());
302: }
303:
304: private void displayAttributesOrStyles(
305: ConceptTagConstraintHolder inCtconh) throws IOException {
306: //
307: if (inCtconh != null && inCtconh.getConstraintCount() > 0) {
308: int topMargin = getLeftMargin();
309: setLeftMargin(topMargin + 1);
310: //
311: String title = inCtconh.getTitle();
312: if (title == null) {
313: title = "(No Label)";
314: }
315: //
316: startTable(3);
317: startRow();
318: startAndEndCell(3, createHorizontalRow(3, null));
319: //createHorizontalRow(3);
320: //endCell();
321: endRow();
322: startRow();
323: startAndEndCell(3, XMLHelper.fromStringToCData(title));
324: endRow();
325: endTable();
326: //
327: for (int i = 0; i < inCtconh.getConstraintCount(); i++) {
328: //
329: ConceptTagConstraint nextCtcon = inCtconh
330: .getConstraint(i);
331: displayConstraint(nextCtcon);
332: }
333: //
334: setLeftMargin(topMargin);
335: }
336: }
337:
338: private void displayConstraint(
339: ConceptTagConstraintOrTemplate inCtcot) throws IOException {
340: //
341: if (inCtcot != null
342: && !(inCtcot.getMinimumLength() == 0
343: && inCtcot.getMaximumLength() == 0 && !inCtcot
344: .isLengthUnbounded())) {
345: //
346: int topMargin = getLeftMargin();
347: setLeftMargin(topMargin + 1);
348:
349: //startTable(3);
350: //startRow();
351: //startAndEndCell(3, createHorizontalRow(3, null));
352: //createHorizontalRow(3);
353: //endCell();
354: //
355: //
356: createHorizontalRow(0);
357: //
358: //
359: //endRow();
360: startTable(3);
361: //
362: startRow();
363: startAndEndCell(1, "Constraint Name", getFontStyle(12,
364: ARIAL, BLACK));
365: if (inCtcot.getTitle() != null) {
366: startAndEndCell(2, XMLHelper.fromStringToCData(inCtcot
367: .getTitle()), getFontStyle(12, ARIAL, BLACK));
368: } else {
369: startAndEndCell(2, XMLHelper
370: .fromStringToCData("(No Label)"), getFontStyle(
371: 12, ARIAL, BLACK));
372: }
373: endRow();
374: //
375: //
376: startRow();
377: startAndEndCell(1, padNbsp(2) + "XML Name", getFontStyle(
378: 10, ARIAL, BLACK));
379: if (!inCtcot.getName().equals(
380: inCtcot.getPreferences().getUnconstrainedSymbol())) {
381: //
382: startAndEndCell(2, XMLHelper.fromStringToCData(inCtcot
383: .getName()), getFontStyle(10, ARIAL, BLACK));
384: } else {
385: startAndEndCell(2, XMLHelper
386: .fromStringToCData("(No Name)"), getFontStyle(
387: 10, ARIAL, BLACK));
388: }
389: endRow();
390: //
391: //
392: startRow();
393: startAndEndCell(1, padNbsp(2) + "Minimum Occurance",
394: getFontStyle(10, ARIAL, BLACK));
395: startAndEndCell(2, XMLHelper.fromStringToCData(inCtcot
396: .getMinimumLength()
397: + ""), getFontStyle(10, ARIAL, BLACK));
398: endRow();
399: //
400: //
401: startRow();
402: startAndEndCell(1, padNbsp(2) + "Maximum Occurance",
403: getFontStyle(10, ARIAL, BLACK));
404: if (inCtcot.isLengthUnbounded()) {
405: startAndEndCell(2, XMLHelper
406: .fromStringToCData("(No Limit)"), getFontStyle(
407: 10, ARIAL, BLACK));
408: } else {
409: startAndEndCell(2, XMLHelper.fromStringToCData(inCtcot
410: .getMaximumLength()
411: + ""), getFontStyle(10, ARIAL, BLACK));
412: }
413: endRow();
414: //
415: //
416: startRow();
417: startAndEndCell(1, padNbsp(2) + "Short Description",
418: getFontStyle(10, ARIAL, BLACK));
419: if (inCtcot.getShortDescription() != null) {
420: startAndEndCell(2, XMLHelper.fromStringToCData(inCtcot
421: .getShortDescription()), getFontStyle(10,
422: ARIAL, BLACK));
423: } else {
424: startAndEndCell(2, XMLHelper
425: .fromStringToCData("(No Description)"),
426: getFontStyle(10, ARIAL, BLACK));
427: }
428: endRow();
429: //
430: //
431: startRow();
432: startAndEndCell(1, padNbsp(2) + "Long Description",
433: getFontStyle(10, ARIAL, BLACK));
434: if (inCtcot.getLongDescription() != null) {
435: startAndEndCell(2, XMLHelper.fromStringToCData(inCtcot
436: .getLongDescription()), getFontStyle(10, ARIAL,
437: BLACK));
438: } else {
439: startAndEndCell(2, XMLHelper
440: .fromStringToCData("(No Description)"),
441: getFontStyle(10, ARIAL, BLACK));
442: }
443: endRow();
444: //
445: endTable();
446:
447: //
448: if (inCtcot.isStaticContextPresent()) {
449: StaticConceptTagConstraintContext sctcc = inCtcot
450: .getStaticConstraintContext();
451: //
452: processStatic(sctcc);
453: }
454:
455: //
456: if (inCtcot.isDynamicContextPresent()) {
457: DynamicConceptTagConstraintContext dctcc = inCtcot
458: .getDynamicConstraintContext();
459: //
460: processDynamic(dctcc);
461: }
462:
463: //
464: if (inCtcot.isCompoundContextPresent()) {
465: CompoundConceptTagConstraintContext cctcc = inCtcot
466: .getCompoundConstraintContext();
467: //
468: processCompound(cctcc);
469: }
470:
471: //
472: setLeftMargin(topMargin);
473: }
474:
475: }
476:
477: private void processStatic(StaticConceptTagConstraintContext inSctcc)
478: throws IOException {
479: //
480: //
481: int staticMargin = getLeftMargin();
482: setLeftMargin(staticMargin + 1);
483: //
484: createHorizontalRow(0);
485: //
486: startAndEndSimpleTableAndRowAndCell(2,
487: "Static Values Are Permitted", getFontStyle(12, ARIAL,
488: BLACK));
489: //
490: startTable(2);
491: startRow();
492: startAndEndCell(1, padNbsp(2) + "Is Multiline?", getFontStyle(
493: 10, ARIAL, BLACK));
494: if (inSctcc.isMultiLine()) {
495: startAndEndCell(1, XMLHelper.fromStringToCData("Yes"),
496: getFontStyle(10, ARIAL, BLACK));
497: } else {
498: startAndEndCell(1, XMLHelper.fromStringToCData("No"),
499: getFontStyle(10, ARIAL, BLACK));
500: }
501: endRow();
502: endTable();
503: //
504: if (inSctcc.getRegularExpression() != null) {
505: //createHorizontalRow(0);
506: //
507: startTable(2);
508: startRow();
509: startAndEndCell(1, padNbsp(2) + "Must Match", getFontStyle(
510: 10, ARIAL, BLACK));
511: startAndEndCell(1, XMLHelper.fromStringToCData(inSctcc
512: .getRegularExpression()), getFontStyle(10, ARIAL,
513: BLACK));
514: endRow();
515: endTable();
516: }
517: //
518: if (inSctcc.getRegularExpressionErrorMessage() != null) {
519: //createHorizontalRow(0);
520: //
521: startTable(2);
522: startRow();
523: startAndEndCell(1, padNbsp(2) + "Must Match Err Mess",
524: getFontStyle(10, ARIAL, BLACK));
525: startAndEndCell(1, XMLHelper.fromStringToCData(inSctcc
526: .getRegularExpressionErrorMessage()), getFontStyle(
527: 10, ARIAL, BLACK));
528: endRow();
529: endTable();
530: }
531: //
532: startTable(2);
533: startRow();
534: startAndEndCell(1, padNbsp(2) + "Minimum Length", getFontStyle(
535: 10, ARIAL, BLACK));
536: startAndEndCell(1, XMLHelper.fromStringToCData(inSctcc
537: .getMinimumStringLength()
538: + ""), getFontStyle(10, ARIAL, BLACK));
539: endRow();
540: endTable();
541: //
542: startTable(2);
543: startRow();
544: startAndEndCell(1, padNbsp(2) + "Maximum Length", getFontStyle(
545: 10, ARIAL, BLACK));
546: if (inSctcc.isStringLengthUnbounded()) {
547: startAndEndCell(1, XMLHelper
548: .fromStringToCData("(No Limit)"), getFontStyle(10,
549: ARIAL, BLACK));
550: } else {
551: startAndEndCell(1, XMLHelper.fromStringToCData(inSctcc
552: .getMaximumStringLength()
553: + ""), getFontStyle(10, ARIAL, BLACK));
554: }
555: endRow();
556: endTable();
557: //
558: //
559: if (inSctcc.getEntrySetLength() > 0) {
560: startTable(2);
561: startRow();
562: startAndEndCell(1, padNbsp(2) + "Predefined Values",
563: getFontStyle(10, ARIAL, BLACK));
564: if (inSctcc.isEntrySetExclusive()) {
565: startAndEndCell(1, XMLHelper
566: .fromStringToCData("(No Other Permitted)"),
567: getFontStyle(10, ARIAL, BLACK));
568: } else {
569: startAndEndCell(1, XMLHelper
570: .fromStringToCData("(Others Permitted)"),
571: getFontStyle(10, ARIAL, BLACK));
572: }
573: endRow();
574: endTable();
575: //
576: //
577: //
578: startTable(2);
579: startRow();
580: startAndEndCell(1, "Description", getFontStyle(10, ARIAL,
581: BLACK));
582: startAndEndCell(1, "Actual Value", getFontStyle(10, ARIAL,
583: BLACK));
584: endRow();
585: for (int i = 0; i < inSctcc.getEntrySetLength(); i++) {
586: startRow();
587: startAndEndCell(1, inSctcc.getEntryDescription(i),
588: addStyle(getFontStyle(10, ARIAL, BLACK),
589: "border", "1px solid #333333"));
590: startAndEndCell(1, inSctcc.getEntryValue(i), addStyle(
591: getFontStyle(10, ARIAL, BLACK), "border",
592: "1px solid #333333"));
593: endRow();
594: }
595: endTable();
596: }
597: //
598: //
599: setLeftMargin(staticMargin);
600: }
601:
602: private void processDynamic(
603: DynamicConceptTagConstraintContext inDctcc)
604: throws IOException {
605: //
606: //
607: DynamicConceptTagValidator dctv = inDctcc.getValidator();
608: ArrayList message = dctv.getMessages("(", ")", " ");
609: //
610: //
611: int dynamicMargin = getLeftMargin();
612: setLeftMargin(dynamicMargin + 1);
613: //
614: createHorizontalRow(0);
615: //
616: startAndEndSimpleTableAndRowAndCell(2,
617: "Dynamic Values Are Permitted", getFontStyle(12, ARIAL,
618: BLACK));
619: //startAndEndSimpleTableAndRowAndCell(
620: // 2, padNbsp(4) + "But Must Satisfy",
621: // getFontStyle(12, ARIAL, BLACK));
622: //
623: //
624: //displayArea(ArrayList inList, int inWidth)
625: startTable(2);
626: startRow();
627: //startAndEndCell(1, padNbsp(1));
628: startCell(2);
629: displayArea(message, 2);
630: endCell();
631: endRow();
632: endTable();
633: setLeftMargin(dynamicMargin);
634: }
635:
636: private void processCompound(
637: CompoundConceptTagConstraintContext inCctcc)
638: throws IOException {
639: //
640: createHorizontalRow(0);
641: //
642: startAndEndSimpleTableAndRowAndCell(2,
643: "Compound Values Are Permitted", getFontStyle(12,
644: ARIAL, BLACK));
645: for (int i = 0; i < inCctcc.getTemplateCount(); i++) {
646: //
647: ConceptTagConstraintTemplate ctcont = inCctcc
648: .getTemplate(i);
649: displayConstraint(ctcont);
650: }
651: }
652:
653: //
654: private final static ArrayList parseSelectionCriteria(
655: SelectionCriteriaForConceptTag inScfct, String inIndent) {
656: //
657: ArrayList outValue = new ArrayList();
658:
659: if (inScfct instanceof SelectionCriteriaForReturnableConceptTag) {
660: SelectionCriteriaForReturnableConceptTag scfrct = (SelectionCriteriaForReturnableConceptTag) inScfct;
661: //
662: Class prc[] = scfrct.getPossibleReturnClasses();
663: if (prc.length > 0) {
664: outValue.add("Returns one of the following");
665: for (int i = 0; i < prc.length; i++) {
666: outValue.add(inIndent
667: + StandardDataTypes.getDisplayName(prc[i]));
668: }
669: }
670: //
671: Class irc[] = scfrct.getImpossibleReturnClasses();
672: if (irc.length > 0) {
673: outValue.add("Returns none of the following");
674: for (int i = 0; i < irc.length; i++) {
675: outValue.add(inIndent
676: + StandardDataTypes.getDisplayName(irc[i]));
677: }
678: }
679: }
680:
681: outValue.add("Flag Settings -");
682: ConceptTagFlags ctf = inScfct.getFlags();
683: ArrayList namespaces = ctf.getAllNamespaces();
684: Collections.sort(namespaces);
685: for (int i = 0; i < namespaces.size(); i++) {
686: //
687: String nextNamespace = (String) namespaces.get(i);
688: ArrayList names = ctf.getAllNames(nextNamespace);
689: for (int j = 0; j < names.size(); j++) {
690: String nextName = (String) names.get(j);
691: outValue.add(inIndent + "(" + nextNamespace + ", "
692: + nextName + ") = '"
693: + ctf.getFlag(nextNamespace, nextName) + "'");
694: }
695: }
696:
697: return outValue;
698: }
699:
700: private final static ArrayList parseByCarriageReturn(String inValue) {
701:
702: ArrayList outValue = new ArrayList();
703:
704: StringTokenizer st = new StringTokenizer(inValue, "\n");
705: while (st.hasMoreTokens()) {
706: String nextToken = st.nextToken();
707: if (nextToken.length() > 0) {
708: outValue.addAll(parseParts(nextToken));
709: }
710: }
711:
712: return outValue;
713: }
714:
715: private final static ArrayList parseParts(String inValue) {
716:
717: ArrayList outValue = new ArrayList();
718:
719: String endValue = null;
720: String midValue = null;
721:
722: int paddingIndex = getFirstNonSpace(inValue);
723: String standardPadding = inValue.substring(0, paddingIndex);
724: String indentedStandardPadding = standardPadding + " ";
725: inValue = inValue.substring(paddingIndex);
726:
727: int endValueIndex = inValue.indexOf("</");
728: if (endValueIndex != -1) {
729: endValue = inValue.substring(endValueIndex);
730: inValue = inValue.substring(0, endValueIndex);
731: }
732: //
733: int midValueIndex = inValue.indexOf(">");
734: if (midValueIndex != -1) {
735: midValue = inValue.substring(midValueIndex + 1);
736: inValue = inValue.substring(0, midValueIndex + 1);
737: }
738: //
739: inValue = inValue.trim();
740:
741: int nextSpaceIndex = 0;
742: boolean valIsEle = (inValue.indexOf("<") != -1);
743: while (valIsEle
744: && (nextSpaceIndex = getNonQuoteSpace(inValue)) != -1) {
745: //
746: String nextSubValue = inValue.substring(0, nextSpaceIndex)
747: .trim();
748: if (outValue.size() > 0) {
749: outValue.add(indentedStandardPadding + nextSubValue);
750: } else {
751: outValue.add(standardPadding + nextSubValue);
752: }
753: inValue = inValue.substring(nextSpaceIndex).trim();
754: }
755: //
756: if (outValue.size() > 0) {
757: outValue.add(indentedStandardPadding + inValue);
758: } else {
759: outValue.add(standardPadding + inValue);
760: }
761:
762: //
763: if (midValue != null) {
764: outValue.add(indentedStandardPadding + midValue);
765: }
766: //
767: if (endValue != null) {
768: outValue.add(standardPadding + endValue);
769: }
770:
771: return outValue;
772: }
773:
774: private final static int getFirstNonSpace(String inValue) {
775:
776: int outValue = 0;
777:
778: for (int i = 0; i < inValue.length(); i++) {
779: //
780: if (inValue.charAt(i) != ' ') {
781: outValue = i;
782: break;
783: }
784: }
785:
786: return outValue;
787: }
788:
789: private final static int getNonQuoteSpace(String inValue) {
790:
791: int outValue = -1;
792:
793: for (int i = 0; i < inValue.length(); i++) {
794: //
795: if (inValue.charAt(i) == ' ' && isOutsideQuotes(inValue, i)) {
796: outValue = i;
797: break;
798: }
799: }
800:
801: return outValue;
802: }
803:
804: private final static boolean isOutsideQuotes(String inValue,
805: int inIndex) {
806:
807: boolean outValue = true;
808:
809: int quoteCount = 0;
810:
811: for (int i = 0; i < inIndex && i < inValue.length(); i++) {
812: if (inValue.charAt(i) == '"') {
813: quoteCount++;
814: }
815: }
816:
817: outValue = (quoteCount % 2 == 0);
818:
819: return outValue;
820: }
821: }
|