📄 a_cmsxmlcontent.java
字号:
/*
* File : $Source: /usr/local/cvs/opencms/src/com/opencms/template/A_CmsXmlContent.java,v $
* Date : $Date: 2001/12/07 14:21:41 $
* Version: $Revision: 1.53 $
*
* 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.*;
import java.util.*;
import java.lang.reflect.*;
import com.opencms.file.*;
import com.opencms.core.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import com.opencms.launcher.*;
// import com.sun.xml.*;
// import com.sun.xml.tree.*;
//import org.apache.xerces.*;
//import org.apache.xerces.dom.*;
//import org.apache.xerces.parsers.*;
/**
* 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.53 $ $Date: 2001/12/07 14:21:41 $
*/
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 static I_CmsXmlParser parser = new CmsXmlProjectXParser();
/** 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.
* @exception 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().currentUser().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.
* @exception 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -