📄 a_cmsxmldocument.java
字号:
/*
* File : $Source: /usr/local/cvs/opencms/src/org/opencms/xml/A_CmsXmlDocument.java,v $
* Date : $Date: 2006/04/28 15:20:52 $
* Version: $Revision: 1.31 $
*
* This library is part of OpenCms -
* the Open Source Content Mananagement System
*
* Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
*
* 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 Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project 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 org.opencms.xml;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.main.CmsIllegalArgumentException;
import org.opencms.main.CmsRuntimeException;
import org.opencms.xml.types.I_CmsXmlContentValue;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.Element;
import org.xml.sax.EntityResolver;
/**
* Provides basic XML document handling functions useful when dealing
* with XML documents that are stored in the OpenCms VFS.<p>
*
* @author Alexander Kandzior
*
* @version $Revision: 1.31 $
*
* @since 6.0.0
*/
public abstract class A_CmsXmlDocument implements I_CmsXmlDocument {
/** The content conversion to use for this xml document. */
protected String m_conversion;
/** The document object of the document. */
protected Document m_document;
/** Maps element names to available locales. */
protected Map m_elementLocales;
/** Maps locales to avaliable element names. */
protected Map m_elementNames;
/** The encoding to use for this xml document. */
protected String m_encoding;
/** The file that contains the document data (note: is not set when creating an empty or document based document). */
protected CmsFile m_file;
/** Set of locales contained in this document. */
protected Set m_locales;
/** Reference for named elements in the document. */
private Map m_bookmarks;
/**
* Default constructor for a XML document
* that initializes some internal values.<p>
*/
protected A_CmsXmlDocument() {
m_bookmarks = new HashMap();
m_locales = new HashSet();
}
/**
* Creates the bookmark name for a localized element to be used in the bookmark lookup table.<p>
*
* @param name the element name
* @param locale the element locale
* @return the bookmark name for a localized element
*/
protected static final String getBookmarkName(String name, Locale locale) {
StringBuffer result = new StringBuffer(64);
result.append('/');
result.append(locale.toString());
result.append('/');
result.append(name);
return result.toString();
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#copyLocale(java.util.Locale, java.util.Locale)
*/
public void copyLocale(Locale source, Locale destination) throws CmsXmlException {
if (!hasLocale(source)) {
throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_NOT_AVAILABLE_1, source));
}
if (hasLocale(destination)) {
throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_ALREADY_EXISTS_1, destination));
}
Element sourceElement = null;
Element rootNode = m_document.getRootElement();
Iterator i = rootNode.elementIterator();
String localeStr = source.toString();
while (i.hasNext()) {
Element element = (Element)i.next();
String language = element.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE, null);
if ((language != null) && (localeStr.equals(language))) {
// detach node with the locale
sourceElement = element.createCopy();
// there can be only one node for the locale
break;
}
}
if (sourceElement == null) {
// should not happen since this was checked already, just to make sure...
throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_NOT_AVAILABLE_1, source));
}
// switch locale value in attribute of copied node
sourceElement.addAttribute(CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE, destination.toString());
// attach the copied node to the root node
rootNode.add(sourceElement);
// re-initialize the document bookmarks
initDocument(m_document, m_encoding, getContentDefinition());
}
/**
* Corrects the structure of this XML content.<p>
*
* @param cms the current cms object
* @return the file that contains the corrected XML structure
*
* @throws CmsXmlException if something goes wrong
*/
public CmsFile correctXmlStructure(CmsObject cms) throws CmsXmlException {
// iterate over all locales
Iterator i = m_locales.iterator();
while (i.hasNext()) {
Locale locale = (Locale)i.next();
List names = getNames(locale);
// iterate over all nodes per language
Iterator j = names.iterator();
while (j.hasNext()) {
// this step is required for values that need a processing of their content
// an example for this is the HTML value that does link replacement
String name = (String)j.next();
I_CmsXmlContentValue value = getValue(name, locale);
if (value.isSimpleType()) {
String content = value.getStringValue(cms);
value.setStringValue(cms, content);
}
}
}
// write the modifed xml back to the VFS file
m_file.setContents(marshal());
return m_file;
}
/**
* Returns the content converison used for the page content.<p>
*
* @return the content converison used for the page content
*/
public String getConversion() {
return m_conversion;
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getEncoding()
*/
public String getEncoding() {
return m_encoding;
}
/**
* Returns the file with the xml page content or <code>null</code> if not set.<p>
*
* @return the file with the xml page content
*/
public CmsFile getFile() {
return m_file;
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getIndexCount(java.lang.String, java.util.Locale)
*/
public int getIndexCount(String name, Locale locale) {
List elements = getValues(name, locale);
if (elements == null) {
return 0;
} else {
return elements.size();
}
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getLocales()
*/
public List getLocales() {
return new ArrayList(m_locales);
}
/**
* Returns a List of all locales that have the named element set in this document.<p>
*
* If no locale for the given element name is available, an empty list is returned.<p>
*
* @param name the element to look up the locale List for
* @return a List of all Locales that have the named element set in this document
*/
public List getLocales(String name) {
Object result = m_elementLocales.get(CmsXmlUtils.createXpath(name, 1));
if (result == null) {
return Collections.EMPTY_LIST;
}
return new ArrayList((Set)result);
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getNames(java.util.Locale)
*/
public List getNames(Locale locale) {
Object o = m_elementNames.get(locale);
if (o != null) {
return new ArrayList((Set)o);
}
return Collections.EMPTY_LIST;
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getStringValue(org.opencms.file.CmsObject, java.lang.String, java.util.Locale)
*/
public String getStringValue(CmsObject cms, String name, Locale locale) {
I_CmsXmlContentValue value = getValueInternal(CmsXmlUtils.createXpath(name, 1), locale);
if (value != null) {
return value.getStringValue(cms);
}
return null;
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getStringValue(CmsObject, java.lang.String, Locale, int)
*/
public String getStringValue(CmsObject cms, String name, Locale locale, int index) {
// directly calling getValueInternal() is more efficient then calling getStringValue(CmsObject, String, Locale)
// since the most costs are generated in resolving the Xpath name
I_CmsXmlContentValue value = getValueInternal(CmsXmlUtils.createXpath(name, index + 1), locale);
if (value != null) {
return value.getStringValue(cms);
}
return null;
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getValue(java.lang.String, java.util.Locale)
*/
public I_CmsXmlContentValue getValue(String name, Locale locale) {
return getValueInternal(CmsXmlUtils.createXpath(name, 1), locale);
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getValue(java.lang.String, java.util.Locale, int)
*/
public I_CmsXmlContentValue getValue(String name, Locale locale, int index) {
return getValueInternal(CmsXmlUtils.createXpath(name, index + 1), locale);
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#getValues(java.util.Locale)
*/
public List getValues(Locale locale) {
List result = new ArrayList();
// bookmarks are stored with the locale as first prefix
String prefix = '/' + locale.toString() + '/';
// it's better for performance to iterate through the list of bookmarks directly
Iterator i = m_bookmarks.keySet().iterator();
while (i.hasNext()) {
String key = (String)i.next();
if (key.startsWith(prefix)) {
result.add(m_bookmarks.get(key));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -