Package org.apache.lenya.cms.site.tree

Source Code of org.apache.lenya.cms.site.tree.TreeSiteManager

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/

package org.apache.lenya.cms.site.tree;

import java.util.ArrayList;
import java.util.List;

import org.apache.avalon.framework.service.Serviceable;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentException;
import org.apache.lenya.cms.publication.DocumentFactory;
import org.apache.lenya.cms.publication.DocumentLocator;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.repository.RepositoryItemFactory;
import org.apache.lenya.cms.site.AbstractSiteManager;
import org.apache.lenya.cms.site.Link;
import org.apache.lenya.cms.site.NodeSet;
import org.apache.lenya.cms.site.SiteException;
import org.apache.lenya.cms.site.SiteNode;
import org.apache.lenya.cms.site.SiteStructure;

/**
* A tree-based site manager.
*
* @version $Id: TreeSiteManager.java 208766 2005-07-01 16:05:00Z andreas $
*/
public class TreeSiteManager extends AbstractSiteManager implements Serviceable {

    /**
     * Ctor.
     */
    public TreeSiteManager() {
        // do nothing
    }

    /**
     * Returns the sitetree for a specific area of this publication. Sitetrees are created on demand
     * and are cached.
     *
     * @param map The document identity map.
     * @param publication The publication.
     * @param area The area.
     * @return A site tree.
     * @throws SiteException if an error occurs.
     */
    public DefaultSiteTree getTree(DocumentFactory map, Publication publication, String area)
            throws SiteException {

        String key = getKey(publication, area);
        DefaultSiteTree sitetree;
        RepositoryItemFactory factory = new SiteTreeFactory(this.manager, getLogger());
        try {
            sitetree = (DefaultSiteTree) map.getSession().getRepositoryItem(factory, key);
        } catch (Exception e) {
            throw new SiteException(e);
        }

        return sitetree;
    }

    protected DefaultSiteTree getTree(Document document) throws SiteException {
        return getTree(document.getFactory(), document.getPublication(), document.getArea());
    }

    /**
     * Returns the ancestors of a resource, beginning with the parent.
     *
     * @param node The resource.
     * @return A list of resources.
     * @throws SiteException if an error occurs.
     */
    protected List getAncestors(SiteNode node) throws SiteException {
        List ancestors = new ArrayList();
        SiteNode parent = null;
        try {
            if (!node.isTopLevel()) {
                parent = node.getParent();
                ancestors.add(parent);
                ancestors.addAll(getAncestors(parent));
            }
        } catch (Exception e) {
            throw new SiteException(e);
        }
        return ancestors;
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#requires(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.site.SiteNode, org.apache.lenya.cms.site.SiteNode)
     */
    public boolean requires(DocumentFactory map, SiteNode dependingResource,
            SiteNode requiredResource) throws SiteException {
        return getAncestors(dependingResource).contains(requiredResource);
    }

    public DocumentLocator[] getRequiredResources(DocumentFactory map, final DocumentLocator loc)
            throws SiteException {
       
        List ancestors = new ArrayList();
        DocumentLocator locator = loc;
        while (locator.getParent() != null) {
            DocumentLocator parent = locator.getParent();
            ancestors.add(parent);
            locator = parent;
        }
        return (DocumentLocator[]) ancestors.toArray(new DocumentLocator[ancestors.size()]);
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getRequiringResources(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.site.SiteNode)
     */
    public SiteNode[] getRequiringResources(DocumentFactory map, SiteNode resource)
            throws SiteException {

        if (getLogger().isDebugEnabled()) {
            getLogger().debug("Obtaining requiring resources of [" + resource + "]");
        }

        NodeSet nodes = new NodeSet(this.manager);
        Publication pub = resource.getStructure().getPublication();
        String area = resource.getStructure().getArea();
        SiteTree tree = getTree(map, pub, area);

        SiteTreeNodeImpl node = (SiteTreeNodeImpl) tree.getNode(resource.getPath());
        if (node != null) {
            List preOrder = node.preOrder();

            // remove original resource (does not require itself)
            preOrder.remove(0);

            for (int i = 0; i < preOrder.size(); i++) {
                SiteTreeNode descendant = (SiteTreeNode) preOrder.get(i);
                nodes.add(descendant);
            }

            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Obtaining requiring resources completed.");
            }
        }

        return nodes.getNodes();
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#contains(org.apache.lenya.cms.publication.Document)
     */
    public boolean contains(Document resource) throws SiteException {
        SiteTree tree = getTree(resource);
        return tree.containsByUuid(resource.getUUID(), resource.getLanguage());
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#containsInAnyLanguage(org.apache.lenya.cms.publication.Document)
     */
    public boolean containsInAnyLanguage(Document resource) throws SiteException {
        SiteTree tree = getTree(resource);
        return tree.containsInAnyLanguage(resource.getUUID());
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#copy(org.apache.lenya.cms.publication.Document,
     *      org.apache.lenya.cms.publication.Document)
     */
    public void copy(Document sourceDocument, Document destinationDocument) throws SiteException {
        DefaultSiteTree destinationTree = getTree(destinationDocument);

        try {
            SiteTreeNode sourceNode = (SiteTreeNode) sourceDocument.getLink().getNode();

            SiteTreeNode[] siblings = sourceNode.getNextSiblings();
            SiteNode parent = sourceNode.getParent();
            String parentId = "";
            if (parent != null) {
                parentId = parent.getPath();
            }
            SiteTreeNode sibling = null;
            String siblingPath = null;

            // same UUID -> insert at the same position
            if (sourceDocument.getUUID().equals(destinationDocument.getUUID())) {
                for (int i = 0; i < siblings.length; i++) {
                    String path = parentId + "/" + siblings[i].getName();
                    sibling = (SiteTreeNode) destinationTree.getNode(path);
                    if (sibling != null) {
                        siblingPath = path;
                        break;
                    }
                }
            }

            if (!sourceNode.hasLink(sourceDocument.getLanguage())) {
                // the node that we're trying to publish
                // doesn't have this language
                throw new SiteException("The node " + sourceDocument.getPath()
                        + " doesn't contain a label for language " + sourceDocument.getLanguage());
            }
            Link link = sourceNode.getLink(sourceDocument.getLanguage());
            SiteTreeNode destinationNode = (SiteTreeNode) destinationTree.getNode(destinationDocument.getPath());
            if (destinationNode == null) {
                if (siblingPath == null) {
                    destinationTree.addNode(destinationDocument.getPath(),
                            destinationDocument.getUUID(),
                            sourceNode.isVisible(),
                            sourceNode.getHref(),
                            sourceNode.getSuffix(),
                            sourceNode.hasLink());
                    destinationTree.addLabel(destinationDocument.getPath(),
                            destinationDocument.getLanguage(),
                            link.getLabel());
                } else {
                    destinationTree.addNode(destinationDocument.getPath(),
                            destinationDocument.getUUID(),
                            sourceNode.isVisible(),
                            sourceNode.getHref(),
                            sourceNode.getSuffix(),
                            sourceNode.hasLink(),
                            siblingPath);
                    destinationTree.addLabel(destinationDocument.getPath(),
                            destinationDocument.getLanguage(),
                            link.getLabel());
                }

            } else {
                // if the node already exists in the live
                // tree simply insert the label in the
                // live tree
                destinationDocument.getLink().setLabel(link.getLabel());
            }
        } catch (DocumentException e) {
            throw new SiteException(e);
        }

    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#setVisibleInNav(org.apache.lenya.cms.publication.Document,
     *      boolean)
     */
    public void setVisibleInNav(Document document, boolean visibleInNav) throws SiteException {
        SiteTree tree = getTree(document);
        try {
            tree.getNode(document.getPath()).setVisible(visibleInNav);
        } catch (DocumentException e) {
            throw new SiteException(e);
        }
    }

    /**
     * Returns the label object of a document.
     *
     * @param document The document.
     * @return A label.
     * @throws SiteException if an error occurs.
     */
    protected Link getLabelObject(Document document) throws SiteException {
        Link label = null;
        SiteTree siteTree = getTree(document);
        if (siteTree != null) {
            SiteTreeNode node = (SiteTreeNode) siteTree.getByUuid(document.getUUID(),
                    document.getLanguage()).getNode();
            if (node == null) {
                throw new SiteException("Node for document [" + document + "] does not exist!");
            }
            label = (Link) node.getLink(document.getLanguage());
        }

        if (label == null) {
            throw new SiteException("The label of document [" + document + "] is null!");
        }

        return label;
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getDocuments(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.publication.Publication, java.lang.String)
     */
    public Document[] getDocuments(DocumentFactory map, Publication publication, String area)
            throws SiteException {
        try {
            SiteTreeNodeImpl root = (SiteTreeNodeImpl) getTree(map, publication, area).getNode("/");
            List allNodes = root.preOrder();
            List documents = new ArrayList();

            for (int i = 1; i < allNodes.size(); i++) {
                SiteTreeNode node = (SiteTreeNode) allNodes.get(i);
                Document doc = map.get(publication, area, node.getUuid());
                String[] languages = doc.getLanguages();
                for (int l = 0; l < languages.length; l++) {
                    documents.add(doc.getTranslation(languages[l]));
                }
            }
            return (Document[]) documents.toArray(new Document[documents.size()]);
        } catch (Exception e) {
            throw new SiteException(e);
        }
    }

    public void add(String path, Document document) throws SiteException {

        if (contains(document)) {
            throw new SiteException("The document [" + document + "] is already contained!");
        }
        DefaultSiteTree tree = getTree(document);

        SiteTreeNode node;
        if (!tree.contains(path)) {
            // done for side effect of calling addNodNode, not the resulting return value
            node = tree.addNode(path, document.getUUID(), true, null, null, false);
        } else {
            node = (SiteTreeNode) tree.getNode(path);
            if (node.getUuid() != null) {
                ((SiteTreeNodeImpl) node).setUUID(document.getUUID());
            }
        }
        tree.addLabel(path, document.getLanguage(), "");
    }

    public void set(String path, Document document) throws SiteException {

        if (contains(document)) {
            throw new SiteException("The document [" + document + "] is already contained!");
        }
        DefaultSiteTree tree = getTree(document);
        SiteTreeNodeImpl node = (SiteTreeNodeImpl) tree.getNode(path);
        node.setUUID(document.getUUID());
        tree.changed();
    }

    /**
     * @param publication The publication.
     * @param area The area.
     * @return The key to store sitetree objects in the identity map.
     */
    protected String getKey(Publication publication, String area) {
        return publication.getId() + ":" + area;
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getSiteStructure(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.publication.Publication, java.lang.String)
     */
    public SiteStructure getSiteStructure(DocumentFactory map, Publication publiation, String area)
            throws SiteException {
        return getTree(map, publiation, area);
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getAvailableLocator(DocumentFactory,
     *      org.apache.lenya.cms.publication.DocumentLocator)
     */
    public DocumentLocator getAvailableLocator(DocumentFactory factory, DocumentLocator locator)
            throws SiteException {
        return DocumentLocator.getLocator(locator.getPublicationId(),
                locator.getArea(),
                computeUniquePath(factory, locator),
                locator.getLanguage());
    }

    /**
     * compute an unique document id
     * @param factory The factory.
     * @param locator The locator.
     * @return the unique documentid
     * @throws SiteException if an error occurs.
     */
    protected String computeUniquePath(DocumentFactory factory, DocumentLocator locator)
            throws SiteException {
        String path = locator.getPath();

        Publication pub;
        try {
            pub = factory.getPublication(locator.getPublicationId());
        } catch (PublicationException e) {
            throw new SiteException(e);
        }
        SiteTree tree = getTree(factory, pub, locator.getArea());

        String suffix = null;
        int version = 0;
        String idwithoutsuffix = null;

        if (tree.contains(path)) {
            int n = path.lastIndexOf("/");
            String lastToken = "";
            String substring = path;
            if ((n < path.length()) && (n > 0)) {
                lastToken = path.substring(n);
                substring = path.substring(0, n);
            }

            int l = lastToken.length();
            int index = lastToken.lastIndexOf("-");
            if (0 < index && index < l) {
                suffix = lastToken.substring(index + 1);
                idwithoutsuffix = substring + lastToken.substring(0, index);
                version = Integer.parseInt(suffix);
            } else {
                idwithoutsuffix = substring + lastToken;
            }

            while (tree.contains(path)) {
                version = version + 1;
                path = idwithoutsuffix + "-" + version;
            }
        }

        return path;
    }

    public boolean isVisibleInNav(Document document) throws SiteException {
        SiteTree tree = getTree(document);
        try {
            return tree.getNode(document.getPath()).isVisible();
        } catch (DocumentException e) {
            throw new SiteException(e);
        }
    }

    protected String getPath(DocumentFactory factory, Publication pub, String area, String uuid,
            String language) throws SiteException {
        SiteTree tree = getTree(factory, pub, area);
        SiteNode node = tree.getByUuid(uuid, language).getNode();
        if (node == null) {
            throw new SiteException("No node found for [" + pub.getId() + ":" + area + ":" + uuid
                    + ":" + language + "]");
        }
        return node.getPath();
    }

    protected String getUUID(DocumentFactory factory, Publication pub, String area, String path)
            throws SiteException {
        SiteTree tree = getTree(factory, pub, area);
        SiteNode node = tree.getNode(path);
        if (node == null) {
            throw new SiteException("No node found for [" + pub.getId() + ":" + area + ":" + path
                    + "]");
        }
        return node.getUuid();
    }

    protected boolean contains(DocumentFactory factory, DocumentLocator locator)
            throws SiteException {
        Publication pub;
        try {
            pub = factory.getPublication(locator.getPublicationId());
        } catch (PublicationException e) {
            throw new SiteException(e);
        }
        SiteTree tree = getTree(factory, pub, locator.getArea());
        if (tree.contains(locator.getPath())) {
            SiteNode node = tree.getNode(locator.getPath());
            return node.hasLink(locator.getLanguage());
        } else {
            return false;
        }
    }

}
TOP

Related Classes of org.apache.lenya.cms.site.tree.TreeSiteManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.