package de.webman.content;
import com.teamkonzept.lib.TKHashtable;
import com.teamkonzept.lib.TKVector;
import com.teamkonzept.lib.TKHashable;
import com.teamkonzept.lib.TKNull;
import com.teamkonzept.lib.TKException;
import com.teamkonzept.web.TKEvent;
import com.teamkonzept.db.*;
import com.teamkonzept.webman.mainint.events.TKUserException;
import com.teamkonzept.webman.WebManEvent;
import com.teamkonzept.webman.mainint.ContextConstants;
import com.teamkonzept.webman.mainint.DatabaseDefaults;
import de.webman.acl.Policy;
import java.util.Enumeration;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.sql.SQLException;
import de.webman.content.workflow.ContentVersion;
import de.webman.content.workflow.VersionSelection;
import de.webman.content.workflow.VersionControl;
import de.webman.content.attributs.AttributeHandler;
import com.teamkonzept.webman.mainint.db.queries.*;
import com.teamkonzept.webman.mainint.events.*;
import de.webman.content.eventhandler.CEUtils;
import org.apache.log4j.Category;
/**
Huelle fuer Content in Webman
Achtung Content und Instanz sind zwar im Datenbankmodell getrennt
werden hier aber noch als eins betrachtet !
* @author $Author: sebastian $
* @version $Revision: 1.28 $
*/
public class Content implements TKHashable, UserCodes, DatabaseDefaults
{
/** Logging Category */
private static Category cat = Category.getInstance(Content.class);
/** Zeitformat */
private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat ("dd.MM.yy HH:mm");
/** beschreibender Name des Contents*/
private String name;
/** kennung des Contents */
private String shortName;
/** ID des zugrundeliegenden Formulars */
private Integer formularId;
/** ein Single Content oder Mitglied eines Gruppencontents */
private boolean isSingle;
/** ID im ContentTree */
private Integer contentNodeId;
/** Instanz Id */
private Integer instanceId;
/** Id des Parents im Contenttree */
private Integer parentId;
/** Hashtable der interessanten Versionen key=statusId value=ContentVersion*/
private TKHashtable interesting = new TKHashtable();
/** Vector aller Versionen */
private TKVector versions = new TKVector();
/** Referenzierender Node, wird zum Generieren gebraucht, ist nicht schoen hier
bis zum Redesign Generator aber notwendig
*/
private Integer refNodeId;
/** gecached die Hashtable */
private TKHashtable templateData = null;
/** erste Version */
private ContentVersion initialVersion;
/** enthhlt den Klassennamen des Attributes, welches ein generieren des Contents
beim letzten Aufruf von getGeneratableVersion verhindert hat */
private String generatableVersionStatus = null;
public Content(Integer _contentNodeId, String _name, String _shortName, Integer _instanceId, Integer _formularId , boolean single, Integer _parentId)
{
contentNodeId = _contentNodeId;
name = _name;
shortName = _shortName;
instanceId = _instanceId;
formularId = _formularId;
isSingle = single;
parentId = _parentId;
}
/** zum erzeugen eines Contents ber die contentnodeid
@param _contentNodeId - ContentNode-Id */
public Content(Integer _contentNodeId)
{
contentNodeId = _contentNodeId;
}
/**
hier werden beim Lesen von der Datenbank
die einzelnen Versionen dazugefuegt
@param version - hinzuzufgende Version
*/
public void addVersion(ContentVersion version)
{
versions.addElement(version);
if (initialVersion == null || version.getId().intValue() < initialVersion.getId().intValue())
initialVersion = version;
}
/** @return gibt die instanceid des contents zurck */
public Integer getInstanceId()
{
return instanceId;
}
public ContentVersion getInitialVersion()
{
return initialVersion;
}
public void setInstanceId(Integer id)
{
instanceId = id;
}
public Integer getParentId()
{
return parentId;
}
public void setParentId(Integer _id)
{
parentId = _id;
}
/** gibt die Contentnodeid des Contents zurck */
public Integer getId()
{
return contentNodeId;
}
public void setRefNodeId(Integer id)
{
refNodeId = id;
}
public Integer getRefNodeId()
{
return refNodeId;
}
public TKVector getAllVersions()
{
return versions;
}
public void setInterestingVersions(TKHashtable table)
{
interesting = table;
}
public String getShortName()
{
return shortName;
}
public Integer getFormularId()
{
return formularId;
}
public String getName()
{
return name;
}
/**
updatet die Definition eines Contents, also saemtliche Daten, die in
der Tabelle CONTENT_TREE gehalten werden
vorher saemtliche Parameter durch die entsprechenden setter setzen
*/
public void updateDefinition() throws Throwable, TKException
{
if (shortName == null && name != null)
{
shortName = CEUtils.checkFileName( name);
}
if (name == null || name.equals(""))
throw new TKUserException("Es mu ein Name angegeben werden", NO_PATHNAME, USER_SEVERITY, true, null);
CEUtils.isValidPathname( shortName );
if (!isSingle)
CEUtils.checkShortName(parentId, contentNodeId, shortName);
TKQuery q = TKDBManager.newQuery(TKDBContentTreeUpdateNode.class);
q.setQueryParams( "CONTENT_NODE_ID", contentNodeId );
q.setQueryParams( "CONTENT_NODE_NAME", name );
q.setQueryParams( "CONTENT_NODE_SHORTNAME", shortName );
q.setQueryParams( "CONTENT_NODE_TYPE", SINGLE_INTEGER );
q.setQueryParams( "CONTENT_FORM", formularId );
q.setQueryParams( "TREE_ID", new Integer(0) );
q.setQueryParams( "PROTOTYPE_ID", TKNull.NULL );
q.execute();
}
/**
liefert Datum der aktuellsten interessanten Version zurueck
*/
public Date getLastDate()
{
Date date = null;
if (interesting != null)
{
Enumeration enum = interesting.elements();
int vid = -1;
while (enum.hasMoreElements())
{
ContentVersion v = (ContentVersion)enum.nextElement();
if (v.getId().intValue() > vid)
{
vid = v.getId().intValue();
date = v.getDate();
}
}
}
return date;
}
/**
liefert die aktuellste Version des Content zurueck
*/
public ContentVersion getCurrentVersion()
{
ContentVersion latest = null;
if (interesting != null)
{
Enumeration enum = interesting.elements();
int vid = -1;
while (enum.hasMoreElements())
{
ContentVersion v = (ContentVersion)enum.nextElement();
if (v.getId().intValue() > vid)
{
vid = v.getId().intValue();
latest = v;
}
}
}
return latest;
}
public TKHashtable getInterestingVersions()
{
return interesting;
}
/**
liefert eine generierbare Version zurueck
falls null zurckgeliefert wurde : @see getGeneratableVersionStatus
@return null, falls es keine generierbare Version gibt
*/
public ContentVersion getGeneratableVersion()
{
generatableVersionStatus = null;
Enumeration enum = interesting.elements();
while (enum.hasMoreElements())
{
ContentVersion v = (ContentVersion)enum.nextElement();
if (v.isGeneratable())
return v;
if (generatableVersionStatus != null)
generatableVersionStatus = v.getGeneratableVersionStatus();
}
return null;
}
/**
gibt null zurck, falls beim letzten Aufruf von getGeneratableVersion
keine Version aufgrund des Workflows zurckgegeben wurde.
Sonst den Klassennamen des Attributes, da ein generieren der Contentversion
verhindert hat.
*/
public String getGeneratableVersionStatus()
{
return generatableVersionStatus;
}
/**
wendet den Filter auf die ermittelten Versionen an
Achtung : Es wird keine Kopie von interesting erzeugt !!
@param filter die Filterdefinition
@param filtermode Von oder Nach Filter
@return true, falls noch Versionen vorhanden sind false sonst
*/
public boolean filterTransitions(TKHashtable filter, String filterMode)
{
Enumeration enum = interesting.keys();
// alle erzwungenen Zustaende bekommen, diese muessen alle definiert sein!
TKHashtable forced = VersionSelection.getForcedStatusList(filter);
if (filterMode != null)
filter.keys();
while (enum.hasMoreElements())
{
Integer statusId = (Integer)enum.nextElement();
String mode = (String)filter.get(statusId);
if (mode == null)
continue;
if (mode.equals("EXCLUDE"))
return false;
if (mode.equals("FORCE"))
{
forced.remove(statusId);
}
}
return interesting.size() > 0 && forced.size()==0;
}
/**
erzeugt eine neue Version ohne neuen Content
@param neuerStatus
@param checkuserrights (sollen auch die Userrechte geprft werden ?)
*/
public void switchToStatus(Integer neuerStatus, String user, boolean checkuserrights) throws TKUserException, SQLException
{
// interesting holen
// checken ob die Transition erlaubt ist
Enumeration enum = interesting.keys();
boolean allowed = false;
ContentVersion quelle = null;
while (enum.hasMoreElements())
{
Integer status = (Integer)enum.nextElement();
ContentVersion version = (ContentVersion)interesting.get(status);
if (checkuserrights)
allowed = VersionControl.isAllowedTransition(version, neuerStatus, true);
else
allowed = VersionControl.isAllowedTransition(version, neuerStatus);
if (allowed)
{
quelle = version;
break;
}
}
if (!allowed)
{
throw new TKUserException("Ungltige Operation", INVALID_WORKFLOW, USER_SEVERITY, false, null);
}
// wenn ja schalten
TKQuery q = TKDBManager.newQuery(TKDBContentNewVersionByVersionId.class);
q.setQueryParams( "INSTANCE_ID", instanceId );
q.setQueryParams( "VERSION_ID", quelle.getId() ); // nur zum ermitteln der ContentId
q.setQueryParams( "STATUS_ID", neuerStatus );
q.setQueryParams( "VERS_INFO", "%Content.switchToStatus" );
q.setQueryParams( "VERS_AUTHOR", user );
q.execute();
}
/**
erzeugt eine neue Version ohne neuen Content
@param neuerStatus
*/
public void switchToStatus(Integer neuerStatus, String user) throws TKUserException, SQLException
{
this.switchToStatus(neuerStatus, user, false);
}
/**
ermittelt den vollen Pfad im Content
*/
public String getFullPath() throws Throwable
{
return CEUtils.getCurrentPath(contentNodeId);
}
/**
* zum Anzeigen in der Oberflaeche werden die Daten in ein verschachteltes
* TKHashtable/TKVector Format gebracht
*/
public TKHashtable toHashtable(){
if (templateData != null){
return templateData;
}
// unter CHOICES alle interessanten Versionen ablegen
templateData = new TKHashtable();
templateData.put("SUB_CONTENT_NODE_NAME", name);
templateData.put("SUB_CONTENT_NODE_SHORTNAME", shortName);
templateData.put ("INSTANCE_ID",instanceId);
templateData.put ("SUB_CONTENT_NODE_ID",contentNodeId);
templateData.put ("SUB_CONTENT_NODE_TYPE",new Integer (3));
templateData.put ("NAME","");
templateData.put ("CONTENT_FORM",formularId);
templateData.put ("TOP_DATE",
DATE_FORMAT.format((getLastDate())));
if (isSingle){
templateData.put("IS_SINGLE", "1");
}
templateData.put("CHOICES", getInterestingVersions());
TKEvent evt = TKEvent.getEventForThread();
try{
WebManEvent.fillEventsIntoHash(evt, templateData, ContextConstants.CONTENT_EDIT, Policy.CONTENT_TREE_ID, contentNodeId);
}
catch (Throwable t){
cat.error("Unable to get events for content" , t);
}
return templateData;
}
public String toString()
{
String text = " Content " + name;
text += ", Kennung: " + shortName;
text += ", ID : " + contentNodeId;
text += ", Instanz : " + instanceId;
text += ", OID : " + super.toString();
return text;
}
}
|