001: package de.webman.content.eventhandler;
002:
003: import com.teamkonzept.web.*;
004: import com.teamkonzept.webman.*;
005: import de.webman.acl.*;
006: import com.teamkonzept.webman.mainint.*;
007: import de.webman.content.*;
008: import de.webman.content.workflow.*;
009: import de.webman.content.workflow.db.*;
010: import com.teamkonzept.webman.mainint.db.queries.*;
011: import com.teamkonzept.webman.mainint.events.*;
012: import com.teamkonzept.lib.*;
013: import com.teamkonzept.field.*;
014: import com.teamkonzept.field.db.*;
015: import com.teamkonzept.db.*;
016: import de.webman.util.legacy.Legacy;
017:
018: import java.sql.*;
019: import java.util.*;
020:
021: import org.apache.log4j.Category;
022:
023: /**
024: * Auflisten aller Contents eines Teilbaums
025: * Liste aller Artikel dieses Node aufbauen (ce_conList)
026: * Wenn subtree gesetzt ist,wird rekursiv der ganze Unterbaum verfolgt <br>
027: *
028: * @author $Author: sebastian $
029: * @version $Revision: 1.38.4.2 $
030: *
031: */
032: public class CEBrowseHandler extends DefaultEventHandler implements
033: DatabaseDefaults, ParameterTypes, FrameConstants {
034: /** logging Categorie */
035: private static final Category CAT = Category
036: .getInstance(CEBrowseHandler.class);
037:
038: /** empty constructor */
039: private CEBrowseHandler() {
040: }
041:
042: /** statische Instance */
043: private static CEBrowseHandler instance = new CEBrowseHandler();
044:
045: /** dynamische Erzeugung */
046: public static CEBrowseHandler getInstance() {
047: return instance;
048: }
049:
050: /** holt aus den Properties die Anzahl der anzuzeigenden Contents */
051:
052: public static int getAnzahlBlaettern(String count) {
053: if ((count == null) || (count.length() != 0)) {
054: try {
055: PropertyManager man = PropertyManager
056: .getPropertyManager("LEAF_THROUGH");
057: String gen = man.getValue("COUNT", "0");
058: return Integer.parseInt(gen);
059: } catch (Throwable t) {
060: return 0;
061: }
062: } else
063: return (Integer.parseInt(count));
064: }
065:
066: /* blättern hoch und runter */
067:
068: private static void blaetter(TKEvent evt, ContentContext ce,
069: TKHTMLTemplate t, int size) {
070: int start = 0;
071: int count = 0;
072:
073: if (evt.getParameter("RICHTUNG", evt.getName()) != null) {
074: if (evt.getParameter("CONLIST_START", evt.getName()) != null)
075: start = Integer.parseInt(evt.getParameter(
076: "CONLIST_START", evt.getName()));
077: count = getAnzahlBlaettern(evt.getParameter(
078: "CONLIST_COUNT", evt.getName()));
079: switch (Integer.parseInt(evt.getParameter("RICHTUNG", evt
080: .getName()))) {
081: case -2:
082: start = 0;
083: break;
084: case -1:
085: if (start > count)
086: start = start - count;
087: else
088: start = 0;
089: break;
090: case 1:
091: start = start + count;
092: if (start + count > size)
093: start = size - count;
094: break;
095: case 2:
096: if (size > count)
097: start = size - count;
098: else
099: start = 0;
100: break;
101: default:
102: break;
103: }
104: ce.conlist_start = Integer.toString(start);
105: ce.conlist_count = Integer.toString(count);
106: t.set("CONLIST_START", ce.conlist_start);
107: t.set("CONLIST_COUNT", ce.conlist_count);
108:
109: } else {
110: if (ce.conlist_count == null) {
111: ce.conlist_count = Integer
112: .toString(getAnzahlBlaettern(null));
113: ce.conlist_start = Integer.toString(0);
114: t.set("CONLIST_START", ce.conlist_start);
115: t.set("CONLIST_COUNT", ce.conlist_count);
116:
117: }
118: }
119: }
120:
121: /** returns to the first content
122: @param context - der ContentContext
123: */
124: private static void blaetternreset(ContentContext context) {
125: if (context.conlist_start != null)
126: context.conlist_start = "0";
127: }
128:
129: /**
130: boolean subtree
131: */
132: public void handleEvent(TKEvent evt) throws TKException {
133: try {
134: // zum Sortieren wird auch das Navigationsframe neu geladen
135: if ((evt.getParameter("SORT_NEW", evt.getName()) != null)
136: && (evt.getParameter("SORT_NEW", evt.getName())
137: .equals("TRUE"))) {
138:
139: TKHTMLTemplate frame = evt
140: .getPrepHTMLTemplate("f_ce.tmpl");
141: HTMLUtils.fillFrameSet(frame, LEFT_FRAME_WIDTH,
142: "CE_SHOWLIST", "CE_GROUP_LIST");
143: // die liste der offenen nodes kommt ins template
144: TKVector openNodes = new TKVector(); // initial bei Root den Baum oeffnen
145: if (evt.getParams()
146: .hasMultiple(PARAMETER, "OPEN_NODES")) {
147: openNodes = evt.getParams().getVector(PARAMETER,
148: "OPEN_NODES");
149: } else {
150: if (evt.getParameter(PARAMETER, "OPEN_NODES") != null)
151: openNodes.put(0, evt.getParameter(PARAMETER,
152: "OPEN_NODES"));
153: else
154: openNodes.put(0, "-1");
155: }
156: TKStandardIterator iterator1 = new TKStandardIterator(
157: openNodes, frame.getListIterator(),
158: "OPEN_NODES", "OPEN_NODES");
159: frame.setListIterator(iterator1);
160:
161: ContentContext ce = null;
162: ce = ContentContext.reCalculateContext(evt
163: .getParameter(PARAMETER, "NAVIGATION_CONTEXT"));
164: ce.sort_by = evt.getParameter("SORT_BY", evt.getName());
165: ce.sortUpDown = evt.getParameter("SORT_UP_DOWN", evt
166: .getName());
167: ce.fillIntoTemplate(frame);
168: frame.set("NAVIGATION_CONTEXT", ce
169: .calculateNavContext());
170:
171: evt.finishTemplate(frame);
172: return;
173: }
174:
175: boolean subtree; // wird der Unterbaum angezeigt ?
176:
177: CEUtils.checkEvent(evt);
178:
179: if (evt.getName().equalsIgnoreCase("CE_GROUP_LIST")) {
180: subtree = false;
181: } else if (evt.getName().equalsIgnoreCase("CE_TREE")) {
182: subtree = true;
183: } else {
184: subtree = evt.getParameter(PARAMETER, "EVT_SUBTREE") != null;
185: }
186:
187: TKHTMLTemplate t = evt
188: .getPrepHTMLTemplate("ce_conList.tmpl");
189:
190: // übernehme Liste der Selectierten Contents
191: CEUtils.keepSelectedContents(evt, t);
192:
193: // Kontext wird durchgeschliffen
194: ContentContext ceContext = null;
195: if (evt.getParameter(PARAMETER, "RECALCULATE") != null) {
196: ceContext = ContentContext.reCalculateContext(evt
197: .getParameter(PARAMETER, "NAVIGATION_CONTEXT"));
198: if (evt.getName().equalsIgnoreCase("CE_SEARCH")) {
199: ceContext.searchString = evt.getParameter(
200: PARAMETER, "SEARCHSTRING");
201: ceContext.searchKennung = evt.getParameter(
202: PARAMETER, "S_KENNUNG");
203: ceContext.subtree = subtree;
204: blaetternreset(ceContext);
205: }
206: ceContext.fillIntoTemplate(t);
207: subtree = ceContext.subtree;
208: } else {
209:
210: ceContext = CEUtils.keepCEContext(evt, t);
211: ceContext.subtree = subtree;
212:
213: }
214:
215: // Soll ein Gruppenknoten verfolgt werden ?
216: boolean isGroup = ceContext.conNodeType.intValue() == GROUP_INTEGER
217: .intValue();
218:
219: // statische Daten der Versionsverwaltung abrufen
220: VersionStatics statics = VersionStatics.setup();
221:
222: // relevante Stati ermitteln, da Singlenodes z.B. redaktionsseitig nicht gelöscht werden können,
223: // fallen dort z.B. bestimmte Zustände weg (singles:off)
224: TKHashtable statusPool = VersionStatus.selectSingles(
225: statics, false);
226:
227: // relevante Stati für Filteroperationen ermitteln, bei subtree-Verfolgung mischen sich u.U.
228: // single- und groupnodes, daher werden bei subtree die single-Statis NICHT ausgeblendet
229: TKHashtable filterStatusPool = VersionStatus.selectSingles(
230: statics, !isGroup /*&& !subtree*/);
231:
232: // Filterdaten für Zustände aus filterStatusPool (s.o.) aus Formular einlesen und durchschleifen
233: TKHashtable filter = null;
234:
235: // 0 ist Standard, <0 Nutzerdefiniert, >0 Vordef. Filter
236: if (ceContext.filterId.intValue() > 0) {
237: VersionStatusFilter f = (VersionStatusFilter) statics
238: .getFilters().get(ceContext.filterId);
239: if (f != null) {
240: filter = f.makeFilter(t, filterStatusPool);
241: ceContext.filterMode = f.filter_mode == VersionStatusFilter.SOURCE_MODE_ID ? "SRC"
242: : "DEST";
243: }
244:
245: } else if (ceContext.filterId.intValue() < 0) {
246: // Filter aus den Parametern bauen
247: filter = VersionSelection.makeContentFilter(t,
248: filterStatusPool, evt.getParams().getClass(
249: PARAMETER));
250: }
251:
252: // Falls nicht definiert -> Standardfilter
253: if (filter == null) {
254: filter = VersionSelection.initContentFilter(statusPool);
255: ceContext.filterMode = "SRC";
256: t.set("FILTER_MODE", ceContext.filterMode);
257: VersionSelection.fillFilterIntoTemplate(t, statusPool,
258: filter);
259: }
260:
261: TKVector allInstances = VersionCache
262: .getVersionInfo(
263: ceContext,
264: subtree,
265: ceContext.searchKennung != null
266: && ceContext.searchKennung.length() != 0 ? true
267: : false, ceContext.searchString);
268:
269: // FILTER wird angewendet
270: TKVector filteredInstances = new TKVector();
271: for (int i = 0; i < allInstances.size(); i++) {
272: Content c = (Content) allInstances.elementAt(i);
273:
274: if (c.filterTransitions(filter, ceContext.filterMode)) {
275: filteredInstances.addElement(c);
276: }
277: }
278:
279: CAT.debug("filter done");
280:
281: // das hier entweder anwenden oder raus damit -> Template !!!
282: // addFullPath(allInstances);
283:
284: // Iterator über relevante Zustände übergeben (wird im template für die Anzeige
285: // der möglichen Transitionen relevanter Versionen gebraucht
286: t.setListIterator(new TKStandardPluginIterator(
287: "VERSION_STATUS", "STATUS", filterStatusPool, true,
288: t.getListIterator()));
289:
290: /* iterator über alle möglichen Statuse beim mutiplen
291: Statuswechsel */
292: t.setListIterator(new TKStandardPluginIterator(
293: "MUTIPLE_STADIEN", null, VersionStatus
294: .selectNotNewVersion(statics), false, t
295: .getListIterator()));
296:
297: // Iterator über vordefinierte Filterübergeben
298: t.setListIterator(new TKStandardPluginIterator(
299: "PREDEFINED_FILTERS", null, statics
300: .getInternationalFilters(), true, t
301: .getListIterator()));
302:
303: // blättern
304: blaetter(evt, ceContext, t, filteredInstances.size());
305:
306: // gefilterte Instanzen anzeigen
307: t.setListIterator(new TKStandardPluginIterator(
308: "CONTENTS_PER_NODE", null, filteredInstances,
309: false, t.getListIterator()));
310:
311: if (allInstances.size() == 0)
312: t.set("NO_CONTENTS_PER_NODE", Boolean.TRUE);
313: t.set("CONTENTS_PER_NODE_SIZE", Integer
314: .toString(filteredInstances.size()));
315:
316: // CE_NEW_NODE erlaubt?
317: LoginFactory factory = LoginFactory.getInstance();
318: Login login = factory.getLogin(evt.getRemoteUser());
319: Event event = EventFactory.getInstance().getEvent(
320: "CE_NEW_NODE");
321: if (login.isAllowed(event.getID(),
322: ContextConstants.CONTENT_EDIT)) {
323: t.set("CE_NEW_NODE", "1");
324: }
325: event = EventFactory.getInstance().getEvent("CE_COMPACT");
326: if (login.isAllowed(event.getID(),
327: ContextConstants.CONTENT_EDIT)) {
328: t.set("CE_COMPACT", "1");
329: }
330: event = EventFactory.getInstance().getEvent("CE_SEARCH");
331: if (login.isAllowed(event.getID(),
332: ContextConstants.CONTENT_EDIT)) {
333: t.set("CE_SEARCH", "1");
334: }
335: event = EventFactory.getInstance().getEvent(
336: "CE_SWITCH_MUTIPLE");
337: if (event != null
338: && login.isAllowed(event.getID(),
339: ContextConstants.CONTENT_EDIT)) {
340: t.set("CE_SWITCH_MUTIPLE", "1");
341: }
342: // Verfolgungsmodus (rekursiv oder flach) durchschleifen
343: if (subtree)
344: t.set("SUBTREE", new Boolean(subtree));
345: // Navigations Context setzen
346: t
347: .set("NAVIGATION_CONTEXT", ceContext
348: .calculateNavContext());
349:
350: if (evt.getParameter(PARAMETER, "SELECT_SEARCH_RESULTS") != null
351: && Boolean.valueOf(
352: evt.getParameter(PARAMETER,
353: "SELECT_SEARCH_RESULTS"))
354: .booleanValue()) {
355: t.set("SELECT_SEARCH_RESULTS", Boolean.TRUE.toString());
356: }
357:
358: TreeUtils.keepOpenNodes(evt, t);
359: evt.finishTemplate(t);
360: } catch (Throwable e) {
361: // TO DO : Analyze Exception !
362: throw WebmanExceptionHandler.getException(e);
363: }
364: }
365:
366: public boolean isHandler(TKEvent evt) {
367: return (evt.getName().equalsIgnoreCase("CE_GROUP_LIST")
368: || evt.getName().equalsIgnoreCase("CE_TREE") || evt
369: .getName().equalsIgnoreCase("CE_SEARCH"));
370:
371: }
372: }
|