/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.vertical.adminweb.handlers.xmlbuilders; import java.util.Date; import java.util.StringTokenizer; import org.apache.commons.lang.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.enonic.esl.containers.ExtendedMap; import com.enonic.esl.util.DateUtil; import com.enonic.esl.xml.XMLTool; import com.enonic.vertical.adminweb.AdminHandlerBaseServlet; import com.enonic.vertical.adminweb.VerticalAdminException; import com.enonic.vertical.adminweb.VerticalAdminLogger; import com.enonic.vertical.adminweb.handlers.ContentBaseHandlerServlet; import com.enonic.vertical.engine.AccessRight; import com.enonic.cms.core.content.binary.BinaryData; import com.enonic.cms.core.portal.PrettyPathNameCreator; import com.enonic.cms.core.security.user.User; public abstract class ContentBaseXMLBuilder extends AbstractBaseXMLBuilder implements ContentXMLBuilder { private static final String DUEDATE_DATE_FORMITEM_KEY = "date_assignment_duedate"; private static final String DUEDATE_TIME_FORMITEM_KEY = "time_assignment_duedate"; private static final String COMMENT_FORMITEM_KEY = "_comment"; private static final String ASSIGNMENT_DESCRIPTION_FORMITEM_KEY = "_assignment_description"; private static final String ASSIGNEE_FORMITEM_KEY = "_assignee"; private static final String ASSIGNER_FORMITEM_KEY = "_assigner"; public static final String ASSIGNEE_XML_KEY = "assignee"; public static final String ASSIGNER_XML_KEY = "assigner"; public static final String ASSIGNMENT_DESCRIPTION_XML_KEY = "assignment-description"; public static final String COMMENT_XML_KEY = "comment"; public static final String ASSIGNMENT_DUEDATE_XML_KEY = "assignment-duedate"; private static final String DEFAULT_ASSIGNMENT_DUEDATE_HHMM = "23:59"; public String getContentTitle( ExtendedMap formItems ) { return formItems.getString( getTitleFormKey() ); } public String getTitleFormKey() { return "title"; } public String getContentTitle( Element contentDataElem, int contentTypeKey ) { return XMLTool.getElementText( XMLTool.getElement( contentDataElem, "title" ) ); } /** * <p> A generic method that builds the contentdata block of arbitrary depth. All fields starting with the pattern 'contentdata_foo' and * followed by arbitrary patterns like '_bar' are translated to nested xml elements, where 'foo' and 'bar' is the name of the elements. * The last element can be specified with one of the following prefix and suffixes: <ul> <li>@ (prefix) - element text will be set * as an attribute to the parent element <li>_CDATA (suffix) - element text will be wrapped in a CDATA element <li>_XHTML (suffix) - * element text will be turned into XHTML elements </ul> When reaching one of the prefix and suffixes, the element creating process will * terminate for this field. </p> <p/> <p>Elements already created with the same path will be reused.</p> <p/> <p>Example:<br> The key * 'contentdata_foo_bar_zot_CDATA' with the value '<b>alpha</b>' will transform into the following xml: * <pre> * <contentdata> * <foo> * <bar> * <zot> * <[!CDATA[<b>alpha</b>]]> * </zot> * </bar> * </foo> * </contentdata> * </pre> * </p> */ public void buildContentTypeXML( User user, Document doc, Element contentdata, ExtendedMap formItems ) throws VerticalAdminException { for ( Object o : formItems.keySet() ) { String key = (String) o; StringTokenizer keyTokenizer = new StringTokenizer( key, "_" ); if ( "contentdata".equals( keyTokenizer.nextToken() ) ) { Element root = contentdata; while ( keyTokenizer.hasMoreTokens() ) { String keyToken = keyTokenizer.nextToken(); if ( "CDATA".equals( keyToken ) ) { XMLTool.createCDATASection( doc, root, formItems.getString( key ) ); break; } else if ( "XML".equals( keyToken ) ) { String xmlDoc = formItems.getString( key ); Document tempDoc = XMLTool.domparse( xmlDoc ); root.appendChild( doc.importNode( tempDoc.getDocumentElement(), true ) ); break; } else if ( "XHTML".equals( keyToken ) ) { XMLTool.createXHTMLNodes( doc, root, formItems.getString( key ), true ); break; } else if ( keyToken.charAt( 0 ) == '@' ) { root.setAttribute( keyToken.substring( 1 ), formItems.getString( key ) ); break; } else { Element elem = XMLTool.getElement( root, keyToken ); if ( elem == null ) { root = XMLTool.createElement( doc, root, keyToken ); } else { root = elem; } if ( !keyTokenizer.hasMoreTokens() ) { XMLTool.createTextNode( doc, root, formItems.getString( key ) ); break; } } } } } } public final String buildXML( ExtendedMap formItems, User user, boolean create, boolean excludeContendataXML, boolean usePersistedContendataXML ) throws VerticalAdminException { boolean published = formItems.getBoolean( "published", false ); boolean sentToApproval = formItems.getBoolean( "senttoapproval", false ); boolean rejected = formItems.getBoolean( "rejected", false ); int categoryKey; if ( formItems.containsKey( "cat" ) ) { categoryKey = formItems.getInt( "cat" ); } else { categoryKey = formItems.getInt( "category_key" ); } int unitKey = -1; if ( formItems.containsKey( "selectedunitkey" ) ) { unitKey = formItems.getInt( "selectedunitkey" ); } else if ( formItems.containsKey( "unitkey" ) ) { unitKey = formItems.getInt( "unitkey" ); } int contenttypekey = ContentBaseHandlerServlet.getContentTypeKey( formItems ); Document doc = XMLTool.createDocument( "content" ); Element content = doc.getDocumentElement(); // General content attributes if ( !create ) { int key = formItems.getInt( "key" ); // @key content.setAttribute( "key", String.valueOf( key ) ); // version/@key int versionKey = formItems.getInt( "versionkey" ); content.setAttribute( "versionkey", String.valueOf( versionKey ) ); } // owner/@key if ( !create && formItems.containsKey( "_pubdata_owner" ) ) { Element ownerElem = XMLTool.createElement( doc, content, "owner" ); ownerElem.setAttribute( "key", formItems.getString( "_pubdata_owner" ) ); } // assignee/@key if ( formItems.containsKey( ASSIGNEE_FORMITEM_KEY ) ) { Element assigneeElem = XMLTool.createElement( doc, content, ASSIGNEE_XML_KEY ); assigneeElem.setAttribute( "key", formItems.getString( ASSIGNEE_FORMITEM_KEY ) ); } if ( formItems.containsKey( ASSIGNER_FORMITEM_KEY ) ) { Element assignerElem = XMLTool.createElement( doc, content, ASSIGNER_XML_KEY ); assignerElem.setAttribute( "key", formItems.getString( ASSIGNER_FORMITEM_KEY ) ); } // DueDate buildDueDateElement( formItems, doc, content ); // Comment if ( formItems.containsKey( COMMENT_FORMITEM_KEY ) ) { XMLTool.createElement( doc, content, COMMENT_XML_KEY, formItems.getString( COMMENT_FORMITEM_KEY ) ); } // Assignment comment if ( formItems.containsKey( ASSIGNMENT_DESCRIPTION_FORMITEM_KEY ) ) { XMLTool.createElement( doc, content, ASSIGNMENT_DESCRIPTION_XML_KEY, formItems.getString( ASSIGNMENT_DESCRIPTION_FORMITEM_KEY ) ); } // modifier/@key Element modifierElem = XMLTool.createElement( doc, content, "modifier" ); modifierElem.setAttribute( "key", String.valueOf( user.getKey() ) ); if ( unitKey >= 0 ) { content.setAttribute( "unitkey", String.valueOf( unitKey ) ); } content.setAttribute( "contenttypekey", String.valueOf( contenttypekey ) ); content.setAttribute( "priority", formItems.getString( "_pubdata_priority", "0" ) ); // language int languageKey; if ( formItems.containsKey( "_pubdata_languagekey" ) ) { languageKey = formItems.getInt( "_pubdata_languagekey" ); } else { languageKey = admin.getUnitLanguageKey( unitKey ); } content.setAttribute( "languagekey", String.valueOf( languageKey ) ); // status int status = formItems.getInt( "_pubdata_status", 0 ); if ( rejected ) { status = 0; } else if ( sentToApproval ) { status = 1; } else if ( published ) { status = 2; } content.setAttribute( "status", String.valueOf( status ) ); try { // record the publish dates if set Date publishFrom = null; Date publishTo = null; Date now = new Date(); if ( formItems.containsKey( "date_pubdata_publishfrom" ) ) { StringBuffer date = new StringBuffer( formItems.getString( "date_pubdata_publishfrom" ) ); date.append( ' ' ); date.append( formItems.getString( "time_pubdata_publishfrom", "00:00" ) ); publishFrom = DateUtil.parseDateTime( date.toString() ); } if ( formItems.containsKey( "date_pubdata_publishto" ) ) { StringBuffer date = new StringBuffer( formItems.getString( "date_pubdata_publishto" ) ); date.append( ' ' ); date.append( formItems.getString( "time_pubdata_publishto", "00:00" ) ); publishTo = DateUtil.parseDateTime( date.toString() ); } if ( published && publishFrom == null ) { publishFrom = now; } if ( published && publishTo != null && publishTo.before( now ) ) { publishTo = null; } if ( publishFrom != null ) { content.setAttribute( "publishfrom", DateUtil.formatISODateTime( publishFrom ) ); } if ( publishTo != null ) { content.setAttribute( "publishto", DateUtil.formatISODateTime( publishTo ) ); } } catch ( Exception e ) { VerticalAdminLogger.errorAdmin( "Error parsing dates: %t", e ); } // created: if ( !create ) { content.setAttribute( "created", formItems.getString( "_pubdata_created" ) ); } String contentTitle; if ( usePersistedContendataXML || excludeContendataXML ) { int versionKey = formItems.getInt( "versionkey" ); contentTitle = admin.getContentTitle( versionKey ); if ( contentTitle == null || contentTitle.length() == 0 ) { Document contentDoc = admin.getContentVersion( user, versionKey ).getAsDOMDocument(); Element contentElem = (Element) contentDoc.getDocumentElement().getFirstChild(); Element contentDataElem = XMLTool.getElement( contentElem, "contentdata" ); contentTitle = getContentTitle( contentDataElem, contenttypekey ); } } else { contentTitle = getContentTitle( formItems ); } // Content title XMLTool.createElement( doc, content, "title", contentTitle ); String contentName = formItems.getString( "_name", null ); if ( StringUtils.isBlank( contentName ) ) { contentName = new PrettyPathNameCreator( transliterate ).generatePrettyPathName( contentTitle ); } XMLTool.createElement( doc, content, "name", contentName ); // create the units root Element contentdata = XMLTool.createElement( doc, content, "contentdata" ); // category Element categoryname; // Not sure if category_name is present in all situations if ( formItems.containsKey( "category_name" ) ) { categoryname = XMLTool.createElement( doc, content, "categoryname", formItems.getString( "category_name" ) ); } else { categoryname = XMLTool.createElement( doc, content, "categoryname" ); } categoryname.setAttribute( "key", String.valueOf( categoryKey ) ); if ( !excludeContendataXML ) { if ( usePersistedContendataXML ) { Document contentXML = admin.getContentXMLField( user, formItems.getInt( "versionkey" ) ).getAsDOMDocument(); XMLTool.replaceElement( contentdata, contentXML.getDocumentElement() ); } else { // Create the content type specific XML buildContentTypeXML( user, doc, contentdata, formItems ); } } // add access rights to content xml AdminHandlerBaseServlet.buildAccessRightsXML( content, null, formItems, AccessRight.CONTENT ); return XMLTool.documentToString( doc ); } private void buildDueDateElement( ExtendedMap formItems, Document doc, Element content ) { if ( formItems.containsKey( DUEDATE_DATE_FORMITEM_KEY ) ) { StringBuffer date = new StringBuffer( formItems.getString( DUEDATE_DATE_FORMITEM_KEY ) ); date.append( ' ' ); date.append( formItems.getString( DUEDATE_TIME_FORMITEM_KEY, DEFAULT_ASSIGNMENT_DUEDATE_HHMM ) ); Date dueDate = null; try { dueDate = DateUtil.parseDateTime( date.toString() ); XMLTool.createElement( doc, content, ASSIGNMENT_DUEDATE_XML_KEY, DateUtil.formatISODateTime( dueDate ) ); } catch ( Exception e ) { VerticalAdminLogger.errorAdmin( "Error parsing dates: %t", e ); } } } public int[] getRelatedContentKeys( ExtendedMap formItems ) { return null; } public BinaryData[] getBinaries( ExtendedMap formItems ) throws VerticalAdminException { return null; } public int[] getDeleteBinaries( ExtendedMap formItems ) throws VerticalAdminException { return null; } }