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

📄 a_cmsxmlcontent.java

📁 OpenCms 是一个J2EE的产品
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     *
     * @param tag Key for this datablock.
     * @param data DOM element node for this datablock.
     */
    private void insertNewDatablock(String tag, Element data) {

        // First check, if this is an extended datablock
        // in <NAME1 name="name2>... format, that has to be inserted
        // as name1.name2
        String nameAttr = data.getAttribute("name");
        String workTag = null;
        if ((!data.getNodeName().toLowerCase().equals("data")) && nameAttr != null && (!"".equals(nameAttr))) {
            // this is an extended datablock
            workTag = tag.substring(0, tag.lastIndexOf("."));
        } else {
            workTag = tag;
        }
        // Import the node for later inserting
        Element importedNode = (Element) m_parser.importNode(m_content, data);

        // Check, if this is a simple datablock without hierarchy.
        if (workTag.indexOf(".") == -1) {
            // Fine. We can insert the new Datablock at the of the document
            m_content.getDocumentElement().appendChild(importedNode);
            m_blocks.put(tag, importedNode);
        } 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 (CmsLog.getLog(this).isDebugEnabled() && cachedDoc != null) {
            CmsLog.getLog(this).debug("Reused 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();
    }
    
    /**
     * 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 byte array to be parsed
     * @return parsed DOM document
     * @throws CmsException if something goes wrong
     */
    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.
     * @throws CmsException if something goes wrong
     */
    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 = m_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, CmsLegacyException.C_XML_PARSING_ERROR);
        }
        if (parsedDoc == null) {
            String errorMessage = "Unknown error. Parsed DOM document is null.";
            throwException(errorMessage, CmsLegacyException.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, CmsLegacyException.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.
     *
     * @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 if something goes wrong
     */
    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 if something goes wrong
     */
    protected void processNode(Node n, Hashtable keys, Method defaultMethod, Object callingObject, Object userObj) throws CmsException {
        processNode(n, keys, defaultMethod, callingObject, userObj, null);
    }

    /**
     * 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.
     * @param stream the output stream
     * @throws CmsException if something goes wrong
     */
    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;

        

⌨️ 快捷键说明

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