/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.vertical.adminweb; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.w3c.dom.Document; import com.enonic.esl.containers.ExtendedMap; import com.enonic.esl.xml.XMLTool; import com.enonic.vertical.engine.VerticalEngineException; import com.enonic.cms.framework.xml.XMLDocument; import com.enonic.cms.framework.xml.XMLDocumentFactory; import com.enonic.cms.core.content.ContentEntity; import com.enonic.cms.core.content.ContentKey; import com.enonic.cms.core.content.ContentSpecification; import com.enonic.cms.core.content.ContentXMLCreator; import com.enonic.cms.core.content.access.ContentAccessResolver; import com.enonic.cms.core.content.category.CategoryAccessResolver; import com.enonic.cms.core.content.category.CategoryAccessType; import com.enonic.cms.core.content.category.CategoryEntity; import com.enonic.cms.core.content.category.CategoryKey; import com.enonic.cms.core.content.category.CategoryXmlCreator; import com.enonic.cms.core.content.contenttype.ContentTypeEntity; import com.enonic.cms.core.content.contenttype.ContentTypeKey; import com.enonic.cms.core.content.contenttype.ContentTypeXmlCreator; import com.enonic.cms.core.content.index.ContentIndexQuery.CategoryAccessTypeFilterPolicy; import com.enonic.cms.core.content.index.ContentIndexQuery.SectionFilterStatus; import com.enonic.cms.core.content.query.ContentByContentQuery; import com.enonic.cms.core.content.query.ContentBySectionQuery; import com.enonic.cms.core.content.resultset.ContentResultSet; import com.enonic.cms.core.content.resultset.RelatedContentResultSetImpl; import com.enonic.cms.core.log.ContentLogEntrySpecification; import com.enonic.cms.core.log.ContentLogXMLCreator; import com.enonic.cms.core.log.LogEntryEntity; import com.enonic.cms.core.log.LogEntryResultSet; import com.enonic.cms.core.log.LogType; import com.enonic.cms.core.log.Table; import com.enonic.cms.core.security.user.User; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.service.AdminService; import com.enonic.cms.core.structure.SectionXmlCreator; public class MyPageServlet extends AdminHandlerBaseServlet { public static final CategoryAccessType[] CREATE_BROWSE = new CategoryAccessType[]{CategoryAccessType.ADMIN_BROWSE, CategoryAccessType.CREATE}; private static final int ASSIGNED_TO_COUNT = 6; public void handlerPage( HttpServletRequest request, HttpServletResponse response, HttpSession session, ExtendedMap formItems, ExtendedMap parameters, User oldUser, Document verticalDoc ) throws VerticalAdminException, VerticalEngineException { Map<Integer, String> contentTypeKeyHandlerMapping = new HashMap<Integer, String>(); UserEntity user = securityService.getUser( oldUser ); String maximize = formItems.getString( "maximize", null ); // ---- // get last modified // ---- if ( maximize == null || "lastmodified".equals( maximize ) ) { handleRecentItems( verticalDoc, contentTypeKeyHandlerMapping, formItems, user ); } // ---- // Get content assigned to current user // ---- if ( maximize == null || "assignedto".equals( maximize ) ) { handleAssignedToMe( verticalDoc, contentTypeKeyHandlerMapping, formItems, user ); } // ---- // Get content waiting for activation // --- if ( maximize == null || "activation".equals( maximize ) ) { handleActivation( verticalDoc, contentTypeKeyHandlerMapping, formItems, user ); } // Default browse config Document defaultBrowseConfig = AdminStore.getXml( session, "defaultbrowseconfig.xml" ).getAsDOMDocument(); XMLTool.mergeDocuments( verticalDoc, defaultBrowseConfig, true ); Document contentTypeKeyHandlerMappingDoc = createContentTypeKeyHandlerMappingXml( contentTypeKeyHandlerMapping ); XMLTool.mergeDocuments( verticalDoc, contentTypeKeyHandlerMappingDoc, true ); // Feedback addFeedback( verticalDoc, formItems ); addParameters( formItems, parameters, maximize ); transformXML( request, response, verticalDoc, "dashboard.xsl", parameters ); } private void addParameters( ExtendedMap formItems, ExtendedMap parameters, String maximize ) { int index = formItems.getInt( "index", 0 ); int count = formItems.getInt( "count", maximize != null ? 20 : ASSIGNED_TO_COUNT ); parameters.put( "index", index ); parameters.put( "count", count ); parameters.put( "maximize", maximize ); } private void handleAssignedToMe( Document verticalDoc, Map<Integer, String> contentTypeKeyHandlerMapping, final ExtendedMap formItems, UserEntity user ) { String maximize = formItems.getString( "maximize", null ); int index = formItems.getInt( "index", 0 ); int count = formItems.getInt( "count", maximize != null ? 20 : ASSIGNED_TO_COUNT ); ContentSpecification contentSpecification = new ContentSpecification(); //contentSpecification.setUser( user ); contentSpecification.setAssignee( user ); contentSpecification.setAssignedDraftsOnly( false ); ContentResultSet contentResultSet = contentService.getContent( contentSpecification, "c.assignmentDueDate ASC, c.timestamp DESC", count, index ); for ( ContentEntity content : contentResultSet.getContents() ) { contentTypeKeyHandlerMapping.put( content.getContentType().getKey(), content.getContentType().getContentHandlerName().getHandlerClassShortName() ); } ContentXMLCreator contentXMLCreator = new ContentXMLCreator(); contentXMLCreator.setResultIndexing( index, count ); contentXMLCreator.setIncludeOwnerAndModifierData( true ); contentXMLCreator.setIncludeContentData( true ); contentXMLCreator.setIncludeCategoryData( true ); contentXMLCreator.setIncludeAccessRightsInfo( false ); contentXMLCreator.setIncludeRelatedContentsInfo( false ); contentXMLCreator.setIncludeRepositoryPathInfo( true ); contentXMLCreator.setIncludeVersionsInfoForAdmin( true ); contentXMLCreator.setIncludeAssignment( true ); contentXMLCreator.setIncludeDraftInfo( true ); contentXMLCreator.setIncludeSectionActivationInfo( true ); XMLDocument xmlDocument = contentXMLCreator.createContentVersionsDocument( user, contentResultSet, new RelatedContentResultSetImpl() ); Document doc = xmlDocument.getAsDOMDocument(); doc.getDocumentElement().setAttribute( "type", "assignedto" ); XMLTool.mergeDocuments( verticalDoc, doc, true ); } private void handleActivation( Document verticalDoc, Map<Integer, String> contentTypeKeyHandlerMapping, final ExtendedMap formItems, UserEntity user ) { String maximize = formItems.getString( "maximize", null ); int index = formItems.getInt( "index", 0 ); int count = formItems.getInt( "count", maximize != null ? 20 : 3 ); ContentBySectionQuery contentBySectionQuery = new ContentBySectionQuery(); contentBySectionQuery.setSectionFilterStatus( SectionFilterStatus.UNAPPROVED_ONLY ); contentBySectionQuery.setSearchInAllSections(); contentBySectionQuery.setCount( count ); contentBySectionQuery.setUser( user ); contentBySectionQuery.setOrderBy( "timestamp DESC" ); contentBySectionQuery.setIndex( index ); contentBySectionQuery.setFilterIncludeOfflineContent(); contentBySectionQuery.setLevels( Integer.MAX_VALUE ); List<CategoryAccessType> categoryAccessTypeFilter = new ArrayList<CategoryAccessType>(); categoryAccessTypeFilter.add( CategoryAccessType.ADMINISTRATE ); categoryAccessTypeFilter.add( CategoryAccessType.APPROVE ); contentBySectionQuery.setCategoryAccessTypeFilter( categoryAccessTypeFilter, CategoryAccessTypeFilterPolicy.OR ); ContentResultSet contentResultSet = null; try { contentResultSet = contentService.queryContent( contentBySectionQuery ); } catch ( Exception e ) { throw new VerticalAdminException( "Failed to get unapproved content", e ); } //build contentTypeKey and handlerName mapping for ( ContentEntity entity : contentResultSet.getContents() ) { contentTypeKeyHandlerMapping.put( entity.getContentType().getKey(), entity.getContentType().getContentHandlerName().getHandlerClassShortName() ); } SectionXmlCreator sectionXmlCreator = new SectionXmlCreator( siteDao, new CategoryAccessResolver( groupDao ), new ContentAccessResolver( groupDao ) ); XMLDocument sectionDocument = sectionXmlCreator.createSectionsDocument( user, contentResultSet, count ); Document waitingForActivationDoc = sectionDocument.getAsDOMDocument(); // waitingForActivationDoc.getDocumentElement().setAttribute("type", "activation"); XMLTool.mergeDocuments( verticalDoc, waitingForActivationDoc, true ); } private void handleRecentItems( Document verticalDoc, Map<Integer, String> contentTypeKeyHandlerMapping, final ExtendedMap formItems, UserEntity user ) { String maximize = formItems.getString( "maximize", null ); int index = formItems.getInt( "index", 0 ); int count = formItems.getInt( "count", maximize != null ? 20 : 10 ); ContentLogEntrySpecification logSpecification = new ContentLogEntrySpecification(); logSpecification.setUser( user ); logSpecification.setTypes( new LogType[]{LogType.ENTITY_OPENED, LogType.ENTITY_CREATED, LogType.ENTITY_UPDATED} ); logSpecification.setTableTypes( new Table[]{Table.CONTENT} ); logSpecification.setAllowDuplicateEntries( false ); logSpecification.setAllowDeletedContent( false ); Calendar now = GregorianCalendar.getInstance(); final int monthsInPast = 3; now.add( Calendar.MONTH, -monthsInPast ); logSpecification.setDateFilter( now.getTime() ); LogEntryResultSet logResult = logService.getLogEntries( logSpecification, "timestamp DESC", count, index ); if ( logResult.getLength() > 0 ) { //build contentTypeKey and handler mapping List<ContentKey> contentKeys = new ArrayList<ContentKey>(); for ( LogEntryEntity entity : logResult.getLogEntries() ) { contentKeys.add( new ContentKey( entity.getKeyValue() ) ); } ContentByContentQuery contentByContentQuery = new ContentByContentQuery(); contentByContentQuery.setContentKeyFilter( contentKeys ); contentByContentQuery.setUser( user ); contentByContentQuery.setIndex( 0 ); contentByContentQuery.setCount( logResult.getLength() ); ContentResultSet contentResultSet = contentService.queryContent( contentByContentQuery ); for ( ContentEntity entity : contentResultSet.getContents() ) { contentTypeKeyHandlerMapping.put( entity.getContentType().getKey(), entity.getContentType().getContentHandlerName().getHandlerClassShortName() ); } } ContentLogXMLCreator logXMLCreator = new ContentLogXMLCreator(); logXMLCreator.setIncludeContentData( true ); logXMLCreator.setContentDao( contentDao ); XMLDocument xmlDocument = logXMLCreator.createLogsDocument( logResult ); Document lastModifiedDoc = xmlDocument.getAsDOMDocument(); lastModifiedDoc.getDocumentElement().setAttribute( "type", "lastmodified" ); XMLTool.mergeDocuments( verticalDoc, lastModifiedDoc, true ); } private Document createContentTypeKeyHandlerMappingXml( Map<Integer, String> contentTypeKeyHandlerMapping ) { org.jdom.Element rootElement = new org.jdom.Element( "contenthandlers" ); for ( Integer key : contentTypeKeyHandlerMapping.keySet() ) { org.jdom.Element contentHandlerEl = new org.jdom.Element( "contenthandler" ); contentHandlerEl.setAttribute( "contenttypekey", Integer.toString( key ) ); contentHandlerEl.setText( contentTypeKeyHandlerMapping.get( key ) ); rootElement.addContent( contentHandlerEl ); } org.jdom.Document doc = new org.jdom.Document( rootElement ); return XMLDocumentFactory.create( doc ).getAsDOMDocument(); } public void handlerCustom( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin, ExtendedMap formItems, String operation, ExtendedMap parameters, User user, Document verticalDoc ) throws VerticalAdminException, VerticalEngineException, MessagingException, IOException { if ( "page".equals( operation ) ) { handlerPage( request, response, session, formItems, parameters, user, verticalDoc ); } else if ( "createcontentwizard_step1".equals( operation ) ) { handlerCreateContentWizardStep1( request, response, formItems, parameters, user ); } else if ( "createcontentwizard_step2".equals( operation ) ) { handlerCreateContentWizardStep2( request, response, formItems, parameters, user ); } else { super.handlerCustom( request, response, session, admin, formItems, operation ); } } @SuppressWarnings("unchecked") private void handlerCreateContentWizardStep1( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems, ExtendedMap parameters, User user ) throws VerticalAdminException, VerticalEngineException { final UserEntity runningUser = securityService.getUser( user ); List<ContentTypeEntity> filteredContentTypes = new ArrayList<ContentTypeEntity>(); for ( ContentTypeEntity contentType : contentTypeDao.getAll() ) { if ( userHasAccessOnCategoriesOfContentType( runningUser, contentType, CREATE_BROWSE ) ) { filteredContentTypes.add( contentType ); } } ContentTypeXmlCreator xmlCreator = new ContentTypeXmlCreator(); XMLDocument doc = xmlCreator.createContentTypesDocument( filteredContentTypes ); parameters.put( "step", "1" ); parameters.put( "source", formItems.getString( "source", "mypage" ) ); parameters.put( "subop", formItems.getString( "subop", "" ) ); parameters.put( "fieldrow", formItems.getString( "fieldrow", "" ) ); parameters.put( "fieldname", formItems.getString( "fieldname", "" ) ); transformXML( request, response, doc.getAsJDOMDocument(), "createcontentwizard.xsl", parameters ); } protected boolean userHasAccessOnCategoriesOfContentType( final UserEntity runningUser, final ContentTypeEntity contentType, final CategoryAccessType... categoryAccessTypes ) { final CategoryAccessResolver categoryAccessResolver = new CategoryAccessResolver( groupDao ); for ( final CategoryEntity category : contentType.getCategories( false ) ) { boolean hasAccess = false; for ( final CategoryAccessType accessType : categoryAccessTypes ) { hasAccess = categoryAccessResolver.hasAccess( runningUser, category, accessType ); if ( !hasAccess ) { break; } } if ( hasAccess ) { return true; } } return false; } @SuppressWarnings("unchecked") private void handlerCreateContentWizardStep2( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems, ExtendedMap parameters, User user ) throws VerticalAdminException, VerticalEngineException { final UserEntity runningUser = securityService.getUser( user ); ContentTypeKey contentTypeKey = new ContentTypeKey( formItems.getInt( "contenttypekey" ) ); CategoryKey topCategoryKey = CategoryKey.parse( formItems.getInt( "topcategorykey", -1 ) ); CategoryXmlCreator xmlCreator = new CategoryXmlCreator(); xmlCreator.setCategoryAccessResolver( new CategoryAccessResolver( groupDao ) ); xmlCreator.setUser( runningUser ); xmlCreator.setAnonymousUser( securityService.getUser( securityService.getAnonymousUserKey() ) ); xmlCreator.setAllowedContentType( contentTypeKey ); xmlCreator.setIncludeOwnerAndModiferInfo( false ); xmlCreator.setIncludeCreatedAndTimestampInfo( false ); xmlCreator.setIncludeAutoApproveInfo( false ); xmlCreator.setIncludeDescriptionInfo( false ); xmlCreator.setIncludeSuperCategoryKeyInfo( false ); xmlCreator.setRootAccess( false ); List<CategoryEntity> rootCategories; if ( runningUser.isEnterpriseAdmin() ) { rootCategories = categoryDao.findRootCategories(); } else { rootCategories = categoryDao.findRootCategories( runningUser.getAllMembershipsGroupKeys() ); } final XMLDocument doc = xmlCreator.createCategoryBranch( rootCategories, topCategoryKey ); parameters.put( "step", "2" ); parameters.put( "contenttypekey", contentTypeKey ); parameters.put( "source", formItems.getString( "source" ) ); parameters.put( "subop", formItems.getString( "subop", "" ) ); parameters.put( "fieldrow", formItems.getString( "fieldrow", "" ) ); parameters.put( "fieldname", formItems.getString( "fieldname", "" ) ); transformXML( request, response, doc.getAsJDOMDocument(), "createcontentwizard.xsl", parameters ); } }