001: package de.webman.generator;
002:
003: import com.teamkonzept.lib.*;
004:
005: import java.util.*;
006: import java.sql.*;
007: import org.apache.log4j.Category;
008:
009: /**
010: * Verwaltet ein Dokument der Site-Struktur
011: * @author $Author: alex $
012: * @version $Revision: 1.5 $
013: */
014: public class SiteDocument implements Visitable {
015:
016: /**
017: Verweis zurück auf den aktuellen statischen Kontext des laufenden Threads
018: */
019: private GeneratorContext context;
020:
021: private static Category cat = Category
022: .getInstance(SiteDocument.class);
023:
024: public final static int DOC_TYPE_INTERN = 1;
025: public final static int DOC_TYPE_EXTERN = 2;
026:
027: /** Strukturknoten an dem das Dokument haengt */
028: private SiteNode anchor;
029:
030: /** Index des Dokuments innerhalb des Knotens */
031: private int idx;
032:
033: /** Typ des Dokuments (intern/extern) */
034: private int type;
035:
036: /** Presentation-Id, die dem Dokument zugrunde liegt */
037: private int presentationId;
038:
039: /** Name des Dokuments */
040: private String name;
041:
042: /** Name der zu generierenden Datei */
043: private String shortName;
044:
045: /** Ist das Dokument vererbbar */
046: private boolean inheritable;
047:
048: /** Ist die Vererbung für diesen Unterbaum schon behandelt ? */
049: private boolean heredityHandled;
050:
051: /** Wie ist die tatsaechliche URL (nur bei externen Dok.) */
052: private String url;
053:
054: /** Welches Template liegt den Dokument zugrunde */
055: private String templateName;
056:
057: /**
058: If the document is inheritable, the Intervall
059: [inheritStartLevel, inheritStopLevel]
060: indicate the hierachy level for which the
061: document is "valid" and generated.
062:
063: Example: let inheritStartLevel = 1
064: and inheritStopLevel = 2
065: then the document will be generated for the
066: children and the children of the children of the
067: documents anchor node.
068: */
069: private int inheritStartLevel = 0;// range: [0, Integer.MAX]
070: private int inheritStopLevel; // range: [0, Integer.MAX], -1 = infinite inheritance
071:
072: /** Ist das Dokument bereits vollständig aufgebaut ?
073: siehe SiteNode.reducedBuild */
074: private boolean isComplete;
075:
076: /** Liste der Referenzen des Dokuments (SiteReference)*/
077: private TKVector references;
078:
079: /** Vector von SiteContentIntegrations */
080: private TKVector contents;
081:
082: /** Key:Name Value: SiteContent */
083: private TKHashtable structContents;
084:
085: /**
086: true, if the document is refered by another document or if
087: it is a non-heritable document, else false.
088: Only refered documents are generated!
089: */
090: private boolean refered;
091:
092: /**
093: true, if the document was generated through inheritance else false.
094: */
095: private boolean virtual;
096:
097: /**
098: Vererbungskonstruktor
099: */
100: public SiteDocument(GeneratorContext context, SiteDocument src,
101: SiteNode node, int nodeDocIdx, int newInheritStartLevel,
102: int newInheritStopLevel) {
103: this .context = context != null ? context : GeneratorContext
104: .setup();
105:
106: this .anchor = node;
107: this .idx = nodeDocIdx;
108: this .type = src.type;
109: this .presentationId = src.presentationId;
110: this .name = src.name;
111: this .shortName = src.shortName;
112: this .inheritable = src.inheritable;
113: this .heredityHandled = true;
114: this .url = src.url;
115: this .refered = false;
116: this .isComplete = !this .context.siteNodes.isReducedBuild()
117: && !this .context.siteNodes.isIndexBuild();
118: this .virtual = true;
119: this .templateName = src.templateName;
120: this .inheritStartLevel = newInheritStartLevel;
121: this .inheritStopLevel = newInheritStopLevel;
122:
123: int refCount = src.references.size();
124: if (refCount == 0) {
125: this .references = new TKVector();
126: } else {
127: this .references = new TKVector(refCount);
128: for (int i = 0; i < refCount; i++) {
129: this .references.addElement(new SiteReference(
130: this .context, (SiteReference) src.references
131: .get(i), this ));
132: }
133: }
134: this .contents = src.contents;
135:
136: int structContCount = src.structContents.size();
137: if (structContCount == 0) {
138: this .structContents = new TKHashtable();
139: } else {
140: this .structContents = new TKHashtable(structContCount);
141: Enumeration e = src.structContents.keys();
142: while (e.hasMoreElements()) {
143: Object name = e.nextElement();
144: SiteContent sc = (SiteContent) src.structContents
145: .get(name);
146: this .structContents.put(name, anchor
147: .getStructureContents().get(
148: new Integer(sc.getFormularId())));
149: }
150: }
151: }
152:
153: /**
154: Konstruktor fuer definierte Dokumente
155: */
156: public SiteDocument(GeneratorContext context, ResultSet rs,
157: SiteNode node) throws SQLException {
158: this .context = context != null ? context : GeneratorContext
159: .setup();
160:
161: this .anchor = node;
162: this .idx = rs.getInt("SITE_NODE_DOC_IDX");
163: this .type = rs.getInt("DOCUMENT_TYPE");
164: this .presentationId = rs.getInt("PRESENTATION_ID");
165: this .name = rs.getString("DOCUMENT_NAME");
166: this .shortName = rs.getString("DOCUMENT_SHORTNAME");
167: this .templateName = rs.getString("TEMPLATE_NAME");
168: this .inheritable = (rs.getInt("INHERITABLE") == 1);
169: this .heredityHandled = !this .inheritable;
170: this .isComplete = !this .context.siteNodes.isReducedBuild()
171: && !this .context.siteNodes.isIndexBuild();
172: this .url = (type == DOC_TYPE_EXTERN ? rs
173: .getString("EXTERNAL_URL") : null);
174:
175: this .inheritStopLevel = rs.getInt("INHERIT_END_LEVEL");
176: this .inheritStartLevel = rs.getInt("INHERIT_BEGIN_LEVEL");
177:
178: this .references = new TKVector();
179: this .contents = new TKVector();
180: this .structContents = new TKHashtable();
181:
182: this .refered = false;
183: this .virtual = false;
184: }
185:
186: public String path() {
187: return anchor.path() + "." + shortName;
188: }
189:
190: public String getPath() {
191: return anchor.getPath() + "/" + shortName;
192: }
193:
194: public String toString() {
195: String result = "<document '" + path() + "'>" + " idx = " + idx
196: + " type = "
197: + (type == DOC_TYPE_INTERN ? "INTERN" : "EXTERN")
198: + " presentation = " + presentationId + " templat = "
199: + templateName + " inheritable = " + inheritable
200: + " refered = " + refered + " virtual = " + virtual
201: + " ";
202:
203: result += " document references:";
204: Enumeration e = references.elements();
205: while (e.hasMoreElements()) {
206: result += " " + e.nextElement();
207: }
208:
209: result += " document contents:";
210: e = contents.elements();
211: while (e.hasMoreElements()) {
212: result += " " + e.nextElement();
213: }
214:
215: result += " structure contents:";
216: e = structContents.keys();
217: while (e.hasMoreElements()) {
218: Object o = e.nextElement();
219: result += " " + o + ":=" + structContents.get(o);
220: }
221:
222: return result + " </document '" + path() + "'> ";
223: }
224:
225: /**
226: @result = 0 := keine weiteren Einträge in ResultSet
227: > 0 := doc-Index des nächsten Eintrags, falls dieser
228: im gleichen Node liegt
229: < 0 := -node_id des nächsten Eintrags
230: */
231:
232: public int traverse(int mode, String nodeColName,
233: String idxColName, ResultSet rs, int docNodeId)
234: throws SQLException {
235: int docIdx = idx;
236: while (docIdx == idx) {
237: if (mode == SiteNode.DOC_TRAV_MODE_REFERENCE) {
238:
239: // singh + 1999.06.25 durch unvollständige Site entstehen ggf. undef. Referenzen
240: SiteReference ref = new SiteReference(context, rs, this );
241: if (ref.getDestinationNode() == null) {
242: String undefPath = anchor.getPath();
243: String ignorePath = (context.siteNodes
244: .getSubtreeNode() == null)
245: || (context.siteNodes.getSubtreeNode()
246: .getParent() == null) ? ""
247: : context.siteNodes.getSubtreeNode()
248: .getParent().getPath();
249:
250: if (!ignorePath.startsWith(undefPath))
251: cat.warn("Undefined reference from "
252: + undefPath + " to site-node "
253: + rs.getInt("DEST_SITE_NODE_ID"));
254:
255: } else
256: references.addElement(ref);
257: } else if (mode == SiteNode.DOC_TRAV_MODE_CONTENT) {
258: contents.addElement(new SiteContentIntegration(context,
259: rs, this ));
260: } else if (mode == SiteNode.DOC_TRAV_MODE_STRUCT_CONTENT) {
261: int formId = rs.getInt("FORM_ID");
262: String shortName = rs
263: .getString("INTEGRATION_SHORTNAME");
264: Object sc = anchor.getStructureContents().get(
265: new Integer(formId));
266: if (sc == null) {
267: cat.error("Missing structure content " + shortName
268: + " in document " + path());
269: } else
270: structContents.put(shortName, sc);
271: } else
272: return 0;
273: if (!rs.next())
274: return 0;
275: int nextNodeId = rs.getInt(nodeColName);
276: if (nextNodeId != docNodeId)
277: return -nextNodeId;
278: docIdx = rs.getInt(idxColName);
279: }
280: return docIdx;
281: }
282:
283: public void expandReferences()
284: {
285: if( refered ) return;
286: refered = true;
287: TKVector foundReferences = new TKVector();
288: Enumeration enum = references.elements();
289: while( enum.hasMoreElements() )
290: {
291: SiteReference ref = (SiteReference) enum.nextElement();
292: context.siteReferences.increaseLevel();
293: try
294: {
295: ref.expand();
296: foundReferences.addElement(ref);
297: }
298: catch( Throwable t )
299: {
300: cat.error( "Could not expand reference " + ref.getIntegrationShortName()
301: + " of document " + path()+" reason: ", t);
302: // references.removeElement(ref);
303: }
304: context.siteReferences.decreaseLevel();
305: }
306: references = foundReferences;
307: }
308:
309: public void findReferenceContentDocuments()
310: {
311: Enumeration enum = references.elements();
312: TKVector validReferences = new TKVector();
313: while ( enum.hasMoreElements()) {
314: SiteReference ref = (SiteReference) enum.nextElement();
315: boolean found = false;
316: try
317: {
318: found = ref.findMatchingContentSource();
319: if (found)
320: validReferences.addElement(ref);
321: }
322: catch( Throwable t )
323: {
324: cat.warn( "Could not find content for reference" + ref.getIntegrationShortName()
325: + " of document " + path(), t );
326: }
327: if( !found )
328: {
329: cat.info( "reference "+ ref.getIntegrationShortName() + " of document " + getPath() + " not found" );
330: // references.removeElement(ref);
331: }
332: }
333: references = validReferences;
334: }
335:
336: public void doContentSelections() {
337: // Hier wird vielleicht im Preview zuviel gemacht ???
338: if (!virtual && inheritStartLevel > 0) {
339: doRealContentSelections();
340: return;
341: }
342: if (virtual || (!refered && !context.siteNodes.isIndexBuild()))
343: return;
344: doRealContentSelections();
345: }
346:
347: private void doRealContentSelections() {
348: Enumeration e = contents.elements();
349: while (e.hasMoreElements()) {
350: ((SiteContentIntegration) e.nextElement()).select();
351: }
352: }
353:
354: /**
355: Adds all generatable contents into the Hashtable <code>result</code>
356: */
357: private void addGenContents(TKHashtable result,
358: SiteContent primaryContent) {
359: Enumeration e = contents.elements();
360: while (e.hasMoreElements()) {
361: SiteContentIntegration cont = (SiteContentIntegration) e
362: .nextElement();
363: TKVector conts = cont.getContents();
364: if (conts == null) {
365: if (primaryContent != null)
366: result.put(cont.getShortName(), primaryContent);
367: } else if (cont.getIntegrationType() == SiteReference.INTEGRATION_TYPE_SINGLE) {
368: if (conts.size() == 0) {
369: cat
370: .error("no content for integration type single in document "
371: + getPath());
372: return; // checken, ob das sauber ist ! vorher error geschmissen !
373: }
374: result.put(cont.getShortName(), conts.get(0));
375: } else {
376: result.put(cont.getShortName(), conts);
377: }
378: }
379: }
380:
381: private void addGenStructContents(TKHashtable result) {
382: Enumeration e = structContents.keys();
383: while (e.hasMoreElements()) {
384: Object o = e.nextElement();
385: result.put(o, structContents.get(o));
386: }
387:
388: }
389:
390: private void addGenReferences(TKHashtable result) {
391: Enumeration e = references.elements();
392: while (e.hasMoreElements()) {
393: ((SiteReference) e.nextElement()).addGenReference(result);
394: }
395: }
396:
397: public GenDocument getGenDocument(SiteContent primaryContent,
398: GenNode anchor) {
399: String genId = "id_"
400: + anchor.getSiteNode().getId()
401: + "_pid_"
402: + (primaryContent == null ? -1 : primaryContent
403: .getContentId()) + "_idx_" + idx;
404:
405: GenDocument doc = (GenDocument) context.genDocuments
406: .getGeneratedDocument(genId);
407: if (doc != null)
408: return doc;
409:
410: TKHashtable genContents = new TKHashtable();
411:
412: addGenContents(genContents, primaryContent);
413: addGenStructContents(genContents);
414:
415: TKHashtable genReferences = new TKHashtable();
416: addGenReferences(genReferences);
417:
418: doc = new GenDocument(context, anchor, shortName, templateName,
419: url, genContents, genReferences);
420: context.genDocuments.putGeneratedDocument(genId, doc);
421: return doc;
422: }
423:
424: // singh + 1999.04.08
425: public void complete() {
426:
427: if (isComplete)
428: return;
429: isComplete = true;
430:
431: anchor.complete();
432:
433: expandReferences();
434: findReferenceContentDocuments();
435: doContentSelections();
436: }
437:
438: /**
439: Classifies the document with respect to a hierarchy level.
440: If the document is inheritable, this function checks, if <code>level</code>
441: lies in, above or below the documents inheritation-intervall.
442: If the document is _not_ inheritable, this function checks, if
443: <code>level</code> lies in, above or below the documents level.
444: @param level the (absolute) hierarchy level
445: @return -1 <code>level</code> is smaller than the valid document intervall
446: 0 <code>level</code> lies in the valid document intervall
447: 1 <code>level</code>is bigger than the valid document intervall
448: */
449: public int classifyByLevel(int level) {
450: int start;
451: int stop;
452: if (inheritable) {
453: start = anchor.getLevel() + inheritStartLevel;
454: if (inheritStopLevel < 0) { // infinite inheritance
455: stop = Integer.MAX_VALUE;
456: } else {
457: stop = anchor.getLevel() + inheritStopLevel;
458: }
459: } else {
460: start = anchor.getLevel();
461: stop = anchor.getLevel();
462: }
463:
464: if (level < start) {
465: return -1;
466: } else if (level > stop) {
467: return +1;
468: } else {
469: return 0;
470: }
471: }
472:
473: public void accept(SiteTreeVisitor visitor) throws Exception {
474: visitor.visitSiteDocument(this );
475: }
476:
477: public String getShortName() {
478: return shortName;
479: }
480:
481: public int getPresentationId() {
482: return presentationId;
483: }
484:
485: public SiteNode getAnchor() {
486: return anchor;
487: }
488:
489: public String getURL() {
490: return url;
491: }
492:
493: public boolean isInheritable() {
494: return inheritable;
495: }
496:
497: public int getInheritStartLevel() {
498: return inheritStartLevel;
499: }
500:
501: public int getInheritStopLevel() {
502: return inheritStopLevel;
503: }
504:
505: public boolean isRefered() {
506: return refered;
507: }
508:
509: public int getIndex() {
510: return idx;
511: }
512:
513: public String getTemplateName() {
514: return templateName;
515: }
516:
517: public String getName() {
518: return name;
519: }
520:
521: public TKVector getReferences() {
522: return references;
523: }
524:
525: public TKVector getContents() {
526: return contents;
527: }
528:
529: public TKHashtable getStructureContents() {
530: return structContents;
531: }
532:
533: }
|