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