org.opencms.ade.containerpage.client.CmsContainerpageUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.opencms.ade.containerpage.client.CmsContainerpageUtil.java

Source

/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.ade.containerpage.client;

import org.opencms.ade.containerpage.client.ui.A_CmsToolbarOptionButton;
import org.opencms.ade.containerpage.client.ui.CmsContainerPageContainer;
import org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel;
import org.opencms.ade.containerpage.client.ui.CmsElementOptionBar;
import org.opencms.ade.containerpage.client.ui.CmsGroupContainerElementPanel;
import org.opencms.ade.containerpage.client.ui.CmsMenuListItem;
import org.opencms.ade.containerpage.client.ui.I_CmsDropContainer;
import org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle;
import org.opencms.ade.containerpage.shared.CmsContainerElementData;
import org.opencms.gwt.client.util.CmsDomUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.google.gwt.dom.client.Node;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;

/**
 * Utility class for the container-page editor.<p>
 * 
 * @since 8.0.0
 */
public class CmsContainerpageUtil {

    /** HTML class used to identify container elements. Has to be identical with {@link org.opencms.jsp.CmsJspTagContainer#CLASS_CONTAINER_ELEMENT_END_MARKER}. */
    public static final String CLASS_CONTAINER_ELEMENT_END_MARKER = "cms_ade_element_end";

    /** HTML class used to identify container elements. Has to be identical with {@link org.opencms.jsp.CmsJspTagContainer#CLASS_CONTAINER_ELEMENT_START_MARKER}. */
    public static final String CLASS_CONTAINER_ELEMENT_START_MARKER = "cms_ade_element_start";

    /** HTML class used to identify group container elements. Has to be identical with {@link org.opencms.jsp.CmsJspTagContainer#CLASS_GROUP_CONTAINER_ELEMENT_MARKER}. */
    public static final String CLASS_GROUP_CONTAINER_ELEMENT_MARKER = "cms_ade_groupcontainer";

    /** The container page controller. */
    private CmsContainerpageController m_controller;

    /** List of buttons of the tool-bar. */
    private A_CmsToolbarOptionButton[] m_optionButtons;

    /**
     * Constructor.<p>
     * 
     * @param controller the container page controller
     * @param optionButtons the tool-bar option buttons
     */
    public CmsContainerpageUtil(CmsContainerpageController controller, A_CmsToolbarOptionButton... optionButtons) {

        m_controller = controller;
        m_optionButtons = optionButtons;
    }

    /**
     * Adds an option bar to the given drag element.<p>
     * 
     * @param element the element
     */
    public void addOptionBar(CmsContainerPageElementPanel element) {

        // the view permission is required for any actions regarding this element
        if (element.hasViewPermission()) {
            CmsElementOptionBar optionBar = CmsElementOptionBar.createOptionBarForElement(element,
                    m_controller.getDndHandler(), m_optionButtons);
            element.setElementOptionBar(optionBar);
        }
    }

    /**
     * Transforms all contained elements into {@link CmsContainerPageElementPanel}.<p>
     * 
     * @param container the container
     */
    public void consumeContainerElements(I_CmsDropContainer container) {

        // the drag element widgets are created from the existing DOM elements,
        Element child = (Element) container.getElement().getFirstChildElement();
        while (child != null) {
            boolean isContainerElement = CmsDomUtil.hasClass(CLASS_CONTAINER_ELEMENT_START_MARKER, child);
            boolean isGroupcontainerElement = CmsDomUtil.hasClass(CLASS_GROUP_CONTAINER_ELEMENT_MARKER, child);
            if (isContainerElement || isGroupcontainerElement) {
                String clientId = child.getAttribute("clientId");
                String sitePath = child.getAttribute("alt");
                String noEditReason = child.getAttribute("rel");
                String newType = child.getAttribute("newType");
                boolean hasProps = Boolean.parseBoolean(child.getAttribute("hasprops"));
                boolean hasViewPermission = Boolean.parseBoolean(child.getAttribute("hasviewpermission"));
                boolean releasedAndNotExpired = Boolean.parseBoolean(child.getAttribute("releasedandnotexpired"));
                if (isContainerElement) {
                    // searching for content element root
                    Element elementRoot = (Element) child.getNextSibling();
                    while ((elementRoot != null) && (elementRoot.getNodeType() != Node.ELEMENT_NODE)) {
                        Element temp = elementRoot;
                        elementRoot = (Element) elementRoot.getNextSibling();
                        temp.removeFromParent();
                    }
                    if (elementRoot == null) {
                        child.removeFromParent();
                        child = null;
                        continue;
                    }
                    if (CmsDomUtil.hasClass(CLASS_CONTAINER_ELEMENT_START_MARKER, elementRoot)) {
                        // broken element, already at next start marker
                        child.removeFromParent();
                        child = elementRoot;
                        continue;
                    }
                    if (CmsDomUtil.hasClass(CLASS_CONTAINER_ELEMENT_END_MARKER, elementRoot)) {
                        // broken element, no content element root
                        child.removeFromParent();
                        child = (Element) elementRoot.getNextSiblingElement();
                        elementRoot.removeFromParent();
                        continue;
                    } else {
                        // looking for the next marker that wraps the current element
                        Element endMarker = (Element) elementRoot.getNextSibling();
                        // only if the end marker node is not null and has neither the end-marker class or start-marker class
                        // remove the current node and check the next sibling 
                        while (!((endMarker == null) || ((endMarker.getNodeType() == Node.ELEMENT_NODE)
                                && (CmsDomUtil.hasClass(CLASS_CONTAINER_ELEMENT_END_MARKER, endMarker) || CmsDomUtil
                                        .hasClass(CLASS_CONTAINER_ELEMENT_START_MARKER, endMarker))))) {
                            Element temp = endMarker;
                            endMarker = (Element) endMarker.getNextSibling();
                            temp.removeFromParent();
                        }
                        if (endMarker == null) {
                            // broken element, end marker missing
                            elementRoot.removeFromParent();
                            child.removeFromParent();
                            child = null;
                            continue;
                        }
                        if (CmsDomUtil.hasClass(CLASS_CONTAINER_ELEMENT_START_MARKER, endMarker)) {
                            // broken element, end marker missing
                            elementRoot.removeFromParent();
                            child.removeFromParent();
                            child = endMarker;
                        }
                        CmsDomUtil.removeScriptTags(elementRoot);
                        CmsContainerPageElementPanel containerElement = createElement(elementRoot, container,
                                clientId, sitePath, noEditReason, hasProps, hasViewPermission,
                                releasedAndNotExpired);
                        if ((newType != null) && (newType.length() > 0)) {
                            containerElement.setNewType(newType);
                        }
                        container.adoptElement(containerElement);
                        child.removeFromParent();
                        child = (Element) endMarker.getNextSiblingElement(); //   (Element)container.getElement().getFirstChildElement();
                        endMarker.removeFromParent();

                    }
                } else if (isGroupcontainerElement && (container instanceof CmsContainerPageContainer)) {
                    CmsDomUtil.removeScriptTags(child);
                    CmsGroupContainerElementPanel groupContainer = createGroupcontainer(child, container, clientId,
                            sitePath, noEditReason, hasProps, hasViewPermission, releasedAndNotExpired);
                    groupContainer.setContainerId(container.getContainerId());
                    container.adoptElement(groupContainer);
                    consumeContainerElements(groupContainer);
                    if (groupContainer.getWidgetCount() == 0) {
                        groupContainer
                                .addStyleName(I_CmsLayoutBundle.INSTANCE.containerpageCss().emptyGroupContainer());
                    }
                    // important: adding the option-bar only after the group-containers have been consumed 
                    addOptionBar(groupContainer);
                    child = (Element) child.getNextSiblingElement();
                }
            } else {
                Element sibling = (Element) child.getNextSiblingElement();
                DOM.removeChild((Element) container.getElement(), child);
                child = sibling;
                continue;
            }
        }
    }

    /**
     * The method will create {@link CmsContainerPageContainer} object for all given containers
     * by converting the associated DOM elements. The contained elements will be transformed into {@link CmsContainerPageElementPanel}.<p>
     * 
     * @param containers the container data
     * 
     * @return the drag target containers
     */
    public Map<String, CmsContainerPageContainer> consumeContainers(Map<String, CmsContainerJso> containers) {

        Map<String, CmsContainerPageContainer> result = new HashMap<String, CmsContainerPageContainer>();
        Iterator<CmsContainerJso> it = containers.values().iterator();
        while (it.hasNext()) {
            CmsContainerJso container = it.next();
            CmsContainerPageContainer dragContainer = new CmsContainerPageContainer(container);
            consumeContainerElements(dragContainer);
            result.put(container.getName(), dragContainer);
        }

        return result;
    }

    /**
     * Creates an drag container element.<p>
     * 
     * @param containerElement the container element data 
     * @param container the container parent
     * 
     * @return the draggable element
     * 
     * @throws Exception if something goes wrong
     */
    public CmsContainerPageElementPanel createElement(CmsContainerElementData containerElement,
            I_CmsDropContainer container) throws Exception {

        if (containerElement.isGroupContainer()) {
            List<CmsContainerElementData> subElements = new ArrayList<CmsContainerElementData>();
            for (String subId : containerElement.getSubItems()) {
                CmsContainerElementData element = m_controller.getCachedElement(subId);
                if (element != null) {
                    subElements.add(element);
                }
            }
            return createGroupcontainerElement(containerElement, subElements, container);
        }
        boolean hasProps = !containerElement.getSettingConfig().isEmpty();
        com.google.gwt.user.client.Element element = CmsDomUtil
                .createElement(containerElement.getContents().get(container.getContainerId()));
        // ensure any embedded flash players are set opaque so UI elements may be placed above them
        CmsDomUtil.fixFlashZindex(element);
        return createElement(element, container, containerElement.getClientId(), containerElement.getSitePath(),
                containerElement.getNoEditReason(), hasProps, containerElement.hasViewPermission(),
                containerElement.isReleasedAndNotExpired());
    }

    /**
     * Creates a drag container element for group-container elements.<p>
     * 
     * @param containerElement the container element data 
     * @param subElements the sub-elements
     * @param container the drag parent
     * 
     * @return the draggable element
     * 
     * @throws Exception if something goes wrong
     */
    public CmsContainerPageElementPanel createGroupcontainerElement(CmsContainerElementData containerElement,
            List<CmsContainerElementData> subElements, I_CmsDropContainer container) throws Exception {

        com.google.gwt.user.client.Element element = DOM.createDiv();
        element.addClassName(CmsContainerpageUtil.CLASS_GROUP_CONTAINER_ELEMENT_MARKER);
        boolean hasProps = !containerElement.getSettingConfig().isEmpty();

        CmsGroupContainerElementPanel groupContainer = createGroupcontainer(element, container,
                containerElement.getClientId(), containerElement.getSitePath(), containerElement.getNoEditReason(),
                hasProps, containerElement.hasViewPermission(), containerElement.isReleasedAndNotExpired());
        groupContainer.setContainerId(container.getContainerId());
        //adding sub-elements
        Iterator<CmsContainerElementData> it = subElements.iterator();
        while (it.hasNext()) {
            CmsContainerElementData subElement = it.next();
            if (subElement.getContents().containsKey(container.getContainerId())) {
                CmsContainerPageElementPanel subDragElement = createElement(subElement, groupContainer);
                groupContainer.add(subDragElement);
            }
        }
        if (subElements.size() == 0) {
            groupContainer.addStyleName(I_CmsLayoutBundle.INSTANCE.containerpageCss().emptyGroupContainer());
        }
        addOptionBar(groupContainer);
        return groupContainer;
    }

    /**
     * Creates a list item.<p>
     * 
     * @param containerElement the element data
     * 
     * @return the list item widget
     */
    public CmsMenuListItem createListItem(CmsContainerElementData containerElement) {

        CmsMenuListItem listItem = new CmsMenuListItem(containerElement);
        listItem.initMoveHandle(m_controller.getDndHandler());
        return listItem;
    }

    /**
     * Creates an drag container element.<p>
     * 
     * @param element the DOM element
     * @param dragParent the drag parent
     * @param clientId the client id
     * @param sitePath the element site-path
     * @param noEditReason the no edit reason
     * @param hasProps if true, the container element has properties which can be edited 
     * @param hasViewPermission indicates if the current user has view permissions on the element resource
     * 
     * @return the draggable element
     */
    private CmsContainerPageElementPanel createElement(com.google.gwt.user.client.Element element,
            I_CmsDropContainer dragParent, String clientId, String sitePath, String noEditReason, boolean hasProps,
            boolean hasViewPermission, boolean releasedAndNotExpired) {

        CmsContainerPageElementPanel dragElement = new CmsContainerPageElementPanel(element, dragParent, clientId,
                sitePath, noEditReason, hasProps, hasViewPermission, releasedAndNotExpired);
        //        enableDragHandler(dragElement);
        addOptionBar(dragElement);
        return dragElement;
    }

    /**
     * Creates an drag container element. This will not add an option-bar!<p>
     * 
     * @param element the DOM element
     * @param dragParent the drag parent
     * @param clientId the client id
     * @param sitePath the element site-path
     * @param noEditReason the no edit reason
     * @param hasProps true if the group-container has properties to edit 
     * @param hasViewPermission indicates if the current user has view permissions on the element resource
     * 
     * @return the draggable element
     */
    private CmsGroupContainerElementPanel createGroupcontainer(com.google.gwt.user.client.Element element,
            I_CmsDropContainer dragParent, String clientId, String sitePath, String noEditReason, boolean hasProps,
            boolean hasViewPermission, boolean releasedAndNotExpired) {

        CmsGroupContainerElementPanel groupContainer = new CmsGroupContainerElementPanel(element, dragParent,
                clientId, sitePath, noEditReason, hasProps, hasViewPermission, releasedAndNotExpired);
        return groupContainer;
    }

}