⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 a_cmsxmlcontent.java

📁 内容管理
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        }
        else {
            // This is a hierachical datablock tag. We have to search for
            // an appropriate place to insert first.
            boolean found = false;
            String match = "." + workTag;
            int dotIndex = match.lastIndexOf(".");
            Vector newBlocks = new Vector();
            while ((!found) && (dotIndex > 1)) {
                match = match.substring(0, dotIndex);
                if (hasData(match.substring(1))) {
                    found = true;
                }
                else {
                    dotIndex = match.lastIndexOf(".");
                    newBlocks.addElement(match.substring(dotIndex + 1));
                }
            }
            // newBlocks now contains a (backward oriented) list
            // of all datablocks that have to be created, before
            // the new datablock named "tag" can be inserted.
            String datablockPrefix = "";
            if (found) {
                datablockPrefix = match.substring(1) + ".";
            }
            // number of new elements to be created
            int numNewBlocks = newBlocks.size();
            // used to create the required new elements
            Element newElem = null;
            // Contains the last existing Element in the hierarchy.
            Element lastElem = null;
            // now create the new elements backwards
            for (int i = numNewBlocks - 1; i >= 0; i--) {
                newElem = m_content.createElement("DATA");
                newElem.setAttribute("name", (String) newBlocks.elementAt(i));
                m_blocks.put(datablockPrefix + (String) newBlocks.elementAt(i), newElem);
                if (lastElem != null) {
                    lastElem.appendChild(newElem);
                }
                else {
                    lastElem = newElem;
                }
            }
            // Now all required parent datablocks are created.
            // Finally the given datablock can be inserted.
            if (lastElem != null) {
                lastElem.appendChild(importedNode);
            }
            else {
                lastElem = importedNode;
            }
            m_blocks.put(datablockPrefix + tag, importedNode);

            // lastElem now contains the hierarchical tree of all DATA tags to be
            // inserted.
            // If we have found an existing part of the hierarchy, get
            // this part and append the tree. If no part was found, append the
            // tree at the end of the document.
            if (found) {
                Element parent = (Element) m_blocks.get(match.substring(1));
                parent.appendChild(lastElem);
            }
            else {
                m_content.getDocumentElement().appendChild(lastElem);
            }
        }
    }

    /**
     * Reloads a previously cached parsed content.
     *
     * @param filename Absolute pathname of the file to look for.
     * @return DOM parsed document or null if the cached content was not found.
     */
    private Document loadCachedDocument(String filename) {
        Document cachedDoc = null;
        String currentProject = m_cms.getRequestContext().currentProject().getName();
        Document lookup = (Document) m_filecache.get(currentProject + ":" + filename);
        if (lookup != null) {
            try {
                //cachedDoc = lookup.cloneNode(true).getOwnerDocument();
                cachedDoc = (Document) lookup.cloneNode(true);
            }
            catch (Exception e) {
                lookup = null;
                cachedDoc = null;
            }
        }
        if (I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING && A_OpenCms.isLogging() && C_DEBUG && cachedDoc != null) {
            A_OpenCms.log(C_OPENCMS_DEBUG, getClassName() + "Re-used previously parsed XML file " + getFilename() + ".");
        }
        return cachedDoc;
    }

    /**
     * Generates a XML comment.
     * It's used to replace no longer needed DOM elements by a short XML comment
     *
     * @param n XML element containing the tag to be replaced <em>(unused)</em>.
     * @param callingObject Reference to the object requesting the node processing <em>(unused)</em>.
     * @param userObj Customizable user object that will be passed through to handling and user methods <em>(unused)</em>.
     * @return the generated XML comment.
     */
    private NodeList replaceTagByComment(Element n, Object callingObject, Object userObj) {
        Element tempNode = (Element) n.cloneNode(false);
        while (tempNode.hasChildNodes()) {
            tempNode.removeChild(tempNode.getFirstChild());
        }
        tempNode.appendChild(m_content.createComment("removed " + n.getNodeName()));
        return tempNode.getChildNodes();
    }
    
    protected Document parse(byte[] content) throws CmsException {
        return parse(new ByteArrayInputStream(content));
    }

    /**
     * Starts the XML parser with the content of the given CmsFile object.
     * After parsing the document it is scanned for INCLUDE and DATA tags
     * by calling processNode with m_firstRunParameters.
     *
     * @param content String to be parsed
     * @return Parsed DOM document.
     * @see #processNode
     * @see #firstRunParameters
     */
    protected Document parse(InputStream content) throws CmsException {
        Document parsedDoc = null;

        // First parse the String for XML Tags and
        // get a DOM representation of the document
        try {
            parsedDoc = parser.parse(content);
        }
        catch (Exception e) {
            // Error while parsing the document.
            // there ist nothing to do, we cannot go on.
            String errorMessage = "Cannot parse XML file \"" + getAbsoluteFilename() + "\". " + e;
            throwException(errorMessage, CmsException.C_XML_PARSING_ERROR);
        }
        if (parsedDoc == null) {
            String errorMessage = "Unknown error. Parsed DOM document is null.";
            throwException(errorMessage, CmsException.C_XML_PARSING_ERROR);
        }

        // Try to normalize the XML document.
        // We should not call the normalize() method in the usual way
        // here, since the DOM interface changed at this point between
        // Level 1 and Level 2.
        // It's better to lookup the normalize() method first using reflection
        // API and call it then. So we will get the appropriate method for the
        // currently used DOM level and avoid NoClassDefFound exceptions.
        try {
            Class elementClass = Class.forName("org.w3c.dom.Element");
            Method normalizeMethod = elementClass.getMethod("normalize", new Class[] {});
            normalizeMethod.invoke(parsedDoc.getDocumentElement(), new Object[] {});
        }
        catch (Exception e) {
            // The workaround using reflection API failed.
            // We have to throw an exception.
            throwException("Normalizing the XML document failed. Possibly you are using concurrent versions of " + "the XML parser with different DOM levels. ", e, CmsException.C_XML_PARSING_ERROR);
        }
        // Delete all unnecessary text nodes from the tree.
        // These nodes could cause errors when serializing this document otherwise
        Node loop = parsedDoc.getDocumentElement();
        while (loop != null) {
            Node next = treeWalker(parsedDoc.getDocumentElement(), loop);
            if (loop.getNodeType() == Node.TEXT_NODE) {
                Node leftSibling = loop.getPreviousSibling();
                Node rightSibling = loop.getNextSibling();
                if (leftSibling == null || rightSibling == null || (leftSibling.getNodeType() == Node.ELEMENT_NODE && rightSibling.getNodeType() == Node.ELEMENT_NODE)) {
                    if ("".equals(loop.getNodeValue().trim())) {
                        loop.getParentNode().removeChild(loop);
                    }
                }
            }
            loop = next;
        }
        return parsedDoc;
    }

    /**
     * Main processing funtion for the whole XML document.
     *
     * @see #processNode
     * @param keys Hashtable with XML tags to look for and corresponding methods.
     * @param defaultMethod Method to be called if the tag is unknown.
     * @param callingObject Reference to the object requesting the node processing.
     * @param userObj Customizable user object that will be passed through to handling and user methods.
     * @throws CmsException
     */
    protected void processDocument(Hashtable keys, Method defaultMethod, Object callingObject, Object userObj) throws CmsException {
        processNode(m_content.getDocumentElement(), keys, defaultMethod, callingObject, userObj);
    }

    /**
     * Universal main processing function for parsed XML templates.
     * The given node is processed by a tree walk.
     * <P>
     * Every XML tag will be looked up in the Hashtable "keys".
     * If a corresponding entry is found, the tag will be handled
     * by the corresponding function returned from the Hashtable.
     * <P>
     * If an unknown tag is detected the method defaultMethod is called
     * instead. Is defaultMethod == null nothing will be done with unknown tags.
     * <P>
     * The invoked handling methods are allowed to return null or objects
     * of the type String, Node, Integer or byte[].
     * If the return value is null, nothing happens. In all other cases
     * the handled node in the tree will be replaced by a new node.
     * The value of this new node depends on the type of the returned value.
     *
     * @param n Node with its subnodes to process
     * @param keys Hashtable with XML tags to look for and corresponding methods.
     * @param defaultMethod Method to be called if the tag is unknown.
     * @param callingObject Reference to the Object that requested the node processing.
     * @param userObj Customizable user object that will be passed to handling and user methods.
     * @throws CmsException
     */
    protected void processNode(Node n, Hashtable keys, Method defaultMethod, Object callingObject, Object userObj) throws CmsException {
        processNode(n, keys, defaultMethod, callingObject, userObj, null);
    }

    protected void processNode(Node n, Hashtable keys, Method defaultMethod, Object callingObject, Object userObj, OutputStream stream) throws CmsException {

        // Node currently processed
        Node child = null;

        // Name of the currently processed child
        String childName = null;

        // Node nextchild needed for the walk through the tree
        Node nextchild = null;

        // List of new Nodes the current node should be replaced with
        NodeList newnodes = null;

        // single new Node from newnodes
        Node insert = null;

        // tag processing method to be called for the current Node
        Method callMethod = null;

        // Object returned by the tag processing methods
        Object methodResult = null;

        // Used for streaming mode. Indicates, if the replaced results for the current node are already written to the stream.
        boolean newnodesAreAlreadyProcessed = false;

        // We should remember the starting node for walking through the tree.
        Node startingNode = n;

        // only start if there is something to process
        if (n != null && n.hasChildNodes()) {
            child = n.getFirstChild();
            while (child != null) {
                childName = child.getNodeName().toLowerCase();

                // Get the next node in the tree first
                nextchild = treeWalker(startingNode, child);

                // Only look for element nodes

                // all other nodes are not very interesting
                if (child.getNodeType() == Node.ELEMENT_NODE) {
                    newnodes = null;
                    callMethod = null;
                    newnodesAreAlreadyProcessed = false;
                    if (keys.containsKey(childName)) {

                        // name of this element found in keys Hashtable
                        callMethod = (Method) keys.get(childName);
                    }
                    else {
                        if (!m_knownTags.contains(childName)) {

                            // name was not found
                            // and even name is not known as tag
                            callMethod = defaultMethod;
                        }
                    }
                    if (callMethod != null) {
                        methodResult = null;
                        try {
                            if (C_DEBUG && I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING && A_OpenCms.isLogging()) {
                                A_OpenCms.log(C_OPENCMS_DEBUG, "<" + childName + "> tag found. Value: " + child.getNodeValue());
                                A_OpenCms.log(C_OPENCMS_DEBUG, "Tag will be handled by method [" + callMethod.getName() + "]. Invoking method NOW.");
                            }

                            // now invoke the tag processing method.
                            methodResult = callMethod.invoke(this, new Object[] { child, callingObject, userObj });
                        }
                        catch (Exception e) {
                            if (e instanceof InvocationTargetException) {
                                Throwable thrown = ((InvocationTargetException) e).getTargetException();

                                // if the method has thrown a cms exception then
                                // throw it again
                                if (thrown instanceof CmsException) {
                                    throw (CmsException) thrown;
                                }
                  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -