001: package de.webman.content.eventhandler;
002:
003: import com.teamkonzept.webman.*;
004: import de.webman.acl.Policy;
005: import com.teamkonzept.web.*;
006: import com.teamkonzept.webman.mainint.*;
007: import com.teamkonzept.webman.mainint.db.*;
008: import com.teamkonzept.webman.mainint.db.queries.*;
009: import com.teamkonzept.webman.mainint.events.*;
010: import com.teamkonzept.lib.*;
011: import com.teamkonzept.field.*;
012: import com.teamkonzept.db.*;
013: import com.teamkonzept.international.LanguageManager;
014: import de.webman.acl.*;
015: import de.webman.content.workflow.*;
016: import de.webman.content.db.queries.SelectShortnamesFromContentTree;
017: import de.webman.sitetree.eventhandler.SiteTreeUtils;
018: import de.webman.content.Content;
019: import com.oroinc.text.regex.*;
020: import java.util.*;
021: import java.sql.*;
022: import java.text.CharacterIterator;
023: import java.text.StringCharacterIterator;
024: import java.io.File;
025:
026: import org.apache.log4j.Category;
027:
028: /**
029: * Sammlung von Content Utility Routinen
030: * @author $Author: uli $
031: * @version $Revision: 1.33 $
032: */
033: public class CEUtils implements DatabaseDefaults, UserCodes,
034: ParameterTypes {
035: /** logging category */
036: private static Category cat = Category.getInstance(CEUtils.class);
037:
038: /** überprüft ob der User das Recht für den Event auf dem aktuellen
039: Contentnode besitzt
040: @param evt - der aktuelle Event
041: @throws Throwable - if Error occures during Right checking
042: */
043: public static void checkEvent(TKEvent evt) throws Throwable {
044: String cid = evt.getParameter(PARAMETER, "CONTENT_NODE_ID");
045: WebManEvent
046: .checkEvent(evt.getRemoteUser(), evt.getName(),
047: ContextConstants.CONTENT_EDIT,
048: Policy.CONTENT_TREE_ID, new Integer(cid != null
049: && cid.length() > 0 ? cid : "1"));
050: }
051:
052: /** übergebe String s mache daraus vector (wobei die Elemente in s durch ; getrennt sind **/
053:
054: private static Vector getPartSelectedContentsList(String s) {
055: Vector back = new Vector();
056: if ((s == null) || (s.length() == 0))
057: return (null);
058: int top = 0;
059: int bottom = s.indexOf(';');
060: while (bottom != -1) {
061: back.add(new String(s.substring(top, bottom)));
062: top = bottom + 1;
063: bottom = s.indexOf(';', bottom + 1);
064: }
065: return (back);
066: }
067:
068: /**
069: * macht aus dem Parameter SELECTED_CONTENTS_LIST einen Vector mit allen Contents
070: **/
071: public static Vector getSelectedContentsList(TKEvent evt) {
072: Vector back = new Vector();
073: String sList = evt.getParameter(PARAMETER,
074: "SELECTED_CONTENTS_LIST");
075: String notList = evt.getParameter(PARAMETER,
076: "NOT_SELECTED_CONTENTS_LIST");
077:
078: if ((sList == null) || (sList.length() == 0))
079: return (null);
080:
081: back = getPartSelectedContentsList(sList.substring(0, sList
082: .indexOf('-')));
083: Vector nachher = getPartSelectedContentsList(sList
084: .substring(sList.indexOf('-') + 1));
085: if (back == null)
086: return (nachher);
087:
088: // nehme nicht selectierte Contents raus
089: Vector notinList = getPartSelectedContentsList(notList);
090: if (notinList != null) {
091: for (int i = 0; i < notinList.size(); i++)
092: back.remove(notinList.elementAt(i));
093: }
094:
095: if (nachher == null)
096: return (back);
097:
098: for (int i = 0; i < nachher.size(); i++) {
099: if (!back.contains(nachher.elementAt(i)))
100: back.add(nachher.elementAt(i));
101: }
102: return (back);
103: }
104:
105: /**
106: * schreibt den Vector der Instances in einen String
107: *
108: * @param vec
109: *
110: */
111: public static String getSelectedContentsString(Vector vec) {
112: String back = "";
113: if (vec != null) {
114: for (int i = 0; i < vec.size(); i++)
115: back = (String) (vec.elementAt(i)) + ";" + back;
116: }
117: return back;
118: }
119:
120: /**
121: * schleift die Liste der markierten Contents durch
122: *
123: * @param evt (dort holt er die Parameter raus)
124: * @param t (hier setzt er die Parameter ein)
125: */
126: public static void keepSelectedContents(TKEvent evt, TemplateBasic t) {
127: Vector keep = getSelectedContentsList(evt);
128: t.set("SELECTED_CONTENTS_LIST", new String(
129: getSelectedContentsString(keep)));
130: }
131:
132: /** checked ob das Recht für den evt (evtname) auf dem contentnode nodeID verfügbar ist
133: *
134: * @param user (der momentane User)
135: * @param evtname (Name des Events)
136: * @param nodeID (Content_Node_ID)
137: * @return boolean (true falls erlaubt sonst false)
138: */
139: public static boolean isAllowedEvent(String user, String evtname,
140: Integer nodeID) throws TKException {
141: /* hole Login */
142: LoginFactory factory = LoginFactory.getInstance();
143: Login login = factory.getLogin(user);
144: /* hole Event */
145: Event evt = EventFactory.getInstance().getEvent(evtname);
146:
147: if (login.isAllowed(evt.getID(), ContextConstants.CONTENT_EDIT,
148: Policy.CONTENT_TREE_ID, nodeID))
149: return true;
150: return false;
151: }
152:
153: /** checked ob das Recht für den evt (evtname) im Context content_edit verfügbar ist
154: *
155: * @param user (der momentane user)
156: * @param evtname (Name des Events)
157: * @return boolean (true falls erlaubt sonst false)
158: */
159: public static boolean isAllowedEvent(String user, String evtname)
160: throws TKException {
161: /* hole Login */
162: LoginFactory factory = LoginFactory.getInstance();
163: Login login = factory.getLogin(user);
164: /* hole Event */
165: Event evt = EventFactory.getInstance().getEvent(evtname);
166:
167: if (login.isAllowed(evt.getID(), ContextConstants.CONTENT_EDIT))
168: return true;
169: return false;
170: }
171:
172: /**
173: ueberprueft Abhaengigkeiten ContentTree / Sitetree
174: @param contentNodeID Id des zu checkenden Contents
175: @param subtree nur der Knoten oder auch seine Kinder ?
176: */
177: public static boolean checkDependencies(Integer contentNodeID,
178: TKVector depends, boolean subtree) throws SQLException {
179: TKQuery q = TKDBManager
180: .newQuery(TKDBContentTreeIsDependent.class);
181: q.setQueryParams("CONTENT_NODE_ID", contentNodeID);
182: q.execute();
183: ResultSet rs = q.fetchResultSet();
184: boolean isDependent = false;
185: while (rs.next()) {
186: int id = rs.getInt("CT_CONTENT_NODE_ID");
187: if (subtree || id == contentNodeID.intValue()) {
188: TKHashtable temp = new TKHashtable();
189: String cName = rs.getString("CT_CONTENT_NODE_NAME");
190: String sNodeID = rs.getString("ST_SITE_NODE_ID");
191: if (sNodeID == null)
192: sNodeID = rs.getString("SD_SITE_NODE_ID");
193: String docName = rs.getString("SD_DOCUMENT_SHORTNAME");
194: String contentNodeType = rs
195: .getString("CT_CONTENT_NODE_TYPE");
196: if (sNodeID == null) {
197: Object[] tmp = new Object[1];
198: tmp[0] = cName;
199: String text = "NOT_REFERENCED";
200: if (contentNodeType.equals(GROUP))
201: text = "GROUP_NOT_REFERENCED";
202: String message = LanguageManager.getText("content",
203: text, tmp);
204: temp.put("REF2", message);
205: depends.addElement(temp);
206: continue; // keine Abhaengigkeit
207: }
208: isDependent = true;
209: String path = SiteTreeUtils.getCurrentPath(new Integer(
210: sNodeID));
211: if (docName != null)
212: path += docName;
213: Object[] tmp = new Object[2];
214: tmp[0] = cName;
215: tmp[1] = path;
216: String text = "REFERENCED";
217: if (contentNodeType.equals(GROUP))
218: text = "GROUP_REFERENCED";
219:
220: String message = LanguageManager.getText("content",
221: text, tmp);
222: cat.debug("Got : ");
223: temp.put("REF2", message);
224: depends.addElement(temp);
225: }
226: }
227: return isDependent;
228: }
229:
230: /**
231: checkt, ob innerhalb einer Contentgruppe ein Shortname schon mal vergeben wurde
232: @param contentNodeId ID des Contents, null falls neu
233: @param shortName der zu speichernde Shortname (Kennung)
234: @param neu, wird ein neuer Content
235: @exception falls es einen Konflikt gibt
236: */
237: public static void checkShortName(Integer contentNodeId,
238: Integer groupID, String shortName) throws SQLException,
239: TKUserException {
240: // Query
241: TKQuery q = TKDBManager
242: .newQuery(SelectShortnamesFromContentTree.class);
243: q.setQueryParams("CONTENT_NODE_ID", groupID);
244: q.setQueryParams("CONTENT_NODE_SHORTNAME", shortName);
245: q.execute();
246: // System.out.println("Checking Shortname : " + shortName);
247: // resultSet auswerten
248: ResultSet rs = q.fetchResultSet();
249: int count = 0;
250: if (rs.next()) {
251: count++;
252: // System.out.println("Got result : " + count);
253: if (contentNodeId == null)
254: throw new TKUserException("Doppelte Kennung",
255: DOUBLE_SHORTNAME, USER_SEVERITY, false, null); // Exception
256: else {
257: int existingId = rs.getInt("CONTENT_NODE_ID");
258: if (existingId != contentNodeId.intValue()) {
259: throw new TKUserException("Doppelte Kennung",
260: DOUBLE_SHORTNAME, USER_SEVERITY, false,
261: null); // Exception
262: }
263: }
264: }
265: }
266:
267: /**
268: * schleift die Sortierparameter durch
269: *
270: * @param evt (dort holt er die Parameter raus)
271: * @param t (hier setzt er die Parameter ein)
272: */
273: public static void keepSortParameter(TKEvent evt, TemplateBasic t) {
274: String evtName = evt.getName();
275: String sort_by = evt.getParameter("SORT_BY", evtName);
276: if (sort_by != null) {
277:
278: String sort_up_down = evt.getParameter("SORT_UP_DOWN",
279: evtName);
280: evt.getParams().put(PARAMETER, "SORT_BY", sort_by);
281: evt.getParams()
282: .put(PARAMETER, "SORT_UP_DOWN", sort_up_down);
283: }
284: // warum wird das hier noch mal abgefragt,
285: // das haben wir doch gesetzt???
286: // weil es auch direkt übergeben werden kann (wenn sort_by == null)
287: if (evt.getParameter(PARAMETER, "SORT_BY") != null) {
288: t.set("SORT_BY", new String(evt.getParameter(PARAMETER,
289: "SORT_BY")));
290: t.set("SORT_UP_DOWN", new String(evt.getParameter(
291: PARAMETER, "SORT_UP_DOWN")));
292: }
293: }
294:
295: /**
296: * Überführt den String <name> in einen brauchbaren Dateinamen, d.h.
297: * es werde spaces, Umlaute etc. ersetzt.
298: */
299: public static String toFilename(final String name) {
300: final StringBuffer fname = new StringBuffer(name.length());
301: final StringCharacterIterator iter = new StringCharacterIterator(
302: name);
303: for (char ch = iter.current(); ch != CharacterIterator.DONE; ch = iter
304: .next()) {
305: switch (ch) {
306: case 'ä':
307: fname.append("ae");
308: break;
309: case 'Ä':
310: fname.append("Ae");
311: break;
312: case 'ö':
313: fname.append("oe");
314: break;
315: case 'Ö':
316: fname.append("Oe");
317: break;
318: case 'ü':
319: fname.append("ue");
320: break;
321: case 'Ü':
322: fname.append("Ue");
323: break;
324: case 'ß':
325: fname.append("ss");
326: break;
327: case '_':
328: default:
329: if (Character.isWhitespace(ch)
330: || Character.isISOControl(ch)
331: || ch == File.separatorChar) {
332: fname.append('_');
333: } else {
334: fname.append(ch);
335: }
336: break;
337: }
338: }
339: return fname.toString();
340: }
341:
342: /**
343: ersetzt Leerzeichen durch _
344: */
345: public static String checkFileName(String fileName) {
346: fileName = toFilename(fileName);
347: /*
348: char[] theChars = fileName.toCharArray();
349:
350: for(int i=0; i < theChars.length; i++) {
351:
352: if( ((theChars[i] >= 'A') && (theChars[i] <= 'Z')) ||
353: ((theChars[i] >= 'a') && (theChars[i] <= 'z')) ||
354: ((theChars[i] >= '0') && (theChars[i] <= '9'))
355:
356: ){
357: }
358: else {
359: if(theChars[i] != '.')
360: theChars[i] = '_';
361: }
362: }
363:
364: return new String(theChars);
365: */
366: return fileName.replace(' ', '_');
367: }
368:
369: public static ContentContext keepCEContext(TKEvent evt,
370: TemplateBasic t) throws Throwable {
371: return keepCEContext(evt, t, evt.getName());
372: }
373:
374: /**
375: * holt aus den params die durchzuschleifenden Params und setzt sie ins
376: * Template t
377: *
378: * @param Template t
379: */
380: public static ContentContext keepCEContext(TKEvent evt,
381: TemplateBasic t, String event) throws Throwable {
382: ContentContext ceContext = new ContentContext(evt.getParams(),
383: event);
384: ceContext.fillIntoTemplate(t);
385: return ceContext;
386: }
387:
388: /**
389: * testen, ob der name ein gueltiger pathname ist
390: *
391: * @param
392: */
393: public static boolean isValidPathname(String name) throws Throwable {
394: if (name == null || name.equals("")) { // leer is natuerlich auch nicht gut...
395: throw new TKUserException(
396: "Es muß ein Name angegeben werden", NO_PATHNAME,
397: USER_SEVERITY, true, null);
398: }
399:
400: PatternMatcher matcher = TKReg.getMatcher();
401: PatternCompiler compiler = TKReg.getCompiler();
402: Pattern patNotAllowed;
403:
404: // nur wordcharacter (alphanumeric) fuer dirnamen: a-zA-Z_0-9 und das -
405: // to DO :: Das paßt nicht zur Localisation !!!
406: patNotAllowed = compiler.compile("[^a-zA-Z_0-9\\-.]");
407: if (matcher.contains(name, patNotAllowed)) {
408: // kein gueltiger pathname! interner name (content_node_shortname)
409: // wird vom generator als verzeichnisname verwendet
410: throw new TKUserException(
411: "Kein gültiger Pfadname: " + name,
412: NO_VALID_PATHNAME, USER_SEVERITY, true, null);
413: } else {
414: return true;
415: }
416: }
417:
418: /**
419: * Ermitteln der Zustände von Content-Instanzen
420: *
421: *
422: * @param
423: */
424: private static void filterInstances(VersionStatics statics,
425: TKVector vec, TKHashtable versions, TKHashtable filter) {
426:
427: int instIndex = 0;
428: while (instIndex < vec.size()) {
429:
430: TKHashtable instHash = (TKHashtable) vec
431: .elementAt(instIndex);
432: TKVector instanceVersions = (TKVector) instHash
433: .get("VERSIONS");
434: TKHashtable interestingKeys = new TKHashtable();
435:
436: int index = -1;
437: Enumeration e = instanceVersions.elements();
438: while (e.hasMoreElements()) {
439: TKSortableInteger versionKey = (TKSortableInteger) e
440: .nextElement();
441: Integer statusKey = (Integer) versions.get(versionKey);
442: index++;
443:
444: VersionSelection.selectContentVersionByStatus(statics,
445: interestingKeys, null, versionKey, statusKey);
446: }
447:
448: boolean removed = false;
449: TKHashtable forced = VersionSelection
450: .getForcedStatusList(filter);
451:
452: for (index = 0; index < instanceVersions.size(); index++) {
453: TKSortableInteger versionKey = (TKSortableInteger) instanceVersions
454: .elementAt(index);
455: if (versionKey == null)
456: continue;
457:
458: Integer statusKey = (Integer) interestingKeys
459: .get(versionKey);
460: if (statusKey == null)
461: continue;
462:
463: String filterCommand = (String) filter.get(statusKey);
464:
465: if (filterCommand != null
466: && filterCommand.equalsIgnoreCase("EXCLUDE")) {
467:
468: vec.removeElementAt(instIndex);
469: removed = true;
470: break;
471:
472: } else if (filterCommand != null
473: && filterCommand.equalsIgnoreCase("FORCE"))
474: forced.remove(statusKey);
475: }
476:
477: if (!removed) {
478:
479: if (forced.size() > 0)
480: vec.removeElementAt(instIndex);
481: else
482: instIndex++;
483: }
484: }
485: }
486:
487: /**
488: * Erzeugt eine Liste aller Instanzen zu einem Gruppen-Knoten,
489: * die einem Filterkriterium genügen
490: *
491: *
492: * @param
493: */
494: public static TKVector getFilteredInstances(int nodeId,
495: TKHashtable filter) throws Throwable {
496: // statische Daten der Versionsverwaltuung abrufen
497: VersionStatics statics = VersionStatics.setup();
498:
499: if (filter == null)
500: filter = VersionSelection.initContentFilter(statics
501: .getStatusPool());
502:
503: TKQuery q = TKDBManager
504: .newQuery(TKDBGetAllNodeContentVersions.class);
505: q.setQueryParams("CONTENT_NODE_ID", new Integer(nodeId));
506:
507: q.execute();
508: ResultSet rs = q.fetchResultSet();
509: TKVector vec = new TKVector();
510: TKHashtable instances = new TKHashtable();
511: TKHashtable versions = new TKHashtable();
512:
513: while (rs.next()) {
514:
515: int versionId = rs.getInt("VERSION_ID");
516: int instanceId = rs.getInt("INSTANCE_ID");
517: int contentNodeId = rs.getInt("CONTENT_NODE_ID");
518: int contentNodeType = rs.getInt("CONTENT_NODE_TYPE");
519: // Auskommentiert wegen JTest begin
520: // int contentId = rs.getInt ("CONTENT_ID");
521: // Auskommentiert wegen JTest end
522:
523: int statusId = rs.getInt("STATUS_ID");
524:
525: VersionStatus statusDesc = (VersionStatus) statics
526: .getStatusPool().get(new Integer(statusId));
527: if (statusDesc.comment)
528: continue;
529:
530: String contentNodename = rs.getString("CONTENT_NODE_NAME");
531: String contentNodeShortName = rs
532: .getString("CONTENT_NODE_SHORTNAME");
533: String instanceName = rs.getString("NAME");
534:
535: TKVector instanceVersions = null;
536:
537: TKHashtable instHash = (TKHashtable) instances
538: .get(new Integer(instanceId));
539: if (instHash == null) {
540:
541: instHash = new TKHashtable();
542: vec.addElement(instHash);
543: instances.put(new Integer(instanceId), instHash);
544:
545: instHash.put("INSTANCE_ID", new Integer(instanceId));
546: instHash.put("CONTENT_NODE_ID", new Integer(
547: contentNodeId));
548: instHash.put("CONTENT_NODE_NAME", contentNodename);
549: instHash.put("CONTENT_NODE_SHORTNAME",
550: contentNodeShortName);
551: instHash.put("CONTENT_NODE_TYPE", new Integer(
552: contentNodeType));
553: instHash.put("NAME", instanceName);
554:
555: instanceVersions = new TKVector();
556: instHash.put("VERSIONS", instanceVersions);
557:
558: } else {
559: instanceVersions = (TKVector) instHash.get("VERSIONS");
560: }
561:
562: TKSortableInteger versionKey = new TKSortableInteger(
563: versionId);
564: versions.put(versionKey, new Integer(statusId));
565: instanceVersions.addElement(versionKey);
566: }
567:
568: filterInstances(statics, vec, versions, filter);
569:
570: return vec;
571: }
572:
573: public static int getVersionInfo(ContentContext ceContext,
574: TemplateBasic t, VersionStatics statics) throws Throwable {
575: if (ceContext.toStatusId.intValue() < 0)
576: throw new Exception(
577: "WebManThread.getVersionInfo: No dest status");
578: int transitionableVersion = ceContext.instanceId.intValue() < 0 ? -1
579: : getTransitionableInstanceVersion(statics,
580: ceContext.instanceId, ceContext.versionId,
581: ceContext.toStatusId);
582: if (transitionableVersion >= 0) {
583: t.set("TRANS_VERSION", new Integer(transitionableVersion));
584: if (ceContext.versionId.intValue() < 0)
585: ceContext.versionId = new Integer(transitionableVersion);
586:
587: } else if (ceContext.instanceId.intValue() >= 0)
588: t.set("MODE", "RO");
589:
590: // ceContext.sVersionId = ceContext.versionId.intValue() < 0 ? null : ceContext.versionId;
591: return transitionableVersion;
592: }
593:
594: /**
595: * Liefert die aktuellste Version einer Content-Instanz die, bzw. überprüft ob eine
596: * uebergebene Version jeweils eine Transition mit dem übergebenen Zielzustand
597: * schaltet
598: *
599: * @param statics statische Versionsinfos
600: * @param instanceId ID der Instanz
601: * @param testVersion
602: * @param destStatus Zielstatus
603: */
604: public static int getTransitionableInstanceVersion(
605: VersionStatics statics, Integer instanceId,
606: Integer testVersion, Integer destStatus) throws Throwable {
607: // Alle Versionsinformationen zu einer Instanz aus DB holen
608: // geordnet nach Contentids und dann chronologisch
609: TKQuery q = TKDBManager
610: .newQuery(TKDBGetAllInstanceVersions.class);
611: q.setQueryParams("INSTANCE_ID", instanceId);
612: q.execute();
613: ResultSet rs = q.fetchResultSet();
614:
615: // ordnet jeder Version ihre Versionsdaten (Hashtabelle) zu
616: TKHashtable versions = new TKHashtable();
617:
618: // Liste der Ids aller Versionen (geordnet)
619: TKVector instanceVersions = new TKVector();
620:
621: // Resultset abarbeiten, kommentierende Versionsinformationen abfiltern
622: while (rs.next()) {
623: int versionId = rs.getInt("VERSION_ID");
624: int statusId = rs.getInt("STATUS_ID");
625:
626: VersionStatus statusDesc = (VersionStatus) statics
627: .getStatusPool().get(new Integer(statusId));
628: if (statusDesc.comment)
629: continue;
630:
631: TKHashtable versionData = new TKHashtable();
632: versionData.put("STATUS_ID", new Integer(statusId));
633:
634: TKSortableInteger versionKey = new TKSortableInteger(
635: versionId);
636: versions.put(versionKey, versionData);
637: instanceVersions.addElement(versionKey);
638: }
639:
640: // ordnet jeder "relevanten" Version ihren Zustand zu
641: TKHashtable interestingKeys = new TKHashtable();
642:
643: // ordnet jeder "relevanten" Version ihre möglichen Folgetransitionen, d.h.
644: // erlaubte Übergänge zu neuen Zuständen zu
645: TKHashtable interesting = new TKHashtable();
646:
647: // Durchläuft die Versionsgeschichte einer Instanz in der Reihenfolge der Versionierung
648: // über die ContentValues und innerhalb dieser chronologisch über die Versionsinformationen
649: //
650: // Für jede solche Version wird untersucht, ob die davor liegenden Versionen noch
651: // relevant sind, andernfalls werden sie aus interestingKeys und interesting entfernt.
652: // Die aktuelle Version ist auf jeden Fall relevant und wird in interestingKeys und
653: // interesting eingetragen. Für interestingKeys wird der Zustand vermerkt, für
654: // interesting wird wird ein zunächst leerer Vector mit möglichen Folgetransitionen
655: // angelegt. Diese werden in einem weiteren Schritt ermittelt
656:
657: int index = -1;
658: Enumeration e = instanceVersions.elements();
659: while (e.hasMoreElements()) {
660: TKSortableInteger versionKey = (TKSortableInteger) e
661: .nextElement();
662:
663: TKHashtable versionData = (TKHashtable) versions
664: .get(versionKey);
665: Integer statusKey = (Integer) versionData.get("STATUS_ID");
666: index++;
667:
668: // Ausfiltern der nicht mehr relevanten Versionen aus interestingKeys und
669: // interesting und Ergänzung um die laufende Version.
670: VersionSelection.selectContentVersionByStatus(statics,
671: interestingKeys,
672: testVersion.intValue() < 0 ? interesting : null,
673: versionKey, statusKey);
674:
675: TKVector transVec = new TKVector();
676: interesting.put(versionKey, transVec);
677:
678: // Bestimmung der möglichen Folgetransitionen zu der laufenden Version
679: VersionSelection.selectContentTransitions(statics,
680: versions, statics.getStatusPool(),
681: instanceVersions, interestingKeys, transVec,
682: versionKey.intValue(), index);
683: }
684:
685: VersionStatus statusDesc = (VersionStatus) statics
686: .getStatusPool().get(destStatus);
687:
688: // Aktuelleste Version die schaltet
689: TKSortableInteger transitionableVersion = null;
690:
691: // Durchläuft die Versionsgeschichte einer Instanz in der Reihenfolge der Versionierung
692: // über die ContentValues und innerhalb dieser chronologisch über die Versionsinformationen
693: for (index = 0; index < instanceVersions.size(); index++) {
694:
695: TKSortableInteger versionKey = (TKSortableInteger) instanceVersions
696: .elementAt(index);
697: if (versionKey == null)
698: continue;
699:
700: // Geht es nur darum zu ueberpruefen, ob eine übergebene Version schaltet,
701: // können die anderen Versionen (nicht aber die oben ausgewertete
702: // Versionsgeschichte) verworfen werden.
703: if (testVersion.intValue() >= 0
704: && versionKey.intValue() != testVersion.intValue())
705: continue;
706:
707: TKVector trans = (TKVector) interesting.get(versionKey);
708: if (trans == null)
709: continue;
710:
711: int transIndex = 0;
712: while (transIndex < trans.size()) {
713:
714: // Auskommentiert wegen JTest begin
715: // TKVersionStatusTransitionDBData dbData =
716: // (TKVersionStatusTransitionDBData) trans.elementAt(transIndex);
717: // Auskommentiert JTest end
718:
719: // Überprüfen ob der beim schalten erreichte Zielzustand noch
720: // mit den relevanten anderen Versionen vereinbar ist
721: // Erfolgt die Überprüfung anhand testVersion, reicht es, daß eine
722: // beliebige "relevante" Version aus interestingKeys schaltet,
723: // ansonsten muß es die laufende sein
724: if (statusDesc.newVersion
725: && VersionSelection.testContentTransition(
726: statics, testVersion.intValue() >= 0,
727: interestingKeys, versionKey.intValue(),
728: destStatus) != null)
729: transitionableVersion = versionKey;
730:
731: transIndex++;
732: }
733: }
734:
735: return transitionableVersion == null ? -1
736: : transitionableVersion.intValue();
737: }
738:
739: /**
740: * Speichern von eingegebenem Content
741: *
742: * @param
743: * @return die erzeugte Instanz ID
744: */
745: public static Content createContentInstance(Integer instanceId,
746: Integer contentNodeType, String name, String shortName,
747: Integer groupId, Integer formId, Integer contentNodeId)
748: throws Throwable {
749: if (contentNodeType.intValue() == GROUP_INTEGER.intValue()
750: || contentNodeType.intValue() == DIRECTORY_NODE_INTEGER
751: .intValue()) {
752:
753: if (contentNodeId.intValue() == -1
754: || (contentNodeType.intValue() == DIRECTORY_NODE_INTEGER
755: .intValue() && instanceId.intValue() == -1)) {
756: // Content Neu
757: cat.debug("Inserting new content ! : " + name);
758: TKQuery q = TKDBManager
759: .newQuery(TKDBContentTreeInsertNode.class);
760: Integer parentId = contentNodeType.intValue() == GROUP_INTEGER
761: .intValue() ? groupId : contentNodeId;
762: q.setQueryParams("NODE_ID", parentId);
763: q.setQueryParams("CONTENT_NODE_NAME", name);
764: q.setQueryParams("CONTENT_NODE_SHORTNAME", shortName);
765: q.setQueryParams("CONTENT_NODE_TYPE", SINGLE_INTEGER);
766: q.setQueryParams("CONTENT_FORM",
767: formId.intValue() < 0 ? ((Object) TKNull.NULL)
768: : formId);
769: q.setQueryParams("TREE_ID", new Integer(0));
770: q.setQueryParams("PROTOTYPE_ID", TKNull.NULL);
771: q.execute();
772: ResultSet rs = q.fetchResultSet();
773: if (!rs.next())
774: throw new Error(
775: "WebManThread.doCESave: Query gives no result");
776: contentNodeId = new Integer(rs
777: .getInt("CONTENT_NODE_ID"));
778: cat.debug("Got new content node id : " + contentNodeId);
779: TKContentInstanceDBData instDB = new TKContentInstanceDBData(
780: contentNodeId.intValue(), "default");
781: TKContentInstanceDBInterface.New(instDB);
782: return new Content(
783: contentNodeId,
784: name,
785: shortName,
786: new Integer(instDB.instance_id),
787: formId,
788: contentNodeType.intValue() == DIRECTORY_NODE_INTEGER
789: .intValue(), parentId);
790: }
791:
792: } else if (instanceId.intValue() == -1) {
793: // Content Neu sollte im Moment nicht auftreten !
794: throw new RuntimeException("Not implemented !");
795: /*
796: TKContentInstanceDBData instDB = new TKContentInstanceDBData(contentNodeId.intValue(), "default" );
797: TKContentInstanceDBInterface.New( instDB );
798: return new Integer(instDB.instance_id);*/
799: }
800: return null;
801: }
802:
803: /**
804: * stellt den path ab der documentroot bis zum aktuellen CONTENT_NODE (CONTENT_NODE_ID)
805: * beginnend mit der root, sich zusammensetzend aus den CONTENT_NODE_SHORTNAMEs
806: * zusammen
807: *
808: * @param contentNodeId Id des Content Nodes
809: * @return aktueller Pfad
810: * @throws SQLException Datenbankfehler
811: */
812: public static String getCurrentPath(Integer contentNodeId)
813: throws SQLException {
814: TKQuery q = TKDBManager
815: .newQuery(TKDBContentTreeGetParents.class);
816: q.setQueryParams("CONTENT_NODE_ID", contentNodeId);
817: q.execute();
818: ResultSet rs = q.fetchResultSet();
819: String res = "/";
820: while (rs.next()) {
821: res += rs.getString("CONTENT_NODE_SHORTNAME") + "/";
822: }
823: return res;
824: }
825:
826: /**
827: * stellt den path ab der documentroot bis zum aktuellen CONTENT_NODE (CONTENT_NODE_ID)
828: * beginnend mit der root, sich zusammensetzend aus den CONTENT_NODE_NAMEs
829: * zusammen
830: *
831: * @param contentNodeId Id des Content Nodes
832: * @return aktueller Pfad
833: * @throws SQLException Datenbankfehler
834: */
835: public static String getCurrentNamePath(Integer contentNodeId)
836: throws SQLException {
837: TKQuery q = TKDBManager
838: .newQuery(TKDBContentTreeGetParents.class);
839: q.setQueryParams("CONTENT_NODE_ID", contentNodeId);
840: q.execute();
841: ResultSet rs = q.fetchResultSet();
842: String res = "/";
843: while (rs.next()) {
844: res += rs.getString("CONTENT_NODE_NAME") + "/";
845: }
846: return res;
847: }
848:
849: /**
850: * Returns the full path of the specified content node.
851: *
852: * @param id the id of the content node.
853: * @return the full path of the specified content node.
854: * @throws TKException if any error occurred during
855: * content node path construction.
856: */
857: public static String getParentPath(Integer id) throws TKException {
858: try {
859: TKQuery query = TKDBManager
860: .newQuery(TKDBContentTreeGetParents.class);
861: query.setQueryParams("CONTENT_NODE_ID", id);
862: query.execute();
863:
864: ResultSet result = query.fetchResultSet();
865: StringBuffer path = new StringBuffer();
866:
867: while (result.next()) {
868: path.append("/").append(
869: result.getString("CONTENT_NODE_NAME"));
870: }
871:
872: if (path.length() == 0) {
873: path.append("/");
874: }
875:
876: return path.toString();
877: } catch (Exception e) {
878: throw WebmanExceptionHandler.getException(e);
879: }
880: }
881:
882: }
|