001: package de.webman.content.eventhandler;
002:
003: import com.teamkonzept.web.*;
004: import com.teamkonzept.webman.*;
005: import com.teamkonzept.webman.db.TKWebmanDBManager;
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.field.db.*;
013: import com.teamkonzept.field.db.queries.*;
014: import com.teamkonzept.db.*;
015: import de.webman.generator.Preview;
016: import java.sql.*;
017: import de.webman.content.workflow.*;
018: import de.webman.content.*;
019: import de.webman.content.db.queries.TKDBContentAttributeGetOldContentId;
020: import de.webman.acl.Policy;
021: import de.webman.util.legacy.Legacy;
022: import org.apache.log4j.Category;
023:
024: /**
025: * @author $Author: uli $
026: * @version $Revision: 1.31 $
027: */
028: public class CESaveHandler extends DefaultEventHandler implements
029: ParameterTypes, FrameConstants, DatabaseDefaults {
030: /** for Logging */
031: private static Category cat = Category
032: .getInstance(CESaveHandler.class);
033:
034: /** Konstruktor private - Singleton !*/
035: private CESaveHandler() {
036: }
037:
038: /** Singleton Instance */
039: private static CESaveHandler instance = new CESaveHandler();
040:
041: /** Zugriff auf Singleton */
042: public static CESaveHandler getInstance() {
043: return instance;
044: }
045:
046: /**
047: checkt User Rechte und wirft Exception, falls Verletzung vorliegt
048: @param user Remote User
049: @param event Name des Events
050: @param contentNodeId des zu checkenden Contents
051: */
052: public void checkUserRights(String user, String event,
053: Integer contentNodeId) throws TKException {
054: try {
055: WebManEvent.checkEvent(user, event,
056: ContextConstants.CONTENT_EDIT,
057: Policy.CONTENT_TREE_ID,
058: contentNodeId == null ? null : contentNodeId);
059: } catch (Throwable t) {
060: throw WebmanExceptionHandler.getException(t);
061: }
062: }
063:
064: /**
065: ueberprueft die Namen beim Abspeichern auf:
066: - ist ein Namen angegeben ?
067: - Kennung wird bei Bedarf automatisch generiert
068: - ist der Name schon einmal vergeben
069: - enthaelt die Kennung nur erlaubte Zeichen ?
070: @param shortName Kennung des Contents
071: @param name Name des Contents
072: @param groupId ID des GroupContents null falls ein Single abgespeichert wird
073: @param contentNodeId des zu speichernden Contents
074: @return die korrekte Kennung
075: @exception TKException falls unzulaessige Eingaben vorhanden
076: */
077: public String getValidName(String shortName, String name,
078: Integer groupId, Integer contentNodeId) throws TKException {
079: try {
080: if (groupId == null)
081: return shortName; // Single wird erstellt !
082: String retName = shortName;
083: // Kennung wird aus Namen eventuell generiert
084: if (shortName == null && name != null) {
085: retName = TKUploadField.checkFileName(name);
086: }
087: if (name == null || name.equals(""))
088: throw new TKUserException(
089: "Es muß ein Name angegeben werden",
090: NO_PATHNAME, USER_SEVERITY, true, null);
091:
092: // check, ob innerhalb einer Contentgruppe die Kennung schon mal existiert !
093: if (groupId.intValue() != -1)
094: CEUtils.checkShortName(contentNodeId, groupId, retName);
095: CEUtils.isValidPathname(retName);
096: return retName;
097: } catch (Throwable t) {
098: t.printStackTrace();
099: throw WebmanExceptionHandler.getException(t);
100: }
101: }
102:
103: /**
104: prueft, ob jemand anders den Content schon abgespeichert hat
105: @param contentNodeId des Contents
106: @param versionId Ausgangsversion
107: @param toStatusId gewuenschter neuer Status
108: @return Namen des Konfliktverursachers, null falls ok
109: */
110: public String getContentSaveConflict(Integer contentNodeId,
111: Integer versionId, Integer toStatusId) throws TKException {
112: if (contentNodeId == null)
113: return null;
114: try {
115: Content content = ContentFactory.getInstance().getContent(
116: contentNodeId);
117: return VersionControl.savedAlready(content, versionId,
118: toStatusId);
119: } catch (Throwable t) {
120: t.printStackTrace();
121: throw WebmanExceptionHandler.getException(t);
122: }
123: }
124:
125: /**
126: speichert die Workflow Informationen zu einem Content
127: @param author Author des Contents
128: @param instanceId des Contents
129: @param toStatusId gewuenschter neuer Status
130: @param contentNodeId des Contents
131: @param name Name des Contents
132: @param shortName Kennung des Contents
133: @param contentNodeType
134: @param formId ID des zugrundeliegenden Formulars
135: @param groupId ID des GruppenContents
136: @param contentId ID des schon abgespeicherten Contents
137: */
138: public Content saveContentVersion(Integer contentId, String author,
139: Integer instanceId, Integer toStatusId,
140: Integer contentNodeType, String name, String shortName,
141: Integer groupId, Integer formId, Integer contentNodeId)
142: throws TKException {
143: try {
144: TKContentDBData cdata = null;
145: if (instanceId == null)
146: instanceId = new Integer(-1);
147:
148: if (contentNodeId == null)
149: contentNodeId = new Integer(-1);
150: if (instanceId.intValue() >= 0) {
151: // hole die alten Attribute (Attribute kopieren !)
152: cdata = new TKContentDBData(instanceId.intValue(), 0); // geht 0 hier ????
153: TKQuery q = TKDBManager
154: .newQuery(TKDBContentAttributeGetOldContentId.class);
155: q.setQueryParams("CONTENT_ID", new Integer(contentId
156: .intValue()));
157: q.setQueryParams("INSTANCE_ID", new Integer(instanceId
158: .intValue()));
159: q.execute();
160:
161: ResultSet rs = q.fetchResultSet();
162: // hole alte content_id
163: while (rs.next()) {
164: cdata.content_id = rs.getInt("OLD_CONTENT_ID");
165: }
166: cdata.setIgnoreTable("CONTENT_NODE", true);
167: cdata.setIgnoreTable("CONTENT_VALUE", true);
168: TKContentDBInterface.Get(cdata);
169: cdata.setIgnoreTable("CONTENT_NODE", false);
170: cdata.setIgnoreTable("CONTENT_VALUE", false);
171:
172: } else {
173: cdata = new TKContentDBData();
174: }
175: // Bei gelöschten oder neuen Contents neue Instanz erzeugen
176: Content content = CEUtils.createContentInstance(instanceId,
177: contentNodeType, name, shortName, groupId, formId,
178: contentNodeId);
179: if (content == null)
180: content = new Content(
181: contentNodeId,
182: name,
183: shortName,
184: instanceId,
185: formId,
186: contentNodeType.intValue() == DIRECTORY_NODE_INTEGER
187: .intValue(), groupId);
188: if (content.getInstanceId() == null)
189: content.setInstanceId(instanceId);
190: cdata.instance_id = content.getInstanceId().intValue();
191: cdata.content_id = contentId.intValue();
192: // Versions-Infos setzen
193: cdata.version_info = "%WebManThread.doCESave/content";
194: cdata.version_author = author;
195: cdata.status_id = toStatusId.intValue();
196:
197: // New erzeugt neue Version, übernimmt aber die aktuellen Attribute (s.o.)
198: TKContentDBInterface.New(cdata);
199: cdata.setIgnoreTable("CONTENT_NODE", true);
200: cdata.setIgnoreTable("CONTENT_VALUE", true);
201: TKContentDBInterface.Put(cdata);
202: cdata.setIgnoreTable("CONTENT_NODE", false);
203: cdata.setIgnoreTable("CONTENT_VALUE", false);
204: // hier neue VersionId auslesen und in den Content setzen
205: ContentVersion version = new ContentVersion(new Integer(
206: cdata.version_id), contentId, content.getId(),
207: author, null, null, groupId == null);
208: content.getInterestingVersions().put(toStatusId, version);
209: return content;
210: } catch (Throwable t) {
211: t.printStackTrace();
212: throw WebmanExceptionHandler.getException(t);
213: }
214: }
215:
216: /**
217: * Handles the specified event.
218: *
219: * @param evt the event to be handled.
220: * @throws TKException if any error occurred during event handling.
221: */
222: public void handleEvent(TKEvent evt) throws TKException {
223: try {
224: if (evt.getName().equalsIgnoreCase("CE_SAVE_AND_PREVIEW")
225: && evt.getParameter(PARAMETER, "DO_PREVIEW") != null) {
226: // Doin' the do ...
227: Preview preview = new Preview(evt);
228: preview.doPreviewIndexPerContent();
229:
230: // Terminate event handling.
231: return;
232: }
233:
234: // Kontext sichern
235: ContentContext ceContext = new ContentContext(evt
236: .getParams(), null);
237:
238: // hier nich ABspeichern neuer Gruppen Contents beruecksichtigen
239: WebManEvent.checkEvent(evt.getRemoteUser(), evt.getName(),
240: ContextConstants.CONTENT_EDIT,
241: Policy.CONTENT_TREE_ID, ceContext.conNodeId);
242:
243: TKHTMLTemplate t = evt
244: .getPrepHTMLTemplate("ce_fields.tmpl");
245:
246: // statische Daten der Versionsverwaltung abrufen
247: VersionStatics statics = VersionStatics.setup();
248: ceContext.conNodeShortName = getValidName(
249: ceContext.conNodeShortName, ceContext.conNodeName,
250: ceContext.groupConNodeId, ceContext.conNodeId);
251: // Hat den Content zwischenzeitlich schon jemand anders bearbeitet ??
252: String conflictAuthor = null;
253: if (ceContext.instanceId.intValue() >= 0)
254: conflictAuthor = getContentSaveConflict(
255: ceContext.conNodeId, ceContext.versionId,
256: ceContext.toStatusId);
257:
258: TKFormDBData data = new TKFormDBData(ceContext.formId
259: .intValue());
260: TKFormDBInterface.Get(data);
261: TKBaseField field = TKFieldRegistry.getFieldFromDB(data);
262: TKHashtable fieldContext = new TKHashtable();
263: Object realData = field.compileData("", evt.getParams()
264: .getClass(PARAMETER), fieldContext);
265: field.fillIntoTemplate(t, realData, "");
266:
267: Object diags = field.getFromContext(TKBaseField.DIAGS_KEY,
268: fieldContext);
269: if (diags != null && (diags instanceof TKVector)) {
270: // ToDo -> in Fehlerverwaltung einbauen !!!
271: ceContext.fillIntoTemplate(t);
272: TKVector hints = new TKVector();
273: hints
274: .addElement("Sicherung wurde NICHT durchgeführt, siehe Meldungen");
275: TKStandardIterator it1 = new TKStandardIterator(hints,
276: t.getListIterator(), "HINTS", "HINT");
277:
278: if (diags != null) {
279: TKListIterator it2 = new TKStandardPluginIterator(
280: "DIAGNOSTICS", "DIAGNOSTIC",
281: (TKVector) diags, false, it1);
282: t.setListIterator(it2);
283: }
284:
285: t.set("HAS_DIAGNOSTICS", new Boolean(true));
286: t.set("HAS_HINTS", new Boolean(true));
287: cat.warn("Sicherung wurde nicht duchgeführt -> ");
288: WebManEvent.fillEventsIntoTemplate(evt.getRemoteUser(),
289: t, ContextConstants.CONTENT_EDIT,
290: Policy.CONTENT_TREE_ID, ceContext.conNodeId);
291: evt.finishTemplate(t);
292: return;
293: }
294: // bis hier raus !
295: // wurde die Warnung schon ausgegeben ?
296: boolean checked = evt.getParameter(PARAMETER, "CHECKED") != null;
297: if (conflictAuthor != null && !checked) {
298: // ToDo -> in Fehlerverwaltung einbauen !!!
299: ceContext.fillIntoTemplate(t);
300: t.set("HAS_CONFLICT", new Boolean(true));
301: t.set("CONFLICT_AUTHOR", conflictAuthor);
302: cat.warn("Konflikt bei Speicherung! ");
303: WebManEvent.fillEventsIntoTemplate(evt.getRemoteUser(),
304: t, ContextConstants.CONTENT_EDIT,
305: Policy.CONTENT_TREE_ID, ceContext.conNodeId);
306: evt.finishTemplate(t);
307: return;
308: }
309:
310: /* Ab hier zum Testen ... - kann weg bei XForms */
311: TKContentDBData testConDB = new TKContentDBData();
312: field.insertDataIntoDB(testConDB, realData);
313: field.getDataFromDB(testConDB);
314: /* Bis hier zum Testen ... */
315:
316: // Das Abspeichern von gelöschten Instancen ist erst mal disabled
317: // das Folgende geht aber auch bei gelöschten Instanzen ...
318: // Hier erst mal die Attribut-Daten der aktuellen Version holen
319: // bei gelöschten Contents (s.u.) wird dann eine neue Instanz erzeugt
320: TKContentDBData cdata = null;
321:
322: // scheint voellig egal zu sein ????
323: // int transitionableVersion = CEUtils.getVersionInfo (ceContext, t, statics);
324:
325: if (ceContext.instanceId.intValue() >= 0) {
326:
327: //if (transitionableVersion < 0)
328: // throw new Exception ("doCEContentAttributes: No transitionable content version");
329:
330: cdata = new TKContentDBData(ceContext.instanceId
331: .intValue(), 0);
332:
333: cdata.setIgnoreTable("CONTENT_VALUE", true);
334: cdata.setIgnoreTable("CONTENT_NODE", true);
335: TKContentDBInterface.Get(cdata);
336: cdata.setIgnoreTable("CONTENT_VALUE", false);
337: cdata.setIgnoreTable("CONTENT_NODE", false);
338:
339: } else
340: cdata = new TKContentDBData();
341: // Bei gelöschten oder neuen Contents neue Instanz erzeugen
342: Content content = CEUtils.createContentInstance(
343: ceContext.instanceId, ceContext.conNodeType,
344: ceContext.conNodeName, ceContext.conNodeShortName,
345: ceContext.groupConNodeId, ceContext.formId,
346: ceContext.conNodeId);
347:
348: if (content != null) {
349: if (content.getInstanceId() == null)
350: content.setInstanceId(ceContext.instanceId);
351: else
352: ceContext.instanceId = content.getInstanceId();
353: if (content.getId() != null)
354: ceContext.conNodeId = content.getId();
355: }
356: // Nach dem Speichern gilt der (evtl. neue) Content als nicht geloescht
357: // ceContext.instanceStatus = null;
358:
359: // Versions-Infos setzen
360: cdata.version_info = "%WebManThread.doCESave/content";
361: cdata.version_author = evt.getRemoteUser();
362: cdata.status_id = ceContext.toStatusId.intValue();
363: cdata.instance_id = ceContext.instanceId.intValue();
364:
365: // New erzeugt neue Version, übernimmt aber die aktuellen Attribute (s.o.)
366: TKContentDBInterface.New(cdata);
367:
368: field.insertDataIntoDB(cdata, realData);
369: TKContentDBInterface.Put(cdata);
370:
371: // Versionsinfos für die nächste Version erzeugen
372: ceContext.versionId = new Integer(cdata.version_id);
373: CEUtils.getVersionInfo(ceContext, t, statics);
374: ceContext.mode = null;
375: ceContext.fillIntoTemplate(t);
376: if (ceContext.getNavigationContext() != null)
377: evt.getParams().put(PARAMETER, "RECALCULATE", "a");
378: // evt.finishTemplate(t);
379:
380: // wie solls weitergehen?
381:
382: if (evt.getName().equalsIgnoreCase("CE_SAVE")) // speichern und zurück
383: {
384: CEBrowseHandler.getInstance().handleEvent(evt);
385: } else {
386: if (evt.getName().equalsIgnoreCase(
387: "CE_SAVE_AND_PREVIEW")) // speichern und preview
388: {
389: evt.getParams().put(PARAMETER, "DO_PREVIEW",
390: Boolean.TRUE);
391: }
392:
393: // "boeser" hack
394: evt.getParams().put(PARAMETER, "VERSION_ID",
395: ceContext.versionId);
396:
397: // ziehen der Parameter bei neuem group-content
398: if (ceContext.instanceId.intValue() != -1) {
399: evt.getParams().put(PARAMETER, "INSTANCE_ID",
400: ceContext.instanceId);
401: evt.getParams().put(PARAMETER, "CONTENT_NODE_ID",
402: ceContext.conNodeId);
403: }
404:
405: CEEditHandler.getInstance().handleEvent(evt);
406:
407: // if (evt.getName().equalsIgnoreCase("CE_SAVE_TO_DB")) // nur speichern
408: // {
409: // // "boeser" hack
410: // evt.getParams().put(PARAMETER, "VERSION_ID", ceContext.versionId);
411: //
412: // // ziehen der Parameter bei neuem group-content
413: // if (ceContext.instanceId.intValue() != -1)
414: // {
415: // evt.getParams().put(PARAMETER, "INSTANCE_ID", ceContext.instanceId);
416: // evt.getParams().put(PARAMETER, "CONTENT_NODE_ID", ceContext.conNodeId);
417: // }
418: // CEEditHandler.getInstance().handleEvent(evt);
419: // }
420: // else
421: // if (evt.getName().equalsIgnoreCase("CE_SAVE_AND_PREVIEW")) // speichern und preview
422: // {
423: // Preview preview = new Preview (evt);
424: // preview.doPreviewIndexPerContent ();
425: // }
426: }
427: } catch (Throwable e) {
428: throw WebmanExceptionHandler.getException(e);
429: }
430: }
431:
432: public boolean isHandler(TKEvent evt) {
433: return (evt.getName().equalsIgnoreCase("CE_SAVE") // speichern und zurück
434: || evt.getName().equalsIgnoreCase("CE_SAVE_TO_DB") // nur speichern
435: || evt.getName().equalsIgnoreCase("CE_SAVE_AND_PREVIEW") // speichern und preview
436: );
437: }
438: }
|