package org.exoplatform.portal.mop.page; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.exoplatform.portal.mop.Described; import org.exoplatform.portal.mop.ProtectedContainer; import org.exoplatform.portal.mop.ProtectedResource; import org.exoplatform.portal.mop.QueryResult; import org.exoplatform.portal.mop.SiteKey; import org.exoplatform.portal.mop.SiteType; import org.exoplatform.portal.mop.Utils; import org.exoplatform.portal.pom.config.POMSession; import org.exoplatform.portal.pom.config.POMSessionManager; import org.exoplatform.portal.pom.data.MappedAttributes; import org.gatein.mop.api.Attributes; import org.gatein.mop.api.content.ContentType; import org.gatein.mop.api.content.Customization; import org.gatein.mop.api.workspace.ObjectType; import org.gatein.mop.api.workspace.Page; import org.gatein.mop.api.workspace.Site; import org.gatein.mop.api.workspace.Workspace; import org.gatein.mop.api.workspace.WorkspaceCustomizationContext; import org.gatein.mop.api.workspace.ui.UIComponent; import org.gatein.mop.api.workspace.ui.UIContainer; import org.gatein.mop.api.workspace.ui.UIWindow; /** * This class implements the {@link PageService} business methods. * * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ public class PageServiceImpl implements PageService { /** . */ final POMSessionManager manager; /** . */ private final DataCache dataCache; /** * Create an instance that uses a simple data cache, such instance should be used for testing purposes. * * @param manager the mop session manager * @throws NullPointerException if the manager argument is null */ public PageServiceImpl(POMSessionManager manager) throws NullPointerException { this(manager, new SimpleDataCache()); } /** * Create an instance that will use a specified data cache instance. * * @param manager the mop session manager * @param dataCache the data cache * @throws NullPointerException if any argument is null */ public PageServiceImpl(POMSessionManager manager, DataCache dataCache) throws NullPointerException { if (manager == null) { throw new NullPointerException("No null pom session manager allowed"); } if (dataCache == null) { throw new NullPointerException("No null data cache allowed"); } this.manager = manager; this.dataCache = dataCache; } @Override public PageContext loadPage(PageKey key) { if (key == null) { throw new NullPointerException(); } // POMSession session = manager.getSession(); PageData data = dataCache.getPageData(session, key); return data != null && data != PageData.EMPTY ? new PageContext(data) : null; } /** * <p> * Load all the pages of a specific site. Note that this method can potentially raise performance issues if the number of * pages is very large and should be used with cautions. That's the motiviation for not having this method on the * {@link PageService} interface. * </p> * * @param siteKey the site key * @return the list of pages * @throws NullPointerException if the site key argument is null * @throws PageServiceException anything that would prevent the operation to succeed */ public List<PageContext> loadPages(SiteKey siteKey) throws NullPointerException, PageServiceException { if (siteKey == null) { throw new NullPointerException("No null site key accepted"); } // POMSession session = manager.getSession(); ObjectType<Site> objectType = Utils.objectType(siteKey.getType()); Workspace workspace = session.getWorkspace(); Site site = workspace.getSite(objectType, siteKey.getName()); // if (site == null) { throw new PageServiceException(PageError.NO_SITE); } // org.gatein.mop.api.workspace.Page root = site.getRootPage(); Collection<org.gatein.mop.api.workspace.Page> pages = root.getChild("pages").getChildren(); List<PageContext> list = new ArrayList<PageContext>(pages.size()); for (Page page : pages) { list.add(loadPage(new PageKey(siteKey, page.getName()))); } return list; } @Override public boolean savePage(PageContext page) { if (page == null) { throw new NullPointerException(); } // POMSession session = manager.getSession(); ObjectType<Site> objectType = Utils.objectType(page.key.getSite().getType()); Workspace workspace = session.getWorkspace(); Site site = workspace.getSite(objectType, page.key.getSite().getName()); // if (site == null) { throw new PageServiceException(PageError.NO_SITE); } // org.gatein.mop.api.workspace.Page root = site.getRootPage(); org.gatein.mop.api.workspace.Page pages = root.getChild("pages"); org.gatein.mop.api.workspace.Page dst = pages.getChild(page.key.getName()); // boolean created; if (dst == null) { dst = pages.addChild(page.key.getName()); created = true; } else { created = false; } // PageState state = page.state; if (state != null) { ProtectedResource pr = dst.adapt(ProtectedResource.class); pr.setAccessPermissions(page.state.accessPermissions); pr.setEditPermission(page.state.editPermission); ProtectedContainer dstPc = dst.adapt(ProtectedContainer.class); dstPc.setMoveAppsPermissions(page.state.moveAppsPermissions); dstPc.setMoveContainersPermissions(page.state.moveContainersPermissions); // Described described = dst.adapt(Described.class); described.setName(page.state.displayName); described.setDescription(page.state.description); // Attributes attrs = dst.getAttributes(); attrs.setValue(MappedAttributes.FACTORY_ID, page.state.factoryId); attrs.setValue(MappedAttributes.SHOW_MAX_WINDOW, page.state.showMaxWindow); } // dataCache.removePage(session, page.key); // Update state page.data = dataCache.getPageData(session, page.key); page.state = null; // return created; } @Override public boolean destroyPage(PageKey key) { if (key == null) { throw new NullPointerException("No null page argument"); } // POMSession session = manager.getSession(); ObjectType<Site> objectType = Utils.objectType(key.getSite().getType()); Workspace workspace = session.getWorkspace(); Site site = workspace.getSite(objectType, key.getSite().getName()); // if (site == null) { throw new PageServiceException(PageError.NO_SITE); } // org.gatein.mop.api.workspace.Page root = site.getRootPage(); org.gatein.mop.api.workspace.Page pages = root.getChild("pages"); org.gatein.mop.api.workspace.Page page = pages.getChild(key.getName()); if (page != null) { page.destroy(); dataCache.removePage(session, key); return true; } else { return false; } } @Override public PageContext clone(PageKey src, PageKey dst) { POMSession session = manager.getSession(); Workspace workspace = session.getWorkspace(); // org.gatein.mop.api.workspace.Page srcPage; ObjectType<Site> srcType = Utils.objectType(src.site.getType()); Site srcSite = workspace.getSite(srcType, src.site.getName()); if (srcSite == null) { throw new PageServiceException(PageError.CLONE_NO_SRC_SITE, "Could not clone page " + src.getName() + "from non existing site of type " + src.site.getType() + " with id " + src.site.getName()); } else { org.gatein.mop.api.workspace.Page root = srcSite.getRootPage(); org.gatein.mop.api.workspace.Page pages = root.getChild("pages"); srcPage = pages.getChild(src.getName()); } // if (srcPage == null) { throw new PageServiceException(PageError.CLONE_NO_SRC_PAGE, "Could not clone non existing page " + src.getName() + " from site of type " + src.site.getType() + " with id " + src.site.getName()); } // ObjectType<Site> dstType = Utils.objectType(dst.getSite().getType()); Site dstSite = workspace.getSite(dstType, dst.getSite().getName()); if (dstSite == null) { throw new PageServiceException(PageError.CLONE_NO_DST_SITE, "Could not clone page " + dst.name + "to non existing site of type " + dst.site.getType() + " with id " + dst.site.getName()); } // org.gatein.mop.api.workspace.Page dstRoot = dstSite.getRootPage(); org.gatein.mop.api.workspace.Page dstPages = dstRoot.getChild("pages"); if (dstPages.getChild(dst.getName()) != null) { throw new PageServiceException(PageError.CLONE_DST_ALREADY_EXIST, "Could not clone page " + dst.name + "to existing page " + dst.site.getType() + " with id " + dst.site.getName()); } // org.gatein.mop.api.workspace.Page dstPage = dstPages.addChild(dst.getName()); // Copy all attributes Attributes srcAttrs = srcPage.getAttributes(); Attributes dstAttrs = dstPage.getAttributes(); for (String key : srcAttrs.getKeys()) { Object value = srcAttrs.getObject(key); dstAttrs.setObject(key, value); } // Copy described Described srcDescribed = srcPage.adapt(Described.class); Described dstDescribed = dstPage.adapt(Described.class); dstDescribed.setName(srcDescribed.getName()); dstDescribed.setDescription(srcDescribed.getDescription()); // Copy src permissions to dst permission ProtectedResource srcPR = srcPage.adapt(ProtectedResource.class); ProtectedResource dstPR = dstPage.adapt(ProtectedResource.class); dstPR.setAccessPermissions(srcPR.getAccessPermissions()); dstPR.setEditPermission(srcPR.getEditPermission()); if (srcPage.isAdapted(ProtectedContainer.class)) { ProtectedContainer srcPc = srcPage.adapt(ProtectedContainer.class); ProtectedContainer dstPc = dstPage.adapt(ProtectedContainer.class); dstPc.setMoveAppsPermissions(srcPc.getMoveAppsPermissions()); dstPc.setMoveContainersPermissions(srcPc.getMoveContainersPermissions()); } // Need to clone page data structure as well copy(srcPage, dstPage, srcPage.getRootComponent(), dstPage.getRootComponent()); // Remove dataCache.removePage(session, dst); // return new PageContext(new PageData(dstPage)); } private void copy(Page srcPage, Page dstPage, UIContainer src, UIContainer dst) { for (UIComponent srcChild : src.getComponents()) { UIComponent dstChild = dst.add(srcChild.getObjectType(), srcChild.getObjectId()); // if (srcChild.isAdapted(Described.class)) { Described srcDescribed = srcChild.adapt(Described.class); Described dstDescribed = dstChild.adapt(Described.class); dstDescribed.setName(srcDescribed.getName()); dstDescribed.setDescription(srcDescribed.getDescription()); } // if (srcChild.isAdapted(ProtectedResource.class)) { ProtectedResource srcPR = srcChild.adapt(ProtectedResource.class); ProtectedResource dstPR = dstChild.adapt(ProtectedResource.class); dstPR.setAccessPermissions(srcPR.getAccessPermissions()); dstPR.setEditPermission(srcPR.getEditPermission()); } if (srcChild.isAdapted(ProtectedContainer.class)) { ProtectedContainer srcPc = srcPage.adapt(ProtectedContainer.class); ProtectedContainer dstPc = dstPage.adapt(ProtectedContainer.class); dstPc.setMoveAppsPermissions(srcPc.getMoveAppsPermissions()); dstPc.setMoveContainersPermissions(srcPc.getMoveContainersPermissions()); } // Attributes srcAttrs = srcChild.getAttributes(); Attributes dstAttrs = dstChild.getAttributes(); for (String key : srcAttrs.getKeys()) { Object value = srcAttrs.getObject(key); dstAttrs.setObject(key, value); } // if (srcChild instanceof UIWindow) { UIWindow srcWindow = (UIWindow) srcChild; UIWindow dstWindow = (UIWindow) dstChild; Customization<?> customization = srcWindow.getCustomization(); ContentType contentType = customization.getType(); String contentId = customization.getContentId(); Customization parent = customization.getParent(); Customization dstParent = null; if (parent != null) { WorkspaceCustomizationContext parentCtx = (WorkspaceCustomizationContext) parent.getContext(); String name = parentCtx.nameOf(parent); if (parentCtx == srcPage) { dstParent = dstPage.getCustomizationContext().getCustomization(name); if (dstParent == null) { Object state = parent.getVirtualState(); dstParent = dstPage.getCustomizationContext().customize(name, contentType, contentId, state); } } if (dstParent != null) { Object state = customization.getState(); Customization dstCustomization = dstWindow.customize(dstParent); dstCustomization.setState(state); } else { Object state = customization.getVirtualState(); dstWindow.customize(contentType, contentId, state); } } else { Object state = customization.getVirtualState(); dstWindow.customize(contentType, contentId, state); } } else if (srcChild instanceof UIContainer) { UIContainer srcContainer = (UIContainer) srcChild; UIContainer dstContainer = (UIContainer) dstChild; copy(srcPage, dstPage, srcContainer, dstContainer); } } } @Override public QueryResult<PageContext> findPages(int from, int to, SiteType siteType, String siteName, String pageName, String pageTitle) { POMSession session = manager.getSession(); org.chromattic.api.query.QueryResult<Page> a = session.findObjects(ObjectType.PAGE, Utils.objectType(siteType), siteName, pageTitle, from, to); int size = a.size(); PageContext[] array = new PageContext[size]; int ptr = 0; while (a.hasNext()) { Page page = a.next(); PageData data = new PageData(page); dataCache.putPage(data); array[ptr++] = new PageContext(data); } return new QueryResult<PageContext>(from, size, Arrays.asList(array)); } public void clearCache() { dataCache.clear(); } }