📄 cmsxmlcontent.java
字号:
* @return the value sequence for the selected element name in this XML content
*/
public CmsXmlContentValueSequence getValueSequence(String name, Locale locale) {
I_CmsXmlSchemaType type = m_contentDefinition.getSchemaType(name);
if (type == null) {
return null;
}
return new CmsXmlContentValueSequence(name, type, locale, this);
}
/**
* Removes an existing XML content value of the given element name and locale at the given index position
* from this XML content document.<p>
*
* @param name the name of the XML content value element
* @param locale the locale where to remove the value
* @param index the index where to remove the value (relative to all other values of this type)
*/
public void removeValue(String name, Locale locale, int index) {
// first get the value from the selected locale and index
I_CmsXmlContentValue value = getValue(name, locale, index);
// check for the min / max occurs constrains
List values = getValues(name, locale);
if (values.size() <= value.getMinOccurs()) {
// must not allow removing an element if min occurs would be violated
throw new CmsRuntimeException(Messages.get().container(
Messages.ERR_XMLCONTENT_ELEM_MINOCCURS_2,
name,
new Integer(value.getMinOccurs())));
}
// detach the value node from the XML document
value.getElement().detach();
// re-initialize this XML content
initDocument(m_document, m_encoding, m_contentDefinition);
}
/**
* Resolves the mappings for all values of this XML content.<p>
*
* @param cms the current users OpenCms context
*/
public void resolveMappings(CmsObject cms) {
// iterate through all initialized value nodes in this XML content
CmsXmlContentMappingVisitor visitor = new CmsXmlContentMappingVisitor(cms, this);
visitAllValuesWith(visitor);
}
/**
* @see org.opencms.xml.I_CmsXmlDocument#validate(org.opencms.file.CmsObject)
*/
public CmsXmlContentErrorHandler validate(CmsObject cms) {
// iterate through all initialized value nodes in this XML content
CmsXmlContentValidationVisitor visitor = new CmsXmlContentValidationVisitor(cms);
visitAllValuesWith(visitor);
return visitor.getErrorHandler();
}
/**
* Visists all values of this XML content with the given value visitor.<p>
*
* Please note that the order in which the values are visited may NOT be the
* order they apper in the XML document. It is ensured that the the parent
* of a nested value is visited before the element it contains.<p>
*
* @param visitor the value visitor implementation to visit the values with
*/
public void visitAllValuesWith(I_CmsXmlContentValueVisitor visitor) {
List bookmarks = new ArrayList(getBookmarks());
Collections.sort(bookmarks);
for (int i = 0; i < bookmarks.size(); i++) {
String key = (String)bookmarks.get(i);
I_CmsXmlContentValue value = (I_CmsXmlContentValue)getBookmark(key);
visitor.visit(value);
}
}
/**
* @see org.opencms.xml.A_CmsXmlDocument#getBookmark(java.lang.String)
*/
protected Object getBookmark(String bookmark) {
// allows package classes to directly access the bookmark information of the XML content
return super.getBookmark(bookmark);
}
/**
* @see org.opencms.xml.A_CmsXmlDocument#getBookmarks()
*/
protected Set getBookmarks() {
// allows package classes to directly access the bookmark information of the XML content
return super.getBookmarks();
}
/**
* Returns the XML root element node for the given locale.<p>
*
* @param locale the locale to get the root element for
*
* @return the XML root element node for the given locale
*
* @throws CmsRuntimeException if no language element is found in the document
*/
protected Element getLocaleNode(Locale locale) throws CmsRuntimeException {
String localeStr = locale.toString();
Iterator i = m_document.getRootElement().elements().iterator();
while (i.hasNext()) {
Element element = (Element)i.next();
if (localeStr.equals(element.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE))) {
// language element found, return it
return element;
}
}
// language element was not found
throw new CmsRuntimeException(Messages.get().container(Messages.ERR_XMLCONTENT_MISSING_LOCALE_1, locale));
}
/**
* @see org.opencms.xml.A_CmsXmlDocument#initDocument(org.dom4j.Document, java.lang.String, org.opencms.xml.CmsXmlContentDefinition)
*/
protected void initDocument(Document document, String encoding, CmsXmlContentDefinition definition) {
m_document = document;
m_contentDefinition = definition;
m_encoding = CmsEncoder.lookupEncoding(encoding, encoding);
m_elementLocales = new HashMap();
m_elementNames = new HashMap();
m_locales = new HashSet();
clearBookmarks();
// initialize the bookmarks
for (Iterator i = m_document.getRootElement().elementIterator(); i.hasNext();) {
Element node = (Element)i.next();
try {
Locale locale = CmsLocaleManager.getLocale(node.attribute(
CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE).getValue());
addLocale(locale);
processSchemaNode(node, null, locale, definition);
} catch (NullPointerException e) {
LOG.error(Messages.get().getBundle().key(Messages.LOG_XMLCONTENT_INIT_BOOKMARKS_0), e);
}
}
}
/**
* Sets the file this XML content is written to.<p>
*
* @param file the file this XML content content is written to
*/
protected void setFile(CmsFile file) {
m_file = file;
}
/**
* Adds a new XML schema type with the default value to the given parent node.<p>
*
* @param cms the cms context
* @param parent the XML parent element to add the new value to
* @param type the type of the value to add
* @param locale the locale to add the new value for
* @param insertIndex the index in the XML document where to add the XML node
*
* @return the created XML content value
*/
private I_CmsXmlContentValue addValue(
CmsObject cms,
Element parent,
I_CmsXmlSchemaType type,
Locale locale,
int insertIndex) {
// first generate the XML element for the new value
Element element = type.generateXml(cms, this, parent, locale);
// detatch the XML element from the appended position in order to insert it at the required position
element.detach();
// add the XML element at the required position in the parent XML node
parent.content().add(insertIndex, element);
// create the type and return it
I_CmsXmlContentValue value = type.createValue(this, element, locale);
// generate the default value again - required for nested mappings because only now the full path is available
String defaultValue = m_contentDefinition.getContentHandler().getDefault(cms, value, locale);
if (defaultValue != null) {
// only if there is a default value available use it to overwrite the initial default
value.setStringValue(cms, defaultValue);
}
// finally return the value
return value;
}
/**
* Returns the content definition object for this xml content object.<p>
*
* @param resolver the XML entity resolver to use, required for VFS access
*
* @return the content definition object for this xml content object
*
* @throws CmsRuntimeException if the schema location attribute (<code>systemId</code>)cannot be found,
* parsing of the schema fails, an underlying IOException occurs or unmarshalling fails
*
*/
private CmsXmlContentDefinition getContentDefinition(EntityResolver resolver) throws CmsRuntimeException {
String schemaLocation = m_document.getRootElement().attributeValue(
I_CmsXmlSchemaType.XSI_NAMESPACE_ATTRIBUTE_NO_SCHEMA_LOCATION);
// Note regarding exception handling:
// Since this object already is a valid XML content object,
// it must have a valid schema, otherwise it would not exist.
// Therefore the exceptions should never be really thrown.
if (schemaLocation == null) {
throw new CmsRuntimeException(Messages.get().container(Messages.ERR_XMLCONTENT_MISSING_SCHEMA_0));
}
try {
return CmsXmlContentDefinition.unmarshal(schemaLocation, resolver);
} catch (SAXException e) {
throw new CmsRuntimeException(Messages.get().container(Messages.ERR_XML_SCHEMA_PARSE_0), e);
} catch (IOException e) {
throw new CmsRuntimeException(Messages.get().container(Messages.ERR_XML_SCHEMA_IO_0), e);
} catch (CmsXmlException e) {
throw new CmsRuntimeException(Messages.get().container(Messages.ERR_XMLCONTENT_UNMARSHAL_0), e);
}
}
/**
* Processes a document node and extracts the values of the node according to the provided XML
* content definition.<p>
*
* @param root the root node element to process
* @param rootPath the Xpath of the root node in the document
* @param locale the locale
* @param definition the XML content definition to use for processing the values
*/
private void processSchemaNode(Element root, String rootPath, Locale locale, CmsXmlContentDefinition definition) {
int count = 1;
String previousName = null;
// first remove all non-element node (i.e. white space text nodes)
List content = root.content();
for (int i = content.size() - 1; i >= 0; i--) {
Node node = (Node)content.get(i);
if (!(node instanceof Element)) {
// this node is not an element, so it must be a white space text node, remove it
content.remove(i);
}
}
// iterate all elements again
for (Iterator i = root.content().iterator(); i.hasNext();) {
// node must be an element since all non-elements were removed
Element element = (Element)i.next();
// check if this is a new node, if so reset the node counter
String name = element.getName();
if ((previousName == null) || !previousName.equals(name)) {
previousName = name;
count = 1;
}
// build the Xpath expression for the current node
String path;
if (rootPath != null) {
StringBuffer b = new StringBuffer(rootPath.length() + name.length() + 6);
b.append(rootPath);
b.append('/');
b.append(CmsXmlUtils.createXpathElement(name, count));
path = b.toString();
} else {
path = CmsXmlUtils.createXpathElement(name, count);
}
// create a XML content value element
I_CmsXmlSchemaType schemaType = definition.getSchemaType(name);
if (schemaType != null) {
// directly add simple type to schema
I_CmsXmlContentValue value = schemaType.createValue(this, element, locale);
addBookmark(path, locale, true, value);
if (!schemaType.isSimpleType()) {
// recurse for nested schema
CmsXmlNestedContentDefinition nestedSchema = (CmsXmlNestedContentDefinition)schemaType;
processSchemaNode(element, path, locale, nestedSchema.getNestedContentDefinition());
}
} else {
// unknown XML node name according to schema
if (LOG.isWarnEnabled()) {
LOG.warn(Messages.get().getBundle().key(
Messages.LOG_XMLCONTENT_INVALID_ELEM_2,
name,
definition.getSchemaLocation()));
}
}
// increase the node counter
count++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -