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

📄 a_cmsxmlcontent.java

📁 内容管理
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
* File   : $Source: /usr/local/cvs/opencms/src/com/opencms/template/A_CmsXmlContent.java,v $
* Date   : $Date: 2003/02/17 10:02:55 $
* Version: $Revision: 1.72 $
*
* This library is part of OpenCms -
* the Open Source Content Mananagement System
*
* Copyright (C) 2001  The OpenCms Group
*
* 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 OpenCms, please see the
* OpenCms 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 com.opencms.template;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import com.opencms.boot.I_CmsLogChannels;
import com.opencms.core.A_OpenCms;
import com.opencms.core.CmsException;
import com.opencms.file.CmsFile;
import com.opencms.file.CmsObject;
import com.opencms.workplace.I_CmsWpConstants;

/**
 * Abstract class for OpenCms files with XML content.
 * <P>
 * This class implements basic functionality for OpenCms XML files.
 * For each XML file content type (e.g. XML template files, XML
 * control files, XML news article files, ...) a customized
 * class extending this abstract class has to be implemented.
 * <P>
 * The functionality of this class is:
 * <UL>
 * <LI>control the XML parser</LI>
 * <LI>recognize and handle special XML tags used in OpenCms environment</LI>
 * <LI>cache parsed documents, so that that they can be re-used</LI>
 * <LI>provide methods to access XML data</LI>
 * </UL>
 * <P>
 * After creating a new instance of the children of this class it has to be
 * initialized by calling the init method.
 * <P>
 * While initializing the content of the given file will be read
 * and parsed with the XML parser. After this, the parsed
 * document will be scanned for INCLUDE tags and for DATA tags.
 * DATA tags will be stored in an internal Hashtable an can
 * easily be accessed by the getData methods or by a PROCESS tag.
 * <P>
 * Extending classes have to implement the abstract methods
 * getXmlDocumentTagName() and getContentDescription().
 *
 * @author Alexander Lucas
 * @version $Revision: 1.72 $ $Date: 2003/02/17 10:02:55 $
 */
public abstract class A_CmsXmlContent implements I_CmsXmlContent, I_CmsLogChannels {

    /** parameter types for XML node handling methods. */
    public static final Class[] C_PARAMTYPES_HANDLING_METHODS = new Class[] { Element.class, Object.class, Object.class };

    /** parameter types for user methods called by METHOD tags */
    public static final Class[] C_PARAMTYPES_USER_METHODS = new Class[] { CmsObject.class, String.class, A_CmsXmlContent.class, Object.class };

    /** The classname of the super XML content class */
    public static final String C_MINIMUM_CLASSNAME = "com.opencms.template.A_CmsXmlContent";

    /** Constant pathname, where to find templates */
    public static final String C_TEMPLATEPATH = "/system/workplace/templates/";

    /** Constant extension of the template-files. */
    public static final String C_TEMPLATE_EXTENSION = "";

    /** Error message for bad <code>&lt;PROCESS&gt;</code> tags */
    public static final String C_ERR_NODATABLOCK = "? UNKNOWN DATABLOCK ";

    /** CmsObject Object for accessing resources */
    protected CmsObject m_cms;

    /** All XML tags known by this class. */
    protected Vector m_knownTags = new Vector();

    /**
     * This Hashtable contains some XML tags as keys
     * and the corresponding methods as values.
     * Used to pass to processNode() to read in
     * include files and scan for datablocks.
     */
    protected Hashtable m_firstRunTags = new Hashtable();

    /**
     * This Hashtable contains some XML tags as keys
     * and the corresponding methods as values.
     * Used to pass to processNode() before generating
     * HTML output.
     */
    protected Hashtable m_mainProcessTags = new Hashtable();

    /** constant for registering handling tags */
    protected final static int C_REGISTER_FIRST_RUN = 1;

    /** constant for registering handling tags */
    protected final static int C_REGISTER_MAIN_RUN = 2;

    /** Boolean for additional debug output control */
    private static final boolean C_DEBUG = false;

    /** DOM representaion of the template content. */
    private Document m_content;

    /** Filename this template was read from */
    private String m_filename;

    /** All datablocks in DOM format */
    private Hashtable m_blocks = new Hashtable();

    /** Reference All included A_CmsXmlContents */
    private Vector m_includedTemplates = new Vector();

    /** Cache for parsed documents */
    static private Hashtable m_filecache = new Hashtable();

    /** XML parser */
    private static I_CmsXmlParser parser = new CmsXmlXercesParser();

    private String m_newEncoding = null;

    /** Constructor for creating a new instance of this class */
    public A_CmsXmlContent() {
        registerAllTags();
    }

    /**
     * Calls a user method in the object callingObject.
     * Every user method has to user the parameter types defined in
     * C_PARAMTYPES_USER_METHODS to be recognized by this method.
     *
     * @see #C_PARAMTYPES_USER_METHODS
     * @param methodName Name of the method to be called.
     * @param parameter Additional parameter passed to the method.
     * @param callingObject Reference to the object containing the called method.
     * @param userObj Customizable user object that will be passed through to the user method.
     * @param resolveMethods If true the methodtags will be resolved even if they have own CacheDirectives.
     * @throws CmsException
     */
    protected Object callUserMethod(String methodName, String parameter, Object callingObject, Object userObj, boolean resolveMethods) throws CmsException {
        Object[] params = new Object[] { m_cms, parameter, this, userObj };
        Object result = null;

        // Check if the user selected a object where to look for the user method.
        if (callingObject == null) {
            throwException("You are trying to call the user method \"" + methodName + "\" without giving an object containing this method. " + "Please select a callingObject in your getProcessedData or getProcessedDataValue call.", CmsException.C_XML_NO_USER_METHOD);
        }

        // check if the method has cachedirectives, if so we just return null
        // this way the methode tag stays in the Element and can be handled like
        // an normal element. We do this only if elementCache is active.
        if (m_cms.getRequestContext().isElementCacheEnabled() && !resolveMethods) {
            try {
                if (callingObject.getClass().getMethod("getMethodCacheDirectives", new Class[] { CmsObject.class, String.class }).invoke(callingObject, new Object[] { m_cms, methodName }) != null) {
                    return null;
                }
            }
            catch (NoSuchMethodException e) {
                throwException("Method getMethodeCacheDirectives was not found in class " + callingObject.getClass().getName() + ".", CmsException.C_XML_NO_USER_METHOD);
            }
            catch (InvocationTargetException targetEx) {

                // the method could be invoked, but throwed a exception
                // itself. Get this exception and throw it again.
                Throwable e = targetEx.getTargetException();
                if (!(e instanceof CmsException)) {
                    // Only print an error if this is NO CmsException
                    throwException("Method getMethodeCacheDirectives throwed an exception. " + e, CmsException.C_UNKNOWN_EXCEPTION);
                }
                else {
                    // This is a CmsException Error printing should be done previously.
                    throw (CmsException) e;
                }
            }
            catch (Exception exc2) {
                throwException("Method getMethodeCacheDirectives was found but could not be invoked. " + exc2, CmsException.C_XML_NO_USER_METHOD);
            }
        }

        // OK. We have a calling object. Now try to invoke the method
        try {
            // try to invoke the method 'methodName'
            result = getUserMethod(methodName, callingObject).invoke(callingObject, params);
        }
        catch (NoSuchMethodException exc) {
            throwException("User method " + methodName + " was not found in class " + callingObject.getClass().getName() + ".", CmsException.C_XML_NO_USER_METHOD);
        }
        catch (InvocationTargetException targetEx) {

            // the method could be invoked, but throwed a exception
            // itself. Get this exception and throw it again.
            Throwable e = targetEx.getTargetException();
            if (!(e instanceof CmsException)) {
                // Only print an error if this is NO CmsException
                throwException("User method " + methodName + " throwed an exception. " + e, CmsException.C_UNKNOWN_EXCEPTION);
            }
            else {
                // This is a CmsException
                // Error printing should be done previously.
                throw (CmsException) e;
            }
        }
        catch (Exception exc2) {
            throwException("User method " + methodName + " was found but could not be invoked. " + exc2, CmsException.C_XML_NO_USER_METHOD);
        }
        if ((result != null) && (!(result instanceof String || result instanceof CmsProcessedString || result instanceof Integer || result instanceof NodeList || result instanceof byte[]))) {
            throwException("User method " + methodName + " in class " + callingObject.getClass().getName() + " returned an unsupported Object: " + result.getClass().getName(), CmsException.C_XML_PROCESS_ERROR);
        }
        return (result);
    }

    /**
     * Deletes all files from the file cache.
     */
    public static void clearFileCache() {
        if (I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING && A_OpenCms.isLogging()) {
            A_OpenCms.log(C_OPENCMS_CACHE, "[A_CmsXmlContent] clearing XML file cache.");
        }
        m_filecache.clear();
    }

    /**
     * Deletes the file represented by the given A_CmsXmlContent from
     * the file cache.
     * @param doc A_CmsXmlContent representing the XML file to be deleted.
     */
    public static void clearFileCache(A_CmsXmlContent doc) {
        if (doc != null) {
            String currentProject = doc.m_cms.getRequestContext().currentProject().getName();
            m_filecache.remove(currentProject + ":" + doc.getAbsoluteFilename());
        }
    }

    /**
     * Deletes the file with the given key from the file cache.
     * If no such file exists nothing happens.
     * @param key Key of the template file to be removed from the cache.
     */
    public static void clearFileCache(String key) {
        m_filecache.remove(key);
    }

    /**
     * Creates a clone of this object.
     * @return cloned object.
     * @throws CloneNotSupportedException
     */
    public Object clone() throws CloneNotSupportedException {
        try {
            A_CmsXmlContent newDoc = (A_CmsXmlContent) getClass().newInstance();
            newDoc.init(m_cms, (Document) m_content.cloneNode(true), m_filename);
            return newDoc;
        }
        catch (Exception e) {
            if (I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING && A_OpenCms.isLogging()) {
                A_OpenCms.log(C_OPENCMS_CRITICAL, getClassName() + "Error while trying to clone object.");
                A_OpenCms.log(C_OPENCMS_CRITICAL, getClassName() + e);
            }
            throw new CloneNotSupportedException(e.toString());
        }
    }

    /**
     * Concats two datablock hashtables and returns the resulting one.
     *
     * @param data1 First datablock hashtable.
     * @param data2 Second datablock hashtable.
     * @return Concatenated data.

⌨️ 快捷键说明

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