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.common.tagging;
009:
010: //base classes
011: import java.util.ArrayList;
012: import org.w3c.dom.Element;
013: import org.w3c.dom.Node;
014: import org.w3c.dom.NodeList;
015:
016: //project specific classes
017: import org.jfolder.common.UnexpectedSystemException;
018: import org.jfolder.common.utils.misc.CommonSeparators;
019: import org.jfolder.common.utils.misc.MiscHelper;
020: import org.jfolder.common.utils.xml.XMLHelper;
021:
022: //other classes
023:
024: public class ConceptTagMenuBranch {
025:
026: private final static String ROOT_NAME = "Root";
027:
028: private String name = null;
029: private ArrayList subNodes = null;
030:
031: protected ConceptTagMenuBranch(ConceptTagSetHolder inCtsh) {
032: //
033: this (ROOT_NAME);
034:
035: //
036: //ArrayList namespaces = inCtsh.getRegisteredNameSpaces();
037: //for (int i = 0; i < namespaces.size(); i++) {
038: // String nextNamespace = (String)namespaces.get(i);
039: //
040: // ArrayList names = inCtsh.getRegisteredNames(nextNamespace);
041: // for (int j = 0; j < names.size(); j++) {
042: // String nextName = (String)names.get(j);
043: // String nextClass = inCtsh.getConceptTagClassAsString(
044: // nextNamespace, nextName);
045: // ConceptTagProperties nextProps =
046: // inCtsh.getConceptTagProperties(nextClass);
047: // initialize(
048: // nextNamespace, nextName, nextProps.getMenuPath(), 0);
049: // }
050: //}
051: }
052:
053: private ConceptTagMenuBranch(String inName) {
054: this .name = inName;
055: this .subNodes = new ArrayList();
056: }
057:
058: public ConceptTagMenuBranch duplicate() {
059:
060: ConceptTagMenuBranch outValue = new ConceptTagMenuBranch(
061: this .name);
062:
063: for (int i = 0; i < this .subNodes.size(); i++) {
064:
065: if (isChildNodeBranch(i)) {
066: outValue.subNodes.add(getChildNodeAsBranch(i)
067: .duplicate());
068: } else if (isChildNodeOption(i)) {
069: outValue.subNodes.add(getChildNodeAsOption(i)
070: .duplicate());
071: }
072: }
073:
074: return outValue;
075: }
076:
077: public String getName() {
078: return this .name;
079: }
080:
081: public int getChildNodeCount() {
082: return this .subNodes.size();
083: }
084:
085: private boolean isBranchEmpty() {
086: return (this .subNodes.size() == 0);
087: }
088:
089: public boolean isChildNodeBranch(int inIndex) {
090: return (this .subNodes.get(inIndex) instanceof ConceptTagMenuBranch);
091: }
092:
093: public boolean isChildNodeOption(int inIndex) {
094: return (this .subNodes.get(inIndex) instanceof ConceptTagMenuOption);
095: }
096:
097: public ConceptTagMenuBranch getChildNodeAsBranch(int inIndex) {
098: return ((ConceptTagMenuBranch) this .subNodes.get(inIndex));
099: }
100:
101: public ConceptTagMenuOption getChildNodeAsOption(int inIndex) {
102: return ((ConceptTagMenuOption) this .subNodes.get(inIndex));
103: }
104:
105: protected void initialize(String inNs, String inName,
106: String inMenuPath[]) {
107: //
108: if (inMenuPath != null) {
109: initialize(inNs, inName, inMenuPath, 0);
110: }
111: //else {
112: // MiscHelper.println(
113: // "No menu path found for \"" + inNs + ":" + inName + "\"");
114: // //
115: // int menuHash = (((inNs + ":" + inName).hashCode())%25);
116: // String sampleMenu[] = new String[]{
117: // ((menuHash/5) + ""), ((menuHash%5) + "")};
118: // initialize(inNs, inName, sampleMenu, 0);
119: // //
120: // MiscHelper.println("Adding random assignment, but remove later");
121: //}
122: }
123:
124: private void initialize(String inNamespace, String inName,
125: String inMenuPath[], int inIndex) {
126:
127: ConceptTagMenuBranch ctmb = null;
128: if (inIndex < inMenuPath.length) {
129: for (int i = 0; i < this .subNodes.size(); i++) {
130: if (isChildNodeBranch(i)) {
131: ConceptTagMenuBranch nextCtmb = getChildNodeAsBranch(i);
132: if (nextCtmb.getName().equals(inMenuPath[inIndex])) {
133: ctmb = nextCtmb;
134: }
135: }
136: }
137: if (ctmb == null) {
138: ctmb = new ConceptTagMenuBranch(inMenuPath[inIndex]);
139: this .subNodes.add(ctmb);
140: }
141: //create or use branch
142: ctmb.initialize(inNamespace, inName, inMenuPath,
143: inIndex + 1);
144: } else {
145: //create or use option
146: ConceptTagMenuOption ctmo = new ConceptTagMenuOption(
147: inNamespace, inName);
148: this .subNodes.add(ctmo);
149: }
150:
151: }
152:
153: public final static ConceptTagMenuBranch qualifyNodes(
154: ConceptTagMenuBranch inCtmb,// ConceptTagMenuQualifier inTmq,
155: ConceptTagSetHolder inCtsh,
156: DynamicConceptTagValidator inDctv) {
157:
158: //MiscHelper.println("inTmb = " + inTmb);
159: ConceptTagMenuBranch outValue = inCtmb.duplicate();
160:
161: outValue.qualifyNodes(inCtsh, inDctv);
162:
163: return outValue;
164: }
165:
166: private void qualifyNodes(
167: //ConceptTagMenuQualifier inTmq,
168: ConceptTagSetHolder inCtsh,
169: DynamicConceptTagValidator inDctv) {
170:
171: for (int i = 0; i < this .getChildNodeCount(); i++) {
172: if (this .isChildNodeBranch(i)) {
173: ConceptTagMenuBranch nextBranch = this
174: .getChildNodeAsBranch(i);
175: nextBranch.qualifyNodes(inCtsh, inDctv);
176:
177: //remove branch if empty
178: if (nextBranch.isBranchEmpty()) {
179: this .subNodes.remove(i);
180: i--;
181: }
182: } else if (this .isChildNodeOption(i)) {
183:
184: ConceptTagMenuOption nextOption = this
185: .getChildNodeAsOption(i);
186: //
187: //ConceptTagProperties nextOptionProps =
188: // inCtsh.getConceptTagProperties(nextOptionClass.getName());
189: //
190: //result &=
191: // (!nextOptionProps.isAllowInUnconstrainedContextOnly()
192: // || inAllowUnconstrainedOnly);
193: //for (int j = 0; j < acceptClasses.length; j++) {
194: // result |= inTmq.isOptionAvailable(acceptClasses[j],
195: // inClassRestrictions,
196: //indetermineValueAndClassRestrictions,
197: // indetermineValueAndClassExclusions);
198: //}
199: String nextOptionNamespace = nextOption.getNamespace();
200: String nextOptionName = nextOption.getName();
201: Class nextOptionClass = inCtsh.getConceptTagClass(
202: nextOptionNamespace, nextOptionName);
203: Object o = MiscHelper.newInstance(nextOptionClass);
204: //
205: if (!validateOption(inCtsh, nextOption, inDctv)) {
206: MiscHelper.println("ConTagMenBran REMOV NODE o = "
207: + o);
208: this .subNodes.remove(i);
209: i--;
210: }
211: }
212: }
213: }
214:
215: //
216: //
217: //
218: public final static String generateInitializationCode(
219: ConceptTagMenuBranch inCtmb, ConceptTagSetHolder inCtsh,
220: DynamicConceptTagValidator inDctv) {
221:
222: StringBuffer outValue = new StringBuffer();
223:
224: generateInitializationCode(inCtmb, inCtsh, inDctv, outValue,
225: null);
226:
227: return outValue.toString();
228: }
229:
230: private final static boolean generateInitializationCode(
231: ConceptTagMenuBranch inCtmb, ConceptTagSetHolder inCtsh,
232: DynamicConceptTagValidator inDctv, StringBuffer inSb,
233: Integer inIndex) {
234: //
235: boolean outValue = false;
236:
237: //ArrayList activeNodes = new ArrayList();
238:
239: int initialSbEnd = inSb.length();
240:
241: if (inIndex != null) {
242: inSb.append(CommonSeparators.SEPARATOR__SUB_SECTION_START);
243: inSb.append(inIndex);
244: }
245:
246: for (int i = 0; i < inCtmb.getChildNodeCount(); i++) {
247: if (inCtmb.isChildNodeOption(i)) {
248:
249: ConceptTagMenuOption nextOption = inCtmb
250: .getChildNodeAsOption(i);
251:
252: if (validateOption(inCtsh, nextOption, inDctv)) {
253: //activeNodes.add(i + "");
254: inSb
255: .append(CommonSeparators.SEPARATOR__SUB_SECTION_START);
256: inSb.append(i);
257: inSb
258: .append(CommonSeparators.SEPARATOR__SUB_SECTION_END);
259: outValue = true;
260: }
261: } else if (inCtmb.isChildNodeBranch(i)) {
262: //inBranch.add(i + "");
263: ConceptTagMenuBranch nextBranch = inCtmb
264: .getChildNodeAsBranch(i);
265: outValue |= generateInitializationCode(nextBranch,
266: inCtsh, inDctv, inSb, new Integer(i));
267: //inBranch.remove(inBranch.size() - 1);
268: } else {
269: throw UnexpectedSystemException.unknownState();
270: }
271: }
272:
273: //outValue |= (activeNodes.size() > 0);
274: if (inIndex != null) {
275: inSb.append(CommonSeparators.SEPARATOR__SUB_SECTION_END);
276: }
277: //
278: //
279: //
280: if (!outValue) {
281: inSb.delete(initialSbEnd, inSb.length());
282: }
283:
284: return outValue;
285: }
286:
287: private final static boolean validateOption(
288: ConceptTagSetHolder inCtsh, ConceptTagMenuOption inCtmo,
289: DynamicConceptTagValidator inDctv) {
290:
291: boolean outValue = false;
292: //
293: String nextOptionNamespace = inCtmo.getNamespace();
294: String nextOptionName = inCtmo.getName();
295: Class nextOptionClass = inCtsh.getConceptTagClass(
296: nextOptionNamespace, nextOptionName);
297: //
298: //Class acceptClasses[] =
299: //inTmq.getReturnClasses(nextOptionClass);
300: Object o = MiscHelper.newInstance(nextOptionClass);
301: SelectionCriteriaForConceptTag scfct = SelectionCriteriaForConceptTag
302: .newInstance(inCtsh
303: .getConceptTagFromClass(nextOptionClass));
304: if (o instanceof ReturnableConceptTag) {
305: ReturnableConceptTag rct = (ReturnableConceptTag) o;
306: //SelectionCriteriaForReturnableConceptTag scfrct =
307: // new SelectionCriteriaForReturnableConceptTag(rct);
308: (rct).appraise(scfct);
309: if (!scfct.isInitialized()) {
310: throw new UnexpectedSystemException(
311: "ReturnableConceptTag '"
312: + nextOptionClass
313: + "' does not fully initialize "
314: + "SelectionCriteriaForReturnableConceptTag"
315: + " in the 'appraise' function");
316: }
317: //scfct = scfrct;
318: } else if (o instanceof ConceptTag) {
319: ConceptTag ct = (ConceptTag) o;
320: //scfct = new SelectionCriteriaForConceptTag(ct);
321: ct.appraise(scfct);
322: } else {
323: throw new UnexpectedSystemException("Class '"
324: + nextOptionClass.getName()
325: + "' does not implemented ConceptTag");
326: }
327: MiscHelper.println("ConTagMenBran o = " + o);
328: ArrayList resultList = inDctv.validate(scfct, null, true);
329:
330: outValue |= (resultList.size() == 0);
331:
332: ////////////////////////////////////////
333: for (int j = 0; j < resultList.size(); j++) {
334: MiscHelper.println(" ConTagMenBran Error = "
335: + resultList.get(j));
336: }
337: //MiscHelper.println("ConTagMenBran o = " + o);
338: MiscHelper.println(" ConTagMenBran result = " + outValue);
339:
340: return outValue;
341: }
342:
343: //
344: //
345: //
346: public boolean seekConceptTagLocation(ArrayList inLocation,
347: String inNamespace, String inName) {
348: //
349: boolean outValue = false;
350:
351: for (int i = 0; i < getChildNodeCount(); i++) {
352: //
353: inLocation.add(i + "");
354: //
355: if (isChildNodeBranch(i)) {
356: //
357: ConceptTagMenuBranch nextCtmb = getChildNodeAsBranch(i);
358: outValue |= nextCtmb.seekConceptTagLocation(inLocation,
359: inNamespace, inName);
360: } else if (isChildNodeOption(i)) {
361: //
362: ConceptTagMenuOption nextCtmo = getChildNodeAsOption(i);
363: if (nextCtmo.getNamespace() == null
364: && inNamespace == null) {
365: //
366: outValue |= (inName.equals(nextCtmo.getName()));
367: } else if (nextCtmo.getNamespace() != null
368: && inNamespace != null) {
369: //
370: outValue |= (inName.equals(nextCtmo.getName()) && inNamespace
371: .equals(nextCtmo.getNamespace()));
372: } else {
373: outValue |= false;
374: }
375: } else {
376: throw UnexpectedSystemException.unknownState();
377: }
378: //
379: if (outValue) {
380: break;
381: }
382: //
383: inLocation.remove(inLocation.size() - 1);
384: }
385:
386: return outValue;
387: }
388: }
|