/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.vertical.engine.handlers;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.enonic.esl.sql.model.Column;
import com.enonic.esl.sql.model.Table;
import com.enonic.esl.util.ArrayUtil;
import com.enonic.esl.util.StringUtil;
import com.enonic.esl.xml.XMLTool;
import com.enonic.vertical.engine.AccessRight;
import com.enonic.vertical.engine.VerticalEngineLogger;
import com.enonic.vertical.engine.VerticalRemoveException;
import com.enonic.vertical.engine.XDG;
import com.enonic.vertical.engine.dbmodel.ContentPubKeyView;
import com.enonic.vertical.engine.dbmodel.ContentPubKeysView;
import com.enonic.vertical.engine.dbmodel.ContentPublishedView;
import com.enonic.vertical.engine.dbmodel.ContentVersionView;
import com.enonic.vertical.engine.dbmodel.ContentView;
import com.enonic.vertical.engine.processors.ContentTypeProcessor;
import com.enonic.vertical.engine.processors.ElementProcessor;
import com.enonic.vertical.engine.processors.VersionKeyContentMapProcessor;
import com.enonic.cms.framework.util.TIntArrayList;
import com.enonic.cms.framework.util.TIntObjectHashMap;
import com.enonic.cms.framework.xml.XMLDocument;
import com.enonic.cms.framework.xml.XMLDocumentFactory;
import com.enonic.cms.core.CalendarUtil;
import com.enonic.cms.core.content.ContentEntity;
import com.enonic.cms.core.content.ContentKey;
import com.enonic.cms.core.content.ContentTitleXmlCreator;
import com.enonic.cms.core.content.category.CategoryKey;
import com.enonic.cms.core.content.contenttype.ContentHandlerEntity;
import com.enonic.cms.core.content.contenttype.ContentHandlerKey;
import com.enonic.cms.core.content.contenttype.ContentTypeEntity;
import com.enonic.cms.core.content.contenttype.ContentTypeKey;
import com.enonic.cms.core.language.LanguageKey;
import com.enonic.cms.core.resource.ResourceKey;
import com.enonic.cms.core.security.user.User;
import com.enonic.cms.core.security.user.UserKey;
import com.enonic.cms.core.security.user.UserNameXmlCreator;
import com.enonic.cms.core.structure.menuitem.MenuItemEntity;
import com.enonic.cms.store.dao.ContentHandlerDao;
import com.enonic.cms.store.dao.ContentTypeDao;
@Component
public final class ContentHandler
extends BaseHandler
{
private final static String CTY_TABLE = "tContentType";
private final static String HAN_TABLE = "tContentHandler";
private final static String CON_IS_CHILD = "SELECT rco_con_lParent,rco_con_lChild FROM TRELATEDCONTENT WHERE rco_con_lChild = ?";
// tContentType
private final static String CTY_INSERT = "INSERT INTO " + CTY_TABLE +
"(cty_lkey, cty_sname, cty_sdescription, cty_mbdata, cty_dtetimestamp, cty_han_lkey, cty_blocal, cty_scss) " +
" VALUES (?,?,?,?,@currentTimestamp@" + ",?,?,?)";
private final static String CTY_DELETE = "DELETE FROM " + CTY_TABLE + " WHERE cty_lKey=?";
private final static String CTY_UPDATE = "UPDATE tContentType " + "SET cty_sName = ?" + ",cty_sDescription = ?" + ",cty_mbData = ?" +
",cty_dteTimestamp = @currentTimestamp@" + ",cty_han_lKey = ?" + ",cty_sCSS = ?" + " WHERE cty_lKey = ?";
private final static String CTY_SELECT_KEY = "SELECT cty_lKey FROM " + CTY_TABLE;
private final static String CTY_WHERE_CLAUSE_HAN = " cty_han_lKey = ?";
// tContentHandler
private final static String HAN_INSERT = "INSERT INTO " + HAN_TABLE +
"(han_lkey, han_sname, han_sclass,han_sdescription,han_xmlconfig,han_dtetimestamp)" + " VALUES (?,?,?,?,?,@currentTimestamp@)";
private final static String HAN_SELECT_KEY = "SELECT han_lKey FROM " + HAN_TABLE;
private final static String HAN_WHERE_CLAUSE_CLASS = " han_sClass = ?";
private final static String HAN_UPDATE =
"UPDATE " + HAN_TABLE + " SET han_sName = ?" + ",han_sDescription = ?" + ",han_sClass = ?" + ",han_xmlConfig = ?" +
",han_dteTimestamp = @currentTimestamp@" + " WHERE han_lKey = ?";
private final static String HAN_DELETE = "DELETE FROM " + HAN_TABLE + " WHERE han_lKey = ?";
@Autowired
private ContentTypeDao contentTypeDao;
@Autowired
private ContentHandlerDao contentHandlerDao;
public CategoryKey getCategoryKey( int contentKey )
{
ContentEntity entity = contentDao.findByKey( new ContentKey( contentKey ) );
if ( ( entity != null ) && !entity.isDeleted() )
{
return entity.getCategory().getKey();
}
else
{
return null;
}
}
private int[] getCategoryKeys( int[] contentKeys )
{
if ( contentKeys == null || contentKeys.length == 0 )
{
return new int[0];
}
CommonHandler commonHandler = getCommonHandler();
StringBuffer sql = XDG.generateSelectWhereInSQL( db.tContent, db.tContent.con_cat_lKey, db.tContent.con_lKey, contentKeys.length );
return commonHandler.getIntArray( sql.toString(), contentKeys );
}
public Document getContentTypesDocument( int[] contentTypeKeys )
{
Document doc = XMLTool.createDocument( "contenttypes" );
if ( contentTypeKeys.length > 0 )
{
for ( int contentTypeKey : contentTypeKeys )
{
Element contentTypeElem = XMLTool.createElement( doc, doc.getDocumentElement(), "contenttype" );
contentTypeElem.setAttribute( "key", Integer.toString( contentTypeKey ) );
XMLTool.createElement( doc, contentTypeElem, "name", getContentHandler().getContentTypeName( contentTypeKey ) );
}
}
return doc;
}
public boolean contentExists( CategoryKey categoryKey, String contentTitle )
{
ContentView contentView = ContentView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( contentView, contentView.con_lKey.getCountColumn(), null );
XDG.appendWhereSQL( sql, contentView.cat_lKey, XDG.OPERATOR_EQUAL, categoryKey.toInt() );
XDG.appendWhereSQL( sql, contentView.cov_sTitle, contentTitle );
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getBoolean( sql.toString() );
}
public int getContentKey( CategoryKey categoryKey, String contentTitle )
{
ContentView contentView = ContentView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( contentView, contentView.con_lKey, null );
XDG.appendWhereSQL( sql, contentView.cat_lKey, XDG.OPERATOR_EQUAL, categoryKey.toInt() );
XDG.appendWhereSQL( sql, contentView.cov_sTitle );
sql.append( " ?" );
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getInt( sql.toString(), contentTitle );
}
public String getCreatedTimestamp( int contentKey )
{
ContentView contentView = ContentView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( contentView, contentView.con_dteCreated, false, contentView.con_lKey );
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getString( sql.toString(), contentKey );
}
public Date getPublishFromTimestamp( int contentKey )
{
ContentView contentView = ContentView.getInstance();
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getTimestamp( contentView, contentView.con_dtePublishFrom, contentView.con_lKey, contentKey );
}
public Date getPublishToTimestamp( int contentKey )
{
ContentView contentView = ContentView.getInstance();
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getTimestamp( contentView, contentView.con_dtePublishTo, contentView.con_lKey, contentKey );
}
public int createContentType( Document doc )
{
PreparedStatement preparedStmt = null;
int key = -1;
try
{
Connection con = getConnection();
preparedStmt = con.prepareStatement( CTY_INSERT );
Element root = doc.getDocumentElement();
Map<String, Element> subelems = XMLTool.filterElements( root.getChildNodes() );
String keyStr = root.getAttribute( "key" );
if ( keyStr.length() > 0 )
{
key = Integer.parseInt( keyStr );
}
else
{
key = getNextKey( CTY_TABLE );
}
Element subelem = subelems.get( "name" );
String name = XMLTool.getElementText( subelem );
subelem = subelems.get( "description" );
String description;
if ( subelem != null )
{
description = XMLTool.getElementText( subelem );
}
else
{
description = null;
}
subelem = subelems.get( "moduledata" );
Document moduleDoc = XMLTool.createDocument();
moduleDoc.appendChild( moduleDoc.importNode( subelem, true ) );
byte[] mdocBytes = XMLTool.documentToBytes( moduleDoc, "UTF-8" );
preparedStmt.setInt( 1, key );
preparedStmt.setString( 2, name );
if ( description != null )
{
preparedStmt.setString( 3, description );
}
else
{
preparedStmt.setNull( 3, Types.VARCHAR );
}
preparedStmt.setBytes( 4, mdocBytes );
String contentHandlerKeyString = root.getAttribute( "contenthandlerkey" );
int contentHandlerKey = Integer.parseInt( contentHandlerKeyString );
preparedStmt.setInt( 5, contentHandlerKey );
preparedStmt.setInt( 6, 0 );
// CSS key
String cssKeyStr = root.getAttribute( "csskey" );
if ( cssKeyStr.length() > 0 )
{
preparedStmt.setString( 7, cssKeyStr );
}
else
{
preparedStmt.setNull( 7, Types.VARCHAR );
}
// add the content type
int result = preparedStmt.executeUpdate();
if ( result == 0 )
{
String message = "Failed to create content type. No content type created.";
VerticalEngineLogger.errorCreate( message, null );
}
}
catch ( SQLException sqle )
{
String message = "Failed to create content type: %t";
VerticalEngineLogger.errorCreate( message, sqle );
}
finally
{
close( preparedStmt );
}
return key;
}
public Document getContent( User user, int contentKey, boolean publishedOnly, int parentLevel, int childrenLevel,
int parentChildrenLevel )
{
return getContents( user, new int[]{contentKey}, publishedOnly, parentLevel, childrenLevel, parentChildrenLevel );
}
private Document getContents( User user, int[] contentKeys, boolean publishedOnly, int parentLevel, int childrenLevel,
int parentChildrenLevel )
{
ContentView contentView = ContentView.getInstance();
if ( contentKeys == null || contentKeys.length == 0 )
{
return XMLTool.createDocument( "contents" );
}
Table contentTable;
if ( publishedOnly )
{
contentTable = ContentPublishedView.getInstance();
}
else
{
contentTable = contentView;
}
Column[] selectColumns = null;
StringBuffer sql = XDG.generateSelectSQL( contentTable, selectColumns, false, null );
XDG.appendWhereInSQL( sql, contentView.con_lKey, contentKeys.length );
List<Integer> paramValues = ArrayUtil.toArrayList( contentKeys );
String sqlString = sql.toString();
if ( user != null )
{
int[] categoryKeys = getCategoryKeys( contentKeys );
sqlString = getSecurityHandler().appendContentSQL( user, categoryKeys, sqlString );
}
return doGetContents( user, null, null, sqlString, paramValues, publishedOnly, parentLevel, childrenLevel, parentChildrenLevel );
}
public String getContentTitle( int versionKey )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContentVersion, db.tContentVersion.cov_sTitle, false, db.tContentVersion.cov_lKey );
return getCommonHandler().getString( sql.toString(), versionKey );
}
public Document getContentType( int contentTypeKey, boolean includeContentCount )
{
return getContentTypes( new int[]{contentTypeKey}, includeContentCount );
}
public ResourceKey getContentTypeCSSKey( int contentTypeKey )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContentType, db.tContentType.cty_sCSS, false, db.tContentType.cty_lKey );
String resourceKey = getCommonHandler().getString( sql.toString(), contentTypeKey );
return ResourceKey.from( resourceKey );
}
public int getContentTypeKey( int contentKey )
{
ContentEntity entity = contentDao.findByKey( new ContentKey( contentKey ) );
return entity != null ? entity.getCategory().getContentType().getKey() : -1;
}
public int[] getContentTypeKeysByHandler( String handlerClass )
{
int contentHandlerKey = getContentHandlerKeyByHandlerClass( handlerClass );
return getContentTypeKeysByHandler( contentHandlerKey );
}
public int[] getContentTypeKeysByHandler( int contentHandlerKey )
{
StringBuilder sql = new StringBuilder( CTY_SELECT_KEY );
sql.append( " WHERE" );
sql.append( CTY_WHERE_CLAUSE_HAN );
return getContentTypeKeys( sql.toString(), contentHandlerKey );
}
public String getContentTypeName( int contentTypeKey )
{
ContentTypeEntity entity = contentTypeDao.findByKey( new ContentTypeKey( contentTypeKey ) );
return entity != null ? entity.getName() : null;
}
public Document getContentTypes( boolean includeContentCount )
{
return getContentTypes( null, includeContentCount );
}
public Document getContentTypes( int[] contentTypeKeys, boolean includeContentCount )
{
List<ContentTypeEntity> list;
if ( contentTypeKeys != null && contentTypeKeys.length > 0 )
{
list = new ArrayList<ContentTypeEntity>();
for ( int key : contentTypeKeys )
{
ContentTypeEntity entity = contentTypeDao.findByKey( new ContentTypeKey( key ) );
if ( entity != null )
{
list.add( entity );
}
}
}
else
{
list = contentTypeDao.getAll();
}
return createContentTypesDoc( list, includeContentCount );
}
public Document getContentOwner( int contentKey )
{
UserKey ownerKey = getOwnerKey( contentKey );
User owner = userDao.findByKey( ownerKey );
UserNameXmlCreator userNameXmlCreator = new UserNameXmlCreator();
return XMLDocumentFactory.create( userNameXmlCreator.createUserNamesDocument( owner ) ).getAsDOMDocument();
}
public UserKey getOwnerKey( int contentKey )
{
ContentEntity content = contentDao.findByKey( new ContentKey( contentKey ) );
return content.getOwner().getKey();
}
public int getState( int versionKey )
{
ContentVersionView versionView = ContentVersionView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( versionView, versionView.cov_lState, false, versionView.cov_lKey );
return getCommonHandler().getInt( sql.toString(), versionKey );
}
public void removeContentType( int contentTypeKey )
throws VerticalRemoveException
{
PreparedStatement preparedStmt = null;
getCommonHandler().cascadeDelete( db.tContentType, contentTypeKey );
try
{
Connection con = getConnection();
preparedStmt = con.prepareStatement( CTY_DELETE );
preparedStmt.setInt( 1, contentTypeKey );
preparedStmt.executeUpdate();
}
catch ( SQLException sqle )
{
String message = "Failed to remove content type: %t";
VerticalEngineLogger.errorRemove( message, sqle );
}
finally
{
close( preparedStmt );
}
}
public void updateContentType( Document doc )
{
PreparedStatement preparedStmt = null;
try
{
Element root = doc.getDocumentElement();
Map<String, Element> subelems = XMLTool.filterElements( root.getChildNodes() );
int key = Integer.parseInt( root.getAttribute( "key" ) );
Element subelem = subelems.get( "name" );
String name = XMLTool.getElementText( subelem );
subelem = subelems.get( "description" );
String description;
if ( subelem != null )
{
description = XMLTool.getElementText( subelem );
}
else
{
description = null;
}
Element moduleElem = subelems.get( "moduledata" );
Document moduleDoc = XMLTool.createDocument();
moduleDoc.appendChild( moduleDoc.importNode( moduleElem, true ) );
byte[] mdocBytes = XMLTool.documentToBytes( moduleDoc, "UTF-8" );
Connection con = getConnection();
preparedStmt = con.prepareStatement( CTY_UPDATE );
preparedStmt.setInt( 6, key );
preparedStmt.setString( 1, name );
if ( description != null )
{
preparedStmt.setString( 2, description );
}
else
{
preparedStmt.setNull( 2, Types.VARCHAR );
}
preparedStmt.setBytes( 3, mdocBytes );
String contentHandlerKeyString = root.getAttribute( "contenthandlerkey" );
int contentHandlerKey = Integer.parseInt( contentHandlerKeyString );
preparedStmt.setInt( 4, contentHandlerKey );
// CSS key
String cssKeyStr = root.getAttribute( "csskey" );
if ( cssKeyStr.length() > 0 )
{
preparedStmt.setString( 5, cssKeyStr );
}
else
{
preparedStmt.setNull( 5, Types.VARCHAR );
}
preparedStmt.executeUpdate();
preparedStmt.close();
preparedStmt = null;
}
catch ( SQLException sqle )
{
String message = "Failed to update content type: %t";
VerticalEngineLogger.errorUpdate( message, sqle );
}
catch ( NumberFormatException nfe )
{
String message = "Failed to parse content type key: %t";
VerticalEngineLogger.errorUpdate( message, nfe );
}
finally
{
close( preparedStmt );
}
}
private Document doGetContents( User user, Set<Integer> referencedKeys, Element contentsElem, String sql, List<Integer> paramValues,
boolean publishedOnly, int parentLevel, int childrenLevel, int parentChildrenLevel )
{
final int count = Integer.MAX_VALUE;
PreparedStatement preparedStmt = null;
ResultSet resultSet = null;
PreparedStatement childPreparedStmt = null;
ResultSet childResultSet = null;
Document doc;
Element root;
doc = XMLTool.createDocument( "contents" );
if ( contentsElem == null )
{
root = doc.getDocumentElement();
}
else
{
doc = contentsElem.getOwnerDocument();
root = contentsElem;
}
Set<Integer> contentKeys;
if ( referencedKeys == null )
{
contentKeys = new HashSet<Integer>();
}
else
{
contentKeys = referencedKeys;
}
try
{
Connection con = getConnection();
childPreparedStmt = con.prepareStatement( CON_IS_CHILD );
preparedStmt = con.prepareStatement( sql );
int paramIndex = -1;
if ( paramValues != null )
{
int i = 1;
for ( Iterator<Integer> iter = paramValues.iterator(); iter.hasNext(); i++ )
{
Object paramValue = iter.next();
preparedStmt.setObject( i, paramValue );
}
}
resultSet = preparedStmt.executeQuery();
TIntArrayList parentKeys = new TIntArrayList();
TIntArrayList childrenKeys = new TIntArrayList();
boolean moreResults = resultSet.next();
// related content keys elememt map
TIntObjectHashMap contentKeyRCKElemMap = new TIntObjectHashMap();
TIntObjectHashMap versionKeyRCKElemMap = new TIntObjectHashMap();
// content binaries processor
VersionKeyContentMapProcessor versionKeyContentMapProcessor = new VersionKeyContentMapProcessor( this );
SectionHandler sectionHandler = getSectionHandler();
int i = 0;
while ( ( i < count ) && ( moreResults || ( paramIndex > 0 && paramIndex < paramValues.size() ) ) )
{
// if we have a result, get data
if ( i >= 0 && moreResults )
{
// pre-fetch content data
Document contentdata;
InputStream contentDataIn = resultSet.getBinaryStream( "cov_xmlContentData" );
contentdata = XMLTool.domparse( contentDataIn );
Integer contentKey = resultSet.getInt( "con_lKey" );
if ( contentKeys.contains( contentKey ) )
{
moreResults = resultSet.next();
continue;
}
contentKeys.add( contentKey );
int versionKey = getCurrentVersionKey( contentKey );
Element elem = XMLTool.createElement( doc, root, "content" );
elem.setAttribute( "key", contentKey.toString() );
String unitKey = resultSet.getString( "cat_uni_lKey" );
if ( !resultSet.wasNull() )
{
elem.setAttribute( "unitkey", unitKey );
}
elem.setAttribute( "contenttypekey", resultSet.getString( "cat_cty_lKey" ) );
elem.setAttribute( "versionkey", String.valueOf( versionKey ) );
LanguageKey languageKey = new LanguageKey( resultSet.getInt( "con_lan_lKey" ) );
elem.setAttribute( "languagekey", String.valueOf( languageKey ) );
elem.setAttribute( "languagecode", getLanguageHandler().getLanguageCode( languageKey ) );
elem.setAttribute( "priority", resultSet.getString( "con_lPriority" ) );
Timestamp publishfrom = resultSet.getTimestamp( "con_dtePublishFrom" );
if ( !resultSet.wasNull() )
{
elem.setAttribute( "publishfrom", CalendarUtil.formatTimestamp( publishfrom ) );
}
Timestamp publishto = resultSet.getTimestamp( "con_dtePublishTo" );
if ( !resultSet.wasNull() )
{
elem.setAttribute( "publishto", CalendarUtil.formatTimestamp( publishto ) );
}
Timestamp created = resultSet.getTimestamp( "con_dteCreated" );
elem.setAttribute( "created", CalendarUtil.formatTimestamp( created ) );
Timestamp timestamp = resultSet.getTimestamp( "cov_dteTimestamp" );
elem.setAttribute( "timestamp", CalendarUtil.formatTimestamp( timestamp ) );
// content status
// 0: draft
// 1: not published
// 2: publish date undecided
// 3: archived
// 4: publish waiting
// 5: published
// 6: publish expired
elem.setAttribute( "status", resultSet.getString( "cov_lStatus" ) );
elem.setAttribute( "state", resultSet.getString( "cov_lState" ) );
// owner info
Element ownerElem = XMLTool.createElement( doc, elem, "owner", resultSet.getString( "usr_sOwnerName" ) );
ownerElem.setAttribute( "key", resultSet.getString( "usr_hOwner" ) );
ownerElem.setAttribute( "uid", resultSet.getString( "usr_sOwnerUID" ) );
ownerElem.setAttribute( "deleted", String.valueOf( resultSet.getBoolean( "usr_bOwnerDeleted" ) ) );
// modifier info
Element modifierElem = XMLTool.createElement( doc, elem, "modifier", resultSet.getString( "usr_sModifierName" ) );
modifierElem.setAttribute( "key", resultSet.getString( "usr_hModifier" ) );
modifierElem.setAttribute( "uid", resultSet.getString( "usr_sModifierUID" ) );
modifierElem.setAttribute( "deleted", String.valueOf( resultSet.getBoolean( "usr_bModDeleted" ) ) );
XMLTool.createElement( doc, elem, "title", resultSet.getString( "cov_sTitle" ) );
// add previous pre-fetched content data
Node contentDataRoot = doc.importNode( contentdata.getDocumentElement(), true );
elem.appendChild( contentDataRoot );
// is the content a child?
childPreparedStmt.setInt( 1, contentKey );
childResultSet = childPreparedStmt.executeQuery();
if ( childResultSet.next() )
{
elem.setAttribute( "child", "true" );
}
close( childResultSet );
childResultSet = null;
Element e = XMLTool.createElement( doc, elem, "categoryname", resultSet.getString( "cat_sName" ) );
e.setAttribute( "key", resultSet.getString( "cat_lKey" ) );
sectionHandler.appendSectionNames( contentKey, elem );
// get the content's children and parent keys according to children and parent levels
Element relatedcontentkeysElem = XMLTool.createElement( doc, elem, "relatedcontentkeys" );
contentKeyRCKElemMap.put( contentKey, relatedcontentkeysElem );
versionKeyRCKElemMap.put( versionKey, relatedcontentkeysElem );
// Always add version info
versionKeyContentMapProcessor.process( elem );
// increase index
i++;
}
else if ( i < 0 )
{
i++;
}
moreResults = resultSet.next();
}
if ( resultSet != null )
{
resultSet.close();
resultSet = null;
}
preparedStmt.close();
preparedStmt = null;
// add binaries elements
getContentBinaries( versionKeyContentMapProcessor.getVersionKeyContentMap() );
if ( parentLevel > 0 )
{
getParentContentKeys( parentKeys, contentKeyRCKElemMap, publishedOnly, true );
}
if ( childrenLevel > 0 )
{
getChildrenContentKeys( childrenKeys, versionKeyRCKElemMap, publishedOnly );
}
Element relatedcontentsElem;
if ( "relatedcontents".equals( root.getTagName() ) )
{
relatedcontentsElem = root;
}
else
{
relatedcontentsElem = XMLTool.createElement( doc, root, "relatedcontents" );
}
Table contentTable;
ContentView contentView = ContentView.getInstance();
if ( publishedOnly )
{
contentTable = ContentPublishedView.getInstance();
}
else
{
contentTable = contentView;
}
if ( parentLevel > 0 && parentKeys.size() > 0 )
{
Column[] selectColumns = null;
int[] parentContentKeys = parentKeys.toArray();
StringBuffer sqlString = XDG.generateSelectSQL( contentTable, selectColumns, false, null );
XDG.appendWhereInSQL( sqlString, contentView.cov_lKey, parentContentKeys );
int[] categoryKeys = getCategoryKeys( parentContentKeys );
String tempSql = sqlString.toString();
tempSql = getSecurityHandler().appendContentSQL( user, categoryKeys, tempSql );
parentChildrenLevel = Math.min( parentChildrenLevel, 3 );
doGetContents( user, contentKeys, relatedcontentsElem, tempSql, null, publishedOnly, parentLevel - 1, parentChildrenLevel,
parentChildrenLevel
// includeStatistics
// includeSectionNames
);
}
if ( childrenLevel > 0 && childrenKeys.size() > 0 )
{
Column[] selectColumns = null;
StringBuffer sqlString = XDG.generateSelectSQL( contentTable, selectColumns, false, null );
sqlString.append( " WHERE con_lKey IN (" );
int[] childrenContentKeys = childrenKeys.toArray();
int[] categoryKeys = getCategoryKeys( childrenContentKeys );
for ( int childrenContentKey : childrenContentKeys )
{
sqlString.append( childrenContentKey );
sqlString.append( ',' );
}
sqlString.replace( sqlString.length() - 1, sqlString.length(), ")" );
String tempSql = sqlString.toString();
tempSql = getSecurityHandler().appendContentSQL( user, categoryKeys, tempSql );
doGetContents( user, contentKeys, relatedcontentsElem, tempSql, null, publishedOnly, 0, childrenLevel - 1, 0
// includeStatistics
// includeSectionNames
);
}
if ( contentsElem == null )
{
StringBuffer countSql = new StringBuffer( sql );
int orderByIndex = sql.indexOf( "ORDER BY" );
int lastParenthesisIndex = sql.lastIndexOf( ")" );
if ( orderByIndex > 0 )
{
countSql.delete( orderByIndex, sql.length() );
}
// append parenthesis if neccessary
if ( orderByIndex != -1 && lastParenthesisIndex > orderByIndex )
{
countSql.append( ")" );
}
countSql.replace( "SELECT ".length(), sql.indexOf( " FROM" ), "count(distinct con_lKey) AS con_lCount" );
preparedStmt = con.prepareStatement( countSql.toString() );
if ( paramValues != null )
{
for ( i = 0; i < paramValues.size(); i++ )
{
preparedStmt.setObject( i + 1, paramValues.get( i ) );
}
}
resultSet = preparedStmt.executeQuery();
if ( resultSet.next() )
{
root.setAttribute( "totalcount", resultSet.getString( "con_lCount" ) );
}
}
}
catch ( SQLException sqle )
{
String message = "Failed to get contents; %t";
VerticalEngineLogger.error( message, sqle );
if ( contentsElem != null )
{
XMLTool.removeChildNodes( contentsElem, false );
}
else
{
doc = XMLTool.createDocument( "contents" );
}
}
finally
{
close( resultSet );
close( preparedStmt );
close( childResultSet );
close( childPreparedStmt );
}
return doc;
}
private void getChildrenContentKeys( TIntArrayList childrenKeys, TIntObjectHashMap rckElemMap, boolean publishedOnly )
{
if ( rckElemMap.size() == 0 )
{
return;
}
Column[] selectColumns = {db.tRelatedContent.rco_con_lChild, db.tRelatedContent.rco_con_lParent};
StringBuffer sql = XDG.generateSelectSQL( db.tRelatedContent, selectColumns, false, null );
if ( publishedOnly )
{
XDG.appendJoinSQL( sql, db.tRelatedContent.rco_con_lChild, ContentPubKeyView.getInstance(), db.tContent.con_lKey );
}
else
{
XDG.appendJoinSQL( sql, db.tRelatedContent.rco_con_lChild, db.tContent, db.tContent.con_lKey );
XDG.appendWhereSQL( sql, db.tContent.con_bDeleted, XDG.OPERATOR_EQUAL, 0 );
}
XDG.appendWhereInSQL( sql, db.tRelatedContent.rco_con_lParent, rckElemMap.keys() );
Object[][] keys = getCommonHandler().getObjectArray( sql.toString(), (int[]) null );
for ( Object[] key : keys )
{
int childContentKey = ( (Number) key[0] ).intValue();
int parentVersionKey = ( (Number) key[1] ).intValue();
Element relatedcontentkeysElem = (Element) rckElemMap.get( parentVersionKey );
Document doc = relatedcontentkeysElem.getOwnerDocument();
Element relatedcontentkey = XMLTool.createElement( doc, relatedcontentkeysElem, "relatedcontentkey" );
if ( !childrenKeys.contains( childContentKey ) )
{
childrenKeys.add( childContentKey );
}
relatedcontentkey.setAttribute( "key", String.valueOf( childContentKey ) );
relatedcontentkey.setAttribute( "level", "1" );
}
}
private void getParentContentKeys( TIntArrayList parentKeys, TIntObjectHashMap rckElemMap, boolean publishedOnly, boolean currentOnly )
{
if ( rckElemMap.size() == 0 )
{
return;
}
StringBuffer sql;
if ( publishedOnly )
{
ContentPubKeysView view = ContentPubKeysView.getInstance();
Column[] selectColumns = {view.con_lKey, db.tRelatedContent.rco_con_lParent, db.tRelatedContent.rco_con_lChild};
sql = XDG.generateSelectSQL( db.tRelatedContent, selectColumns, false, null );
XDG.appendJoinSQL( sql, db.tRelatedContent.rco_con_lParent, view, view.cov_lKey );
XDG.appendWhereInSQL( sql, db.tRelatedContent.rco_con_lChild, rckElemMap.keys() );
}
else if ( currentOnly )
{
ContentVersionView versionView = ContentVersionView.getInstance();
Column[] selectColumns = {versionView.con_lKey, db.tRelatedContent.rco_con_lParent, db.tRelatedContent.rco_con_lChild};
sql = XDG.generateSelectSQL( db.tRelatedContent, selectColumns, false, null );
XDG.appendJoinSQL( sql, db.tRelatedContent.rco_con_lParent, versionView, versionView.cov_lKey );
XDG.appendWhereInSQL( sql, db.tRelatedContent.rco_con_lChild, rckElemMap.keys() );
XDG.appendWhereSQL( sql, versionView.cov_bCurrent, XDG.OPERATOR_EQUAL, 1 );
}
else
{
Column[] selectColumns =
{db.tContentVersion.cov_con_lKey, db.tRelatedContent.rco_con_lParent, db.tRelatedContent.rco_con_lChild};
sql = XDG.generateSelectSQL( db.tRelatedContent, selectColumns, false, null );
XDG.appendJoinSQL( sql, db.tRelatedContent.rco_con_lParent, db.tContentVersion, db.tContentVersion.cov_lKey );
XDG.appendJoinSQL( sql, db.tContentVersion.cov_con_lKey, db.tContent, db.tContent.con_lKey );
XDG.appendWhereInSQL( sql, db.tRelatedContent.rco_con_lChild, rckElemMap.keys() );
XDG.appendWhereSQL( sql, db.tContent.con_bDeleted, XDG.OPERATOR_EQUAL, 0 );
}
Object[][] keys = getCommonHandler().getObjectArray( sql.toString(), (int[]) null );
for ( int i = 0; i < keys.length; i++ )
{
int parentContentKey = ( (Number) keys[i][0] ).intValue();
int parentVersionKey = ( (Number) keys[i][1] ).intValue();
int childContentKey = ( (Number) keys[i][2] ).intValue();
Element relatedcontentkeysElem = (Element) rckElemMap.get( childContentKey );
Document doc = relatedcontentkeysElem.getOwnerDocument();
Element relatedcontentkey = XMLTool.createElement( doc, relatedcontentkeysElem, "relatedcontentkey" );
if ( !parentKeys.contains( parentVersionKey ) )
{
parentKeys.add( parentVersionKey );
}
relatedcontentkey.setAttribute( "key", String.valueOf( parentContentKey ) );
relatedcontentkey.setAttribute( "versionkey", String.valueOf( parentVersionKey ) );
relatedcontentkey.setAttribute( "level", "-1" );
}
}
private Document createContentTypesDoc( List<ContentTypeEntity> list, boolean includeContentCount )
{
Document doc = XMLTool.createDocument( "contenttypes" );
Element root = doc.getDocumentElement();
if ( list == null )
{
return doc;
}
for ( ContentTypeEntity entity : list )
{
Element elem = XMLTool.createElement( doc, root, "contenttype" );
elem.setAttribute( "key", String.valueOf( entity.getKey() ) );
elem.setAttribute( "contenthandlerkey", String.valueOf( entity.getContentHandler().getKey() ) );
elem.setAttribute( "handler", entity.getContentHandler().getClassName() );
if ( entity.getDefaultCssKey() != null )
{
elem.setAttribute( "csskey", entity.getDefaultCssKey().toString() );
elem.setAttribute( "csskeyexists",
resourceService.getResourceFile( entity.getDefaultCssKey() ) != null ? "true" : "false" );
}
if ( includeContentCount )
{
int count = getContentCountByContentType( entity.getKey() );
elem.setAttribute( "contentcount", String.valueOf( count ) );
}
XMLTool.createElement( doc, elem, "name", entity.getName() );
if ( entity.getDescription() != null )
{
XMLTool.createElement( doc, elem, "description", entity.getDescription() );
}
if ( entity.getData() != null )
{
Document modDoc = XMLTool.domparse( XMLTool.documentToString( entity.getData() ) );
Element mdElem = modDoc.getDocumentElement();
if ( mdElem.getTagName().equals( "module" ) )
{
Element tempElem = XMLTool.createElement( doc, elem, "moduledata" );
tempElem.appendChild( doc.importNode( mdElem, true ) );
}
else
{
elem.appendChild( doc.importNode( mdElem, true ) );
}
}
else
{
XMLTool.createElement( doc, elem, "moduledata" );
}
XMLTool.createElement( doc, elem, "timestamp", CalendarUtil.formatTimestamp( entity.getTimestamp(), true ) );
}
return doc;
}
public int getContentCountByContentType( int contentTypeKey )
{
ContentView contentView = ContentView.getInstance();
StringBuffer countSQL =
XDG.generateSelectSQL( contentView, contentView.con_lKey.getCountColumn(), false, contentView.cat_cty_lKey );
return getCommonHandler().getInt( countSQL.toString(), contentTypeKey );
}
private int[] getContentTypeKeys( String sql, int paramValue )
{
PreparedStatement preparedStmt = null;
ResultSet resultSet = null;
TIntArrayList contentTypeKeys = new TIntArrayList();
try
{
Connection con = getConnection();
preparedStmt = con.prepareStatement( sql );
preparedStmt.setInt( 1, paramValue );
resultSet = preparedStmt.executeQuery();
while ( resultSet.next() )
{
contentTypeKeys.add( resultSet.getInt( 1 ) );
}
}
catch ( SQLException sqle )
{
String message = "Failed to get content type keys: %t";
VerticalEngineLogger.error( message, sqle );
}
finally
{
close( resultSet );
close( preparedStmt );
}
return contentTypeKeys.toArray();
}
public String getContentHandlerClassForContentType( int contentTypeKey )
{
final ContentTypeEntity entity = contentTypeDao.findByKey( new ContentTypeKey( contentTypeKey ) );
if ( entity == null )
{
return null;
}
return entity.getContentHandler().getClassName();
}
public org.jdom.Document getContentHandler( final int contentHandlerKey )
{
final ContentHandlerEntity entity = this.contentHandlerDao.findByKey( new ContentHandlerKey( contentHandlerKey ) );
List<ContentHandlerEntity> list = Collections.emptyList();
if ( entity != null )
{
list = Collections.singletonList( entity );
}
return toDocument( list );
}
private int getContentHandlerKeyByHandlerClass( String handlerClass )
{
StringBuilder sql = new StringBuilder( HAN_SELECT_KEY );
sql.append( " WHERE" );
sql.append( HAN_WHERE_CLAUSE_CLASS );
return getCommonHandler().getInt( sql.toString(), new Object[]{handlerClass} );
}
public org.jdom.Document getContentHandlers()
{
final List<ContentHandlerEntity> list = this.contentHandlerDao.findAll();
return toDocument( list );
}
private org.jdom.Document toDocument( final List<ContentHandlerEntity> list )
{
final org.jdom.Element root = new org.jdom.Element( "contenthandlers" );
for ( final ContentHandlerEntity entity : list )
{
final org.jdom.Element elem = new org.jdom.Element( "contenthandler" );
root.addContent( elem );
elem.setAttribute( "key", entity.getKey().toString() );
elem.addContent( new org.jdom.Element( "name" ).setText( entity.getName() ) );
elem.addContent( new org.jdom.Element( "class" ).setText( entity.getClassName() ) );
final String description = entity.getDescription();
if ( description != null )
{
elem.addContent( new org.jdom.Element( "description" ).setText( description ) );
}
final org.jdom.Document xmlConfig = entity.getXmlConfig();
if ( xmlConfig != null )
{
elem.addContent( xmlConfig.getRootElement().detach() );
}
else
{
elem.addContent( new org.jdom.Element( "xmlconfig" ) );
}
final String timestamp = CalendarUtil.formatTimestamp( entity.getTimestamp(), true );
elem.addContent( new org.jdom.Element( "timestamp" ).setText( timestamp ) );
}
return new org.jdom.Document( root );
}
public int createContentHandler( Document doc )
{
PreparedStatement preparedStmt = null;
int key = -1;
try
{
Connection con = getConnection();
preparedStmt = con.prepareStatement( HAN_INSERT );
Element root = doc.getDocumentElement();
String keyStr = root.getAttribute( "key" );
if ( keyStr.length() > 0 )
{
key = Integer.parseInt( keyStr );
}
else
{
key = getNextKey( HAN_TABLE );
}
Map<String, Element> subelems = XMLTool.filterElements( root.getChildNodes() );
Element subelem = subelems.get( "name" );
String name = XMLTool.getElementText( subelem );
subelem = subelems.get( "class" );
String className = XMLTool.getElementText( subelem );
subelem = subelems.get( "description" );
String description;
if ( subelem != null )
{
description = XMLTool.getElementText( subelem );
}
else
{
description = null;
}
subelem = subelems.get( "xmlconfig" );
Document configDoc = XMLTool.createDocument();
configDoc.appendChild( configDoc.importNode( subelem, true ) );
byte[] cdocBytes = XMLTool.documentToBytes( configDoc, "UTF-8" );
preparedStmt.setInt( 1, key );
preparedStmt.setString( 2, name );
preparedStmt.setString( 3, className );
if ( description != null )
{
preparedStmt.setString( 4, description );
}
else
{
preparedStmt.setNull( 4, Types.VARCHAR );
}
preparedStmt.setBytes( 5, cdocBytes );
// add the content handler
int result = preparedStmt.executeUpdate();
if ( result == 0 )
{
String message = "Failed to create content handler. No content handler created.";
VerticalEngineLogger.errorCreate( message, null );
}
}
catch ( SQLException sqle )
{
String message = "Failed to create content handler: %t";
VerticalEngineLogger.errorCreate( message, sqle );
}
finally
{
close( preparedStmt );
}
return key;
}
public void updateContentHandler( Document doc )
{
PreparedStatement preparedStmt = null;
try
{
Element root = doc.getDocumentElement();
Map<String, Element> subelems = XMLTool.filterElements( root.getChildNodes() );
int key = Integer.parseInt( root.getAttribute( "key" ) );
Element subelem = subelems.get( "name" );
String name = XMLTool.getElementText( subelem );
subelem = subelems.get( "class" );
String className = XMLTool.getElementText( subelem );
subelem = subelems.get( "description" );
String description;
if ( subelem != null )
{
description = XMLTool.getElementText( subelem );
}
else
{
description = null;
}
Element configElem = subelems.get( "xmlconfig" );
Document configDoc = XMLTool.createDocument();
configDoc.appendChild( configDoc.importNode( configElem, true ) );
byte[] cdocBytes = XMLTool.documentToBytes( configDoc, "UTF-8" );
Connection con = getConnection();
preparedStmt = con.prepareStatement( HAN_UPDATE );
preparedStmt.setInt( 5, key );
preparedStmt.setString( 1, name );
if ( description != null )
{
preparedStmt.setString( 2, description );
}
else
{
preparedStmt.setNull( 2, Types.VARCHAR );
}
preparedStmt.setString( 3, className );
preparedStmt.setBytes( 4, cdocBytes );
preparedStmt.executeUpdate();
preparedStmt.close();
preparedStmt = null;
}
catch ( SQLException sqle )
{
String message = "Failed to update content type: %t";
VerticalEngineLogger.errorUpdate( message, sqle );
}
catch ( NumberFormatException nfe )
{
String message = "Failed to parse content type key: %t";
VerticalEngineLogger.errorUpdate( message, nfe );
}
finally
{
close( preparedStmt );
}
}
public void removeContentHandler( int contentHandlerKey )
throws VerticalRemoveException
{
PreparedStatement preparedStmt = null;
getCommonHandler().cascadeDelete( db.tContentHandler, contentHandlerKey );
try
{
Connection con = getConnection();
preparedStmt = con.prepareStatement( HAN_DELETE );
preparedStmt.setInt( 1, contentHandlerKey );
preparedStmt.executeUpdate();
}
catch ( SQLException sqle )
{
String message = "Failed to remove content handler: %t";
VerticalEngineLogger.errorRemove( message, sqle );
}
finally
{
close( preparedStmt );
}
}
public Document getContentTypeModuleData( int contentTypeKey )
{
Document doc;
Document modDoc = getCommonHandler().getDocument( db.tContentType, contentTypeKey );
Element mdElem = modDoc.getDocumentElement();
// workaround for old contenttypes
if ( mdElem.getTagName().equals( "module" ) )
{
doc = XMLTool.createDocument( "moduledata" );
doc.getDocumentElement().appendChild( doc.importNode( mdElem, true ) );
}
else
{
doc = XMLTool.createDocument();
doc.appendChild( doc.importNode( mdElem, true ) );
}
return doc;
}
public XMLDocument getContentTitles( int[] contentKeys, int[] totalContentKeys, boolean includeSectionInfo, MenuItemEntity section )
{
org.jdom.Element contentsEl = new org.jdom.Element( "contenttitles" );
if ( contentKeys == null || contentKeys.length == 0 )
{
return XMLDocumentFactory.create( new org.jdom.Document( contentsEl ) );
}
Date now = new Date();
ContentTitleXmlCreator contentTitleXmlCreator = new ContentTitleXmlCreator( now );
contentTitleXmlCreator.setIncludeIsInHomeSectionInfo( includeSectionInfo, section );
for ( int contentKeyInt : contentKeys )
{
ContentKey contentKey = new ContentKey( contentKeyInt );
ContentEntity content = contentDao.findByKey( contentKey );
org.jdom.Element contentEl = contentTitleXmlCreator.createContentTitleElement( content );
contentsEl.addContent( contentEl );
}
if ( totalContentKeys != null )
{
for ( int totalContentKeyInt : totalContentKeys )
{
ContentKey totalContentKey = new ContentKey( totalContentKeyInt );
ContentEntity totalContent = contentDao.findByKey( totalContentKey );
org.jdom.Element totalContentEl = contentTitleXmlCreator.createTotalContentTitleElement( totalContent );
contentsEl.addContent( totalContentEl );
}
}
return XMLDocumentFactory.create( new org.jdom.Document( contentsEl ) );
}
public Document getContentTitleDoc( int versionKey )
{
Document doc = XMLTool.createDocument( "contenttitles" );
ContentVersionView versionView = ContentVersionView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( versionView, versionView.cov_lKey );
PreparedStatement preparedStmt = null;
ResultSet resultSet = null;
Element root = doc.getDocumentElement();
try
{
Connection con = getConnection();
preparedStmt = con.prepareStatement( sql.toString() );
preparedStmt.setInt( 1, versionKey );
resultSet = preparedStmt.executeQuery();
while ( resultSet.next() )
{
Element elem = XMLTool.createElement( doc, root, "contenttitle" );
int contentKey = resultSet.getInt( "con_lKey" );
elem.setAttribute( "key", String.valueOf( contentKey ) );
int categoryKey = resultSet.getInt( "cat_lKey" );
elem.setAttribute( "categorykey", String.valueOf( categoryKey ) );
Timestamp timestamp = resultSet.getTimestamp( "cov_dteTimestamp" );
elem.setAttribute( "timestamp", CalendarUtil.formatTimestamp( timestamp ) );
//elem.setAttribute("unitkey", String.valueOf(resultSet.getInt("cat_uni_lKey")));
elem.setAttribute( "contenttypekey", String.valueOf( resultSet.getInt( "cat_cty_lKey" ) ) );
Timestamp publishfrom = resultSet.getTimestamp( "con_dtePublishFrom" );
if ( !resultSet.wasNull() )
{
elem.setAttribute( "publishfrom", CalendarUtil.formatTimestamp( publishfrom ) );
}
Timestamp publishto = resultSet.getTimestamp( "con_dtePublishTo" );
if ( !resultSet.wasNull() )
{
elem.setAttribute( "publishto", CalendarUtil.formatTimestamp( publishto ) );
}
// content status
// 0: draft
// 1: not published
// 2: publish waiting
// 3: published
// 4: archived
elem.setAttribute( "status", resultSet.getString( "cov_lStatus" ) );
elem.setAttribute( "state", resultSet.getString( "cov_lState" ) );
XMLTool.createTextNode( doc, elem, resultSet.getString( "cov_sTitle" ) );
}
}
catch ( SQLException sqle )
{
String message = "Failed to get content titles; %t";
VerticalEngineLogger.error( message, sqle );
doc = XMLTool.createDocument( "contenttitles" );
}
finally
{
close( resultSet );
close( preparedStmt );
}
return doc;
}
public int getCurrentVersionKey( int contentKey )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContent, db.tContent.con_cov_lKey, false, db.tContent.con_lKey );
return getCommonHandler().getInt( sql.toString(), contentKey );
}
public int getContentKeyByVersionKey( int versionKey )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContentVersion, db.tContentVersion.cov_con_lKey, false, db.tContentVersion.cov_lKey );
return getCommonHandler().getInt( sql.toString(), versionKey );
}
private Document getContentVersions( int contentKey )
{
ContentVersionView versionView = ContentVersionView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( versionView,
new Column[]{versionView.cov_lKey, versionView.cov_sTitle, versionView.cov_dteCreated,
versionView.cov_dteTimestamp, versionView.cov_lState, versionView.cov_bCurrent,
versionView.usr_sOwnerName}, false, new Column[]{versionView.con_lKey} );
XDG.appendOrderBySQL( sql, versionView.cov_dteCreated, true );
Object[][] data = getCommonHandler().getObjectArray( sql.toString(), new Object[]{contentKey} );
Document doc = XMLTool.createDocument( "versions" );
for ( int contentCounter = 0; contentCounter < data.length; contentCounter++ )
{
Element versionElem = XMLTool.createElement( doc, doc.getDocumentElement(), "version" );
int versionKey = ( (Number) data[contentCounter][0] ).intValue();
String title = (String) data[contentCounter][1];
Timestamp created = (Timestamp) data[contentCounter][2];
Timestamp timestamp = (Timestamp) data[contentCounter][3];
int state = ( (Number) data[contentCounter][4] ).intValue();
boolean current = ( (Number) data[contentCounter][5] ).intValue() == 1;
String owner = (String) data[contentCounter][6];
versionElem.setAttribute( "key", String.valueOf( versionKey ) );
versionElem.setAttribute( "title", StringUtil.getXMLSafeString( title ) );
versionElem.setAttribute( "created", created.toString() );
versionElem.setAttribute( "timestamp", timestamp.toString() );
versionElem.setAttribute( "state", String.valueOf( state ) );
versionElem.setAttribute( "current", String.valueOf( current ) );
versionElem.setAttribute( "owner", String.valueOf( owner ) );
}
return doc;
}
private void getContentBinaries( TIntObjectHashMap versionKeyContentMap )
{
if ( versionKeyContentMap.size() == 0 )
{
return;
}
Table cbd = db.tContentBinaryData;
Table bd = db.tBinaryData;
Column[] selectColumns =
{db.tBinaryData.bda_lKey, db.tBinaryData.bda_sFileName, db.tBinaryData.bda_lFileSize, db.tContentBinaryData.cbd_sLabel,
db.tContentBinaryData.cbd_cov_lKey};
StringBuffer sql = XDG.generateFKJoinSQL( cbd, bd, selectColumns );
XDG.appendWhereInSQL( sql, db.tContentBinaryData.cbd_cov_lKey, versionKeyContentMap.keys().length );
Object[][] data = getCommonHandler().getObjectArray( sql.toString(), versionKeyContentMap.keys() );
for ( int binaryCounter = 0; binaryCounter < data.length; binaryCounter++ )
{
int binaryKey = ( (Number) data[binaryCounter][0] ).intValue();
String fileName = StringUtil.stripControlChars( (String) data[binaryCounter][1] );
int fileSize = ( (Number) data[binaryCounter][2] ).intValue();
String label = (String) data[binaryCounter][3];
int versionKey = ( (Number) data[binaryCounter][4] ).intValue();
Element contentElem = (Element) versionKeyContentMap.get( versionKey );
Document doc = contentElem.getOwnerDocument();
Element binariesElem = XMLTool.createElementIfNotPresent( doc, contentElem, "binaries" );
Element binaryElem = XMLTool.createElement( doc, binariesElem, "binary" );
binaryElem.setAttribute( "key", String.valueOf( binaryKey ) );
binaryElem.setAttribute( "filename", fileName );
binaryElem.setAttribute( "filesize", String.valueOf( fileSize ) );
if ( label != null )
{
binaryElem.setAttribute( "label", label );
}
}
}
public Document getContentVersion( final User user, int versionKey )
{
ContentVersionView versionView = ContentVersionView.getInstance();
StringBuffer sql = XDG.generateSelectSQL( versionView, null, false, versionView.cov_lKey );
int contentKey = getContentKeyByVersionKey( versionKey );
getSecurityHandler().appendContentSQL( user, sql );
ElementProcessor sectionNamesProcessor = new ElementProcessor()
{
private final SectionHandler sectionHandler = getSectionHandler();
public void process( Element elem )
{
int contentKey = Integer.parseInt( elem.getAttribute( "key" ) );
sectionHandler.appendSectionNames( contentKey, elem );
}
};
VersionKeyContentMapProcessor versionKeyContentMapProcessor = new VersionKeyContentMapProcessor( this );
Document doc = getCommonHandler().getData( versionView, sql.toString(), new int[]{versionKey},
new ElementProcessor[]{versionKeyContentMapProcessor, sectionNamesProcessor} );
// add binaries elements
getContentBinaries( versionKeyContentMapProcessor.getVersionKeyContentMap() );
Element contentsElem = doc.getDocumentElement();
Element contentElem = XMLTool.getElement( contentsElem, "content" );
if ( contentElem == null )
{
return doc;
}
// accessrights
Document accessRightsDoc = getSecurityHandler().getAccessRights( user, AccessRight.CONTENT, contentKey, true );
XMLTool.mergeDocuments( contentElem, accessRightsDoc, true );
// versions
Document versionsDoc = getContentVersions( contentKey );
XMLTool.mergeDocuments( contentElem, versionsDoc, true );
Element relatedContentKeysElem = XMLTool.createElement( doc, contentElem, "relatedcontentkeys" );
Element relatedContentsElem = XMLTool.createElement( doc, contentsElem, "relatedcontents" );
// children
TIntArrayList childrenKeys = new TIntArrayList();
TIntObjectHashMap versionKeyRCKElemMap = new TIntObjectHashMap();
versionKeyRCKElemMap.put( versionKey, relatedContentKeysElem );
getChildrenContentKeys( childrenKeys, versionKeyRCKElemMap, false );
ContentView contentView = ContentView.getInstance();
if ( childrenKeys.size() > 0 )
{
int[] children = childrenKeys.toArray();
sql = XDG.generateSelectWhereInSQL( contentView, null, false, contentView.con_lKey, children.length );
Document childrenDoc = getCommonHandler().getData( contentView, sql.toString(), children, null );
XMLTool.mergeDocuments( relatedContentsElem, childrenDoc, false );
}
ElementProcessor[] elementProcessors = {new ContentTypeProcessor( this )};
// parents
TIntArrayList parentKeys = new TIntArrayList();
TIntObjectHashMap contentKeyRCKElemMap = new TIntObjectHashMap();
contentKeyRCKElemMap.put( contentKey, relatedContentKeysElem );
getParentContentKeys( parentKeys, contentKeyRCKElemMap, false, false );
if ( parentKeys.size() > 0 )
{
int[] parents = parentKeys.toArray();
sql = XDG.generateSelectWhereInSQL( versionView, null, false, versionView.cov_lKey, parents.length );
Document childrenDoc = getCommonHandler().getData( versionView, sql.toString(), parents, elementProcessors );
if ( childrenDoc != null )
{ // NSSR somehow got a nullpointerexception on the next line, when undeleting a content (manually in the db)
XMLTool.mergeDocuments( relatedContentsElem, childrenDoc, false );
}
}
return doc;
}
public Document getContentXMLField( int versionKey )
{
return getCommonHandler().getDocument( db.tContentVersion, versionKey );
}
public int[] getContentTypesByHandlerClass( String className )
{
// Funker denne?
StringBuffer sql = XDG.generateSelectSQL( db.tContentType, db.tContentType.cty_lKey, true, null );
XDG.appendJoinSQL( sql, db.tContentType.cty_han_lKey );
XDG.appendWhereSQL( sql, db.tContentHandler.han_sClass, className );
return getCommonHandler().getIntArray( sql.toString(), (int[]) null );
}
public boolean isContentVersionApproved( int versionKey )
{
ContentVersionView versionView = ContentVersionView.getInstance();
Column[] whereColumns = {versionView.cov_lKey, versionView.cov_lStatus};
StringBuffer sql = XDG.generateSelectSQL( versionView, versionView.cov_lKey, whereColumns );
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getInt( sql.toString(), new int[]{versionKey, 2} ) >= 0;
}
public Document getContentHomes( int contentKey )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContentHome );
XDG.generateWhereSQL( sql, db.tContentHome.cho_con_lKey );
ElementProcessor pageTemplateProcessor = new ElementProcessor()
{
private final CommonHandler commonHandler = getCommonHandler();
private final String sql =
XDG.generateSelectSQL( db.tPageTemplate, db.tPageTemplate.pat_sName, false, db.tPageTemplate.pat_lKey ).toString();
public void process( Element elem )
{
if ( elem.hasAttribute( "pagetemplatekey" ) )
{
int pageTemplateKey = Integer.valueOf( elem.getAttribute( "pagetemplatekey" ) );
String pageTemplateName = commonHandler.getString( sql, pageTemplateKey );
elem.setAttribute( "pagetemplatename", pageTemplateName );
}
}
};
CommonHandler commonHandler = getCommonHandler();
return commonHandler.getData( db.tContentHome, sql.toString(), contentKey, new ElementProcessor[]{pageTemplateProcessor} );
}
public int getContentStatus( int versionKey )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContentVersion, db.tContentVersion.cov_lStatus, false, db.tContentVersion.cov_lKey );
return getCommonHandler().getInt( sql.toString(), versionKey );
}
public int getContentTypeKeyByName( String name )
{
StringBuffer sql = XDG.generateSelectSQL( db.tContentType, db.tContentType.cty_lKey, false, null );
XDG.appendWhereSQL( sql, db.tContentType.cty_sName, name );
return getCommonHandler().getInt( sql.toString(), (Object[]) null );
}
}