📄 a_cmsxmlcontent.java
字号:
/*
* 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><PROCESS></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 + -