Skip to content

Commit

Permalink
Fix for issue alkacon#296 (Content-Definition with XSD: Wrong order f…
Browse files Browse the repository at this point in the history
…or choice elements after XSD change or saving in control code editor)
  • Loading branch information
kaiwidmann committed Feb 11, 2015
1 parent 0f5f7c9 commit 090e2c7
Showing 1 changed file with 48 additions and 31 deletions.
79 changes: 48 additions & 31 deletions src/org/opencms/xml/A_CmsXmlDocument.java
Original file line number Diff line number Diff line change
Expand Up @@ -284,40 +284,23 @@ public CmsFile correctXmlStructure(CmsObject cms) throws CmsXmlException {

// step 1: first sort the nodes according to the schema, this takes care of re-ordered elements
List<List<Element>> nodeLists = new ArrayList<List<Element>>();
for (I_CmsXmlSchemaType type : cd.getTypeSequence()) {
List<Element> elements = CmsXmlGenericWrapper.elements(root, type.getName());
int maxOccures = cd.getChoiceMaxOccurs() > 0
? cd.getChoiceMaxOccurs()
: type.getMaxOccurs();
if (elements.size() > maxOccures) {
if (type.getTypeName().equals(CmsXmlCategoryValue.TYPE_NAME)) {
if (type.getMaxOccurs() == 1) {
Element category = elements.get(0);
List<Element> categories = new ArrayList<Element>();
for (Element value : elements) {
@SuppressWarnings("unchecked")
Iterator<Element> itLink = value.elementIterator();
while (itLink.hasNext()) {
Element link = itLink.next();
categories.add((Element)link.clone());
}
}
category.clearContent();
for (Element value : categories) {
category.add(value);
}
}
boolean isMultipleChoice = cd.getSequenceType() == CmsXmlContentDefinition.SequenceType.MULTIPLE_CHOICE;

}

// to many nodes of this type appear according to the current schema definition
for (int lo = (elements.size() - 1); lo >= type.getMaxOccurs(); lo--) {
elements.remove(lo);
}

}
// if it's a multiple choice element, the child elements must not be sorted into their types,
// but must keep their original order
if (isMultipleChoice) {
List<Element> elements = CmsXmlGenericWrapper.elements(root);
checkMaxOccurs(elements, cd.getChoiceMaxOccurs(), cd.getTypeName());
nodeLists.add(elements);
}
// if it's a sequence, the children are sorted according to the sequence type definition
else {
for (I_CmsXmlSchemaType type : cd.getTypeSequence()) {
List<Element> elements = CmsXmlGenericWrapper.elements(root, type.getName());
checkMaxOccurs(elements, type.getMaxOccurs(), type.getTypeName());
nodeLists.add(elements);
}
}

// step 2: clear the list of nodes (this will remove all invalid nodes)
List<Element> nodeList = CmsXmlGenericWrapper.elements(root);
Expand Down Expand Up @@ -345,6 +328,40 @@ public CmsFile correctXmlStructure(CmsObject cms) throws CmsXmlException {
return m_file;
}

/**
* Removes all nodes that exceed newly defined maxOccurs rules from the list of elements
* @param cd the content type definition
* @param maxOccurs maximum number of elements allowed
* @param typeName name of the element type
*/
private void checkMaxOccurs(List<Element> elements, int maxOccurs, String typeName) {
if (elements.size() > maxOccurs) {
if (typeName.equals(CmsXmlCategoryValue.TYPE_NAME)) {
if (maxOccurs == 1) {
Element category = elements.get(0);
List<Element> categories = new ArrayList<Element>();
for (Element value : elements) {
@SuppressWarnings("unchecked")
Iterator<Element> itLink = value.elementIterator();
while (itLink.hasNext()) {
Element link = itLink.next();
categories.add((Element)link.clone());
}
}
category.clearContent();
for (Element value : categories) {
category.add(value);
}
}
}

// too many nodes of this type appear according to the current schema definition
for (int lo = (elements.size() - 1); lo >= maxOccurs; lo--) {
elements.remove(lo);
}
}
}

/**
* @see org.opencms.xml.I_CmsXmlDocument#getBestMatchingLocale(java.util.Locale)
*/
Expand Down

0 comments on commit 090e2c7

Please sign in to comment.