/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.structure; import java.util.Collection; import java.util.Map; import java.util.Set; import org.jdom.Document; import org.jdom.Element; import org.springframework.beans.factory.annotation.Autowired; import com.enonic.vertical.adminweb.SitePropertiesXmlCreator; import com.enonic.vertical.engine.handlers.MenuHandler; import com.enonic.cms.framework.xml.XMLBuilder; import com.enonic.cms.framework.xml.XMLDocument; import com.enonic.cms.framework.xml.XMLDocumentFactory; import com.enonic.cms.core.resource.ResourceKey; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.user.UserXmlCreator; import com.enonic.cms.core.structure.menuitem.MenuItemAccessResolver; import com.enonic.cms.core.structure.menuitem.MenuItemEntity; import com.enonic.cms.core.structure.menuitem.MenuItemXMLCreatorSetting; import com.enonic.cms.core.structure.menuitem.MenuItemXmlCreator; public class SiteXmlCreator { private DefaultSiteAccessRightsAccumulatedXmlCreator accessRightsAccumulatedXmlCreator = new DefaultSiteAccessRightsAccumulatedXmlCreator(); private MenuItemXmlCreator menuItemXmlCreator; private MenuItemAccessResolver menuItemAccessResolver; private boolean includeHiddenMenuItems = false; private UserEntity user; private MenuItemEntity activeMenuItem; private boolean includeMenuItems = true; private MenuItemEntity menuItemInBranch; private int menuItemLevels = 0; private int branchStartLevel = 0; private boolean includeTopLevel = false; private boolean includeSiteURLInfo = false; private boolean includeDeviceClassResolverInfo = false; private boolean includeLocalizationInfo = false; private boolean includePathToPublicHome = false; private boolean includePathToHome = false; private boolean includeRunAs = false; private boolean userXmlAsAdminConsoleStyle = true; private final MenuItemEntity menuItemInPreview; private boolean includeProperties; private MenuHandler menuHandler; public SiteXmlCreator( MenuItemAccessResolver menuItemAccessResolver, MenuItemEntity menuItemInPreview, MenuHandler menuHandler ) { this.menuItemAccessResolver = menuItemAccessResolver; this.menuItemInPreview = menuItemInPreview; this.menuHandler = menuHandler; } public SiteXmlCreator( MenuItemAccessResolver menuItemAccessResolver, MenuHandler menuHandler ) { this.menuItemAccessResolver = menuItemAccessResolver; this.menuItemInPreview = null; this.menuHandler = menuHandler; } public Element createSitesElement( Iterable<SiteEntity> sites, Map<SiteKey, SiteProperties> sitesPropertiesMap, String rootElementName ) { return doCreateSitesElement( sites, sitesPropertiesMap, rootElementName ); } private Element doCreateSitesElement( Iterable<SiteEntity> sites, Map<SiteKey, SiteProperties> sitesPropertiesMap, String rootElementName ) { Element rootEl = new Element( rootElementName ); for ( SiteEntity site : sites ) { rootEl.addContent( doCreateMenuElement( site, sitesPropertiesMap.get( site.getKey() ), "site" ) ); } return rootEl; } public Element createMenuElement( SiteEntity site, SiteProperties siteProperties, DefaultSiteAccumulatedAccessRights accessRightsAccumulated ) { includeMenuItems = false; XMLBuilder xmlDoc = new XMLBuilder( "menus" ); createMenuElement( site, siteProperties, xmlDoc, accessRightsAccumulated ); return (Element) xmlDoc.getRootElement().getChild( "menu" ).detach(); } public XMLDocument createLegacyGetMenuData( SiteEntity site, SiteProperties siteProperties ) { includeMenuItems = false; menuItemXmlCreator = new MenuItemXmlCreator( MenuItemXMLCreatorSetting.createFrom( this ), menuItemAccessResolver, menuItemInPreview ); XMLBuilder xmlDoc = new XMLBuilder( "menus" ); createMenuElement( site, siteProperties, xmlDoc, null ); return xmlDoc.getDocument(); } public XMLDocument createLegacyGetMenu( SiteEntity site, SiteProperties siteProperties ) { menuItemXmlCreator = new MenuItemXmlCreator( MenuItemXMLCreatorSetting.createFrom( this ), menuItemAccessResolver, menuItemInPreview ); XMLBuilder xmlDoc = new XMLBuilder( "menus" ); if ( site != null ) { createMenuElement( site, siteProperties, xmlDoc, null ); } return xmlDoc.getDocument(); } public XMLDocument createLegacyGetMenus( Collection<SiteEntity> sites, Map<SiteKey, SiteProperties> sitesPropertiesMap ) { XMLBuilder xmlDoc = new XMLBuilder( "menus" ); for ( SiteEntity site : sites ) { createMenuElement( site, sitesPropertiesMap.get( site.getKey() ), xmlDoc, null ); } return xmlDoc.getDocument(); } public static XMLDocument createEmptyMenuBranch() { return XMLDocumentFactory.create( new Document( new Element( "menu" ) ) ); } public static XMLDocument createEmptyMenus() { return XMLDocumentFactory.create( new Document( new Element( "menus" ) ) ); } public static XMLDocument createEmptyMenuItems() { return XMLDocumentFactory.create( new Document( new Element( "menuitems" ) ) ); } public XMLDocument createLegacyGetMenuBranch( SiteEntity siteEntity ) { if ( siteEntity == null ) { return createEmptyMenuBranch(); } if ( getMenuItemInBranch() == null ) { return createMenuItemsWithErrorMessage( "Menu item not specified" ); } menuItemXmlCreator = new MenuItemXmlCreator( MenuItemXMLCreatorSetting.createFrom( this ), menuItemAccessResolver, menuItemInPreview ); MenuItemEntity menuItemInBranch = getMenuItemInBranch(); if ( menuItemInBranch == null ) { return createMenuItemsWithErrorMessage( "Menu item " + getMenuItemInBranch() + " not found in site " + siteEntity.getKey() ); } int menuItemInBranchLevel = menuItemInBranch.getLevel(); MenuItemEntity topLevelMenuItem; XMLBuilder xmlDoc = new XMLBuilder(); if ( getBranchStartLevel() <= 0 ) { topLevelMenuItem = menuItemInBranch.getTopLevelMenuItem(); if ( includeTopLevel() ) { createMenuItemsElementWithTopLevel( xmlDoc, siteEntity, topLevelMenuItem ); } else { createMenuItemsElement( xmlDoc, topLevelMenuItem, true ); } } else if ( getBranchStartLevel() > menuItemInBranchLevel + 1 ) { return createMenuItemsWithErrorMessage( "Start level (" + getBranchStartLevel() + ") cannot be more than one level below the level of the given menuItem (" + menuItemInBranchLevel + ")" ); } else if ( getBranchStartLevel() == menuItemInBranchLevel + 1 ) { topLevelMenuItem = menuItemInBranch; createMenuItemsElement( xmlDoc, topLevelMenuItem.getChildren(), false ); } else if ( getBranchStartLevel() == menuItemInBranchLevel ) { topLevelMenuItem = menuItemInBranch.getParent(); createMenuItemsElement( xmlDoc, topLevelMenuItem.getChildren(), false ); } else if ( getBranchStartLevel() < menuItemInBranchLevel ) { topLevelMenuItem = menuItemInBranch.getParentAtLevel( getBranchStartLevel() ); topLevelMenuItem = topLevelMenuItem.getParent(); createMenuItemsElement( xmlDoc, topLevelMenuItem.getChildren(), false ); } else { return createMenuItemsWithErrorMessage( "I am not sure what to respond to this" ); } return xmlDoc.getDocument(); } public XMLDocument createLegacyGetSubMenu( SiteEntity siteEntity ) { if ( siteEntity == null ) { return createEmptyMenuBranch(); } if ( getMenuItemInBranch() == null ) { return createMenuItemsWithErrorMessage( "Menu item not specified" ); } if ( getMenuItemLevels() > 0 ) { // on GetSubMenu-calls shall x menuItemLevels be interpreted as x+1 setMenuItemLevels( getMenuItemLevels() + 1 ); } menuItemXmlCreator = new MenuItemXmlCreator( MenuItemXMLCreatorSetting.createFrom( this ), menuItemAccessResolver, menuItemInPreview ); MenuItemEntity menuItemInBranch = getMenuItemInBranch(); if ( menuItemInBranch == null ) { return createMenuItemsWithErrorMessage( "Menu item " + getMenuItemInBranch() + " not found in site " + siteEntity.getKey() ); } boolean isTop = menuItemInBranch.isAtTopLevel(); XMLBuilder xmlDoc = new XMLBuilder(); createMenuItemsElement( xmlDoc, menuItemInBranch, isTop ); return xmlDoc.getDocument(); } private void createMenuItemsElementWithTopLevel( XMLBuilder xmlDoc, SiteEntity site, MenuItemEntity rootMenuItem ) { xmlDoc.startElement( "menuitems" ); xmlDoc.setAttribute( "istop", "yes" ); if ( rootMenuItem != null ) { for ( MenuItemEntity menuItem : site.getTopMenuItems() ) { if ( menuItemXmlCreator.addable( menuItem ) ) { boolean includeChildren = rootMenuItem == menuItem; menuItemXmlCreator.addMenuItemElement( xmlDoc, menuItem, includeChildren ); } } } xmlDoc.endElement(); } private void createMenuItemsElement( XMLBuilder xmlDoc, MenuItemEntity rootMenuItem, boolean isTop ) { xmlDoc.startElement( "menuitems" ); xmlDoc.setAttribute( "istop", isTop ? "yes" : "no" ); if ( rootMenuItem != null && menuItemXmlCreator.addable( rootMenuItem ) ) { menuItemXmlCreator.addMenuItemElement( xmlDoc, rootMenuItem ); } xmlDoc.endElement(); } private void createMenuItemsElement( XMLBuilder xmlDoc, Collection<MenuItemEntity> menuItems, boolean isTop ) { xmlDoc.startElement( "menuitems" ); xmlDoc.setAttribute( "istop", isTop ? "yes" : "no" ); for ( MenuItemEntity menuItem : menuItems ) { if ( menuItemXmlCreator.addable( menuItem ) ) { menuItemXmlCreator.addMenuItemElement( xmlDoc, menuItem ); } } xmlDoc.endElement(); } private XMLDocument createMenuItemsWithErrorMessage( String errorMessage ) { Element menuItems = new Element( "menuitems" ); menuItems.setAttribute( "error", errorMessage ); return XMLDocumentFactory.create( new Document( menuItems ) ); } private Element doCreateMenuElement( SiteEntity site, SiteProperties siteProperties, String rootElementName ) { includeMenuItems = false; XMLBuilder xmlDoc = new XMLBuilder( "dummy" ); createMenuElement( site, siteProperties, xmlDoc, null ); final Element siteEl = xmlDoc.getRootElement().getChild( "menu" ); siteEl.setName( rootElementName ); return (Element) siteEl.detach(); } private void createMenuElement( SiteEntity site, SiteProperties siteProperties, XMLBuilder xmlDoc, DefaultSiteAccumulatedAccessRights accessRightsAccumulated ) { xmlDoc.startElement( "menu" ); xmlDoc.setAttribute( "key", site.getKey().toString() ); xmlDoc.setAttribute( "language", site.getLanguage().getDescription() ); xmlDoc.setAttribute( "languagekey", site.getLanguage().getKey().toInt() ); xmlDoc.setAttribute( "languagecode", site.getLanguage().getCode() ); xmlDoc.startElement( "name" ); if ( site.getName() != null ) { xmlDoc.addContent( site.getName() ); } xmlDoc.endElement(); xmlDoc.startElement( "firstpage" ); if ( site.getFrontPage() != null ) { xmlDoc.setAttribute( "key", site.getFrontPage().getKey().toInt() ); } xmlDoc.endElement(); xmlDoc.startElement( "loginpage" ); if ( site.getLoginPage() != null ) { xmlDoc.setAttribute( "key", String.valueOf( site.getLoginPage().getKey().toInt() ) ); } xmlDoc.endElement(); xmlDoc.startElement( "errorpage" ); if ( site.getErrorPage() != null ) { xmlDoc.setAttribute( "key", site.getErrorPage().getKey().toInt() ); } xmlDoc.endElement(); xmlDoc.startElement( "defaultpagetemplate" ); if ( site.getPageTemplate() != null ) { xmlDoc.setAttribute( "pagetemplatekey", Integer.toString( site.getPageTemplate().getKey() ) ); } xmlDoc.endElement(); addMenudataElement( site, xmlDoc ); xmlDoc.startElement( "details" ); xmlDoc.setAttribute( "menukey", site.getKey().toString() ); xmlDoc.endElement(); if ( includeSiteURLInfo ) { xmlDoc.startElement( "url" ); if ( siteProperties != null && siteProperties.getSiteURL() != null ) { xmlDoc.addContent( siteProperties.getSiteURL() ); } xmlDoc.endElement(); } xmlDoc.startElement( "statistics" ); if ( site.getStatisticsUrl() != null ) { xmlDoc.addContent( site.getStatisticsUrl() ); } xmlDoc.endElement(); if ( includeDeviceClassResolverInfo ) { xmlDoc.startElement( "deviceclassresolver" ); if ( site.getDeviceClassResolver() != null ) { xmlDoc.setAttribute( "key", site.getDeviceClassResolver().toString() ); } xmlDoc.endElement(); } if ( includeLocalizationInfo ) { xmlDoc.startElement( "defaultlocalizationresource" ); if ( site.getDefaultLocalizationResource() != null ) { xmlDoc.setAttribute( "key", site.getDefaultLocalizationResource().toString() ); } xmlDoc.endElement(); xmlDoc.startElement( "localeresolver" ); if ( site.getLocaleResolver() != null ) { xmlDoc.setAttribute( "key", site.getLocaleResolver().toString() ); } xmlDoc.endElement(); } if ( includePathToPublicHome ) { xmlDoc.startElement( "path-to-public-home-resources" ); if ( site.getPathToPublicResources() != null ) { xmlDoc.setAttribute( "key", site.getPathToPublicResources().toString() ); } xmlDoc.endElement(); } if ( includePathToHome ) { xmlDoc.startElement( "path-to-home-resources" ); if ( site.getPathToResources() != null ) { xmlDoc.setAttribute( "key", site.getPathToResources().toString() ); } xmlDoc.endElement(); } if ( includeRunAs ) { UserEntity runAsUser = menuHandler.getRunAsUserForSite( site.getKey() ); if ( runAsUser != null ) { xmlDoc.startElement( "run-as" ); UserXmlCreator userXmlCreator = new UserXmlCreator(); userXmlCreator.setAdminConsoleStyle( userXmlAsAdminConsoleStyle ); xmlDoc.getCurrentElement().addContent( userXmlCreator.createUserElement( runAsUser, false ) ); xmlDoc.endElement(); } } if ( accessRightsAccumulated != null ) { accessRightsAccumulatedXmlCreator.setUserRightAttributes( xmlDoc.getCurrentElement(), accessRightsAccumulated ); } if ( includeMenuItems() ) { createMenuItemsElement( xmlDoc, site.getTopMenuItems(), true ); } // include site-x.properties if ( includeProperties && siteProperties != null) { final SitePropertiesXmlCreator xmlCreator = new SitePropertiesXmlCreator(); xmlDoc.startElement( "advanced" ); xmlDoc.getCurrentElement().addContent( xmlCreator.createElement( "properties", "property", siteProperties.getProperties() ) ); xmlDoc.endElement(); } xmlDoc.endElement(); } private void addMenudataElement( SiteEntity site, XMLBuilder xmlDoc ) { final Set<String> allowedPageTypes = site.getAllowedPageTypes(); final ResourceKey defaultCssKey = site.getDefaultCssKey(); if ( allowedPageTypes.size() == 0 && defaultCssKey == null ) { xmlDoc.addContentElement( "menudata", "" ); return; } xmlDoc.startElement( "menudata" ); if ( allowedPageTypes.size() > 0 ) { xmlDoc.startElement( "pagetypes" ); for ( String type : allowedPageTypes ) { xmlDoc.startElement( "allow" ); xmlDoc.setAttribute( "type", type ); xmlDoc.endElement(); } xmlDoc.endElement(); } if ( defaultCssKey != null ) { xmlDoc.startElement( "defaultcss" ); xmlDoc.setAttribute( "key", defaultCssKey.toString() ); xmlDoc.endElement(); } xmlDoc.endElement(); } public void setIncludeSiteURLInfo( boolean includeSiteURLInfo ) { this.includeSiteURLInfo = includeSiteURLInfo; } public void setIncludeDeviceClassResolverInfo( boolean includeDeviceClassResolverInfo ) { this.includeDeviceClassResolverInfo = includeDeviceClassResolverInfo; } public void setIncludeLocalizationInfo( boolean includeLocalizationInfo ) { this.includeLocalizationInfo = includeLocalizationInfo; } public void setIncludePathToPublicHome( boolean includePathToPublicHome ) { this.includePathToPublicHome = includePathToPublicHome; } public void setIncludePathToHome( boolean includePathToHome ) { this.includePathToHome = includePathToHome; } public void setIncludeRunAs( boolean includeRunAs ) { this.includeRunAs = includeRunAs; } public boolean includeHiddenMenuItems() { return includeHiddenMenuItems; } public void setIncludeHiddenMenuItems( boolean includeHiddenMenuItems ) { this.includeHiddenMenuItems = includeHiddenMenuItems; } public UserEntity getUser() { return user; } public void setUser( UserEntity user ) { this.user = user; } public MenuItemEntity getActiveMenuItem() { return activeMenuItem; } public void setActiveMenuItem( MenuItemEntity activeMenuItem ) { this.activeMenuItem = activeMenuItem; } public boolean includeMenuItems() { return includeMenuItems; } public void setIncludeMenuItems( boolean includeMenuItems ) { this.includeMenuItems = includeMenuItems; } public MenuItemEntity getMenuItemInBranch() { return menuItemInBranch; } public void setMenuItemInBranch( MenuItemEntity menuItemInBranch ) { this.menuItemInBranch = menuItemInBranch; } public int getMenuItemLevels() { return menuItemLevels; } public void setMenuItemLevels( int menuItemLevels ) { this.menuItemLevels = menuItemLevels; } public int getBranchStartLevel() { return branchStartLevel; } public void setBranchStartLevel( int branchStartLevel ) { this.branchStartLevel = branchStartLevel; } public boolean includeTopLevel() { return includeTopLevel; } public void setIncludeTopLevel( boolean includeTopLevel ) { this.includeTopLevel = includeTopLevel; } public void setUserXmlAsAdminConsoleStyle( boolean userXmlAsAdminConsoleStyle ) { this.userXmlAsAdminConsoleStyle = userXmlAsAdminConsoleStyle; } public void setIncludeProperties( final boolean includeProperties ) { this.includeProperties = includeProperties; } public boolean isIncludeProperties() { return includeProperties; } }