AbstractParentNode.java :  » Content-Management-System » daisy » org » outerj » daisy » navigation » impl » Java Open Source

Java Open Source » Content Management System » daisy 
daisy » org » outerj » daisy » navigation » impl » AbstractParentNode.java
/*
 * Copyright 2004 Outerthought bvba and Schaubroeck nv
 *
 * Licensed 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.outerj.daisy.navigation.impl;

import org.outerj.daisy.repository.VariantKey;
import org.outerj.daisy.repository.RepositoryException;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

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

public abstract class AbstractParentNode implements Node {
    protected final List<Node> children = new ArrayList<Node>();
    protected int position;

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }

    public void add(Node node) {
        children.add(node);
        node.setPosition(children.size());
    }

    public List<Node> getChildren() {
        return children;
    }

    public void searchPath(String[] path, int pos, long branchId, long languageId, Node[] foundPath) throws RepositoryException {
        for (Node node : getChildren()) {
            if (node.isIdentifiable()) {
                // branch and language should only be checked for the last part of the path,
                // since those only apply to that specific document node (if it is a document node)
                long checkBranchId = pos == path.length - 1 ? branchId : -1;
                long checkLanguageId = pos == path.length -1 ? languageId : -1;
                if (node.isIdentifiable() && node.checkId(path[pos], checkBranchId, checkLanguageId)) {
                    foundPath[pos] = node;
                    if (pos != path.length - 1) {
                        node.searchPath(path, pos + 1, branchId, languageId, foundPath);
                    }
                    return;
                }
            }
        }
    }

    public List<Node> searchDocument(VariantKey key) throws RepositoryException {
        for (Node node : getChildren()) {
            List<Node> foundNodePath = node.searchDocument(key);
            if (foundNodePath != null) {
                if (isIdentifiable())
                    foundNodePath.add(this);
                return foundNodePath;
            }
        }
        return null;
    }

    public void populateNodeLookupMap(Map<VariantKey, String> map, String path) throws RepositoryException {
        for (Node node : getChildren()) {
            node.populateNodeLookupMap(map, path);
        }
    }

    public void generateChildXml(final ContentHandler contentHandler, final Node[] activeNodePath, final int pos,
            final int depth, final String path, final long userId, final long[] roleIds,
            final NavigationValueFormatter valueFormatter, final boolean includeChildCounts) throws RepositoryException, SAXException {
        int parentPos = pos - 1;
        if (pos < depth || (activeNodePath != null && parentPos < activeNodePath.length && activeNodePath[parentPos] == this)) {
            generateChildNodes(new NodeGenerator() {
                public boolean generate(Node node) throws RepositoryException, SAXException {
                    return node.generateXml(contentHandler, activeNodePath, pos, depth, path, userId, roleIds, valueFormatter, includeChildCounts);
                }
            }, userId, roleIds);
        }
    }

    private static interface NodeGenerator {
        boolean generate(Node node) throws RepositoryException, SAXException;
    }

    private void generateChildNodes(NodeGenerator nodeGenerator, long userId, long[] roleIds) throws SAXException, RepositoryException {
        // This method performs some action for each of the child nodes, except for unwanted
        // separator nodes, which are:
        //  - separator nodes as first and last child of its parent node
        //  - multiple separator nodes without any other visible nodes in between them

        boolean previousIsSeparator = false;
        int childCount = children.size();
        for (int i = 0; i < childCount; i++) {
            Node node = children.get(i);
            boolean isSeparator = node instanceof SeparatorNode;
            boolean visible = false;
            boolean showNode = true;

            if (isSeparator) {
                if (i == 0 || previousIsSeparator) {
                    showNode = false;
                } else {
                    boolean otherNodeFound = false;
                    for (int k = i + 1; k < childCount; k++) {
                        if (children.get(k).isVisible(userId, roleIds, null, -1)) {
                            otherNodeFound = true;
                            break;
                        }
                    }
                    showNode = otherNodeFound;
                }
            }

            if (showNode) {
                visible = nodeGenerator.generate(node);
            }

            if (isSeparator || visible) {
                previousIsSeparator = isSeparator;
            }
        }
    }

    public String getId() {
        throw new UnsupportedOperationException();
    }

    public String findFirstDocumentNode(String path, long userId, long[] roleIds) throws RepositoryException {
        for (Node child : getChildren()) {
            boolean representsDocument = child instanceof DocumentNode;
            if (representsDocument && child.isVisible(userId, roleIds, null, -1)) {
                return path + "/" + child.getId();
            } else if (!representsDocument) {
                String node = child.findFirstDocumentNode(path + "/" + child.getId(), userId, roleIds);
                if (node != null)
                    return node;
            }
        }
        return null;
    }

    protected int[] getChildCounts(long userId, long[] roleIds, Node[] activeNodePath, int activeNodePathPos) throws RepositoryException {
        int visibleChildCount = 0;
        int totalChildCount = 0;
        List<Node> children = getChildren();
        for (Node child : children) {
            boolean[] visAndEx = child.getVisibleAndExists(userId, roleIds, activeNodePath, activeNodePathPos);
            if (visAndEx[0])
                visibleChildCount++;
            if (visAndEx[1])
                totalChildCount++;
        }
        return new int[] { visibleChildCount, totalChildCount };
    }

    protected void addChildCountAttrs(AttributesImpl attrs, long userId, long[] roleIds, Node[] activeNodePath, int activeNodePathPos) throws RepositoryException {
        int[] counts = getChildCounts(userId, roleIds, activeNodePath, activeNodePathPos);
        attrs.addAttribute("", "visibleChildCount", "visibleChildCount", "CDATA", String.valueOf(counts[0]));
        attrs.addAttribute("", "childCount", "childCount", "CDATA", String.valueOf(counts[1]));
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.