Author: pierre Date: 2010-01-12 16:40:27 +0100 (Tue, 12 Jan 2010) New Revision: 40534
Modified: mmbase/trunk/core/src/main/java/org/mmbase/util/xml/AbstractBuilderReader.java mmbase/trunk/core/src/main/java/org/mmbase/util/xml/resources/builder.xsd Log: MMB-1907 Modified: mmbase/trunk/core/src/main/java/org/mmbase/util/xml/AbstractBuilderReader.java =================================================================== --- mmbase/trunk/core/src/main/java/org/mmbase/util/xml/AbstractBuilderReader.java 2010-01-12 15:35:47 UTC (rev 40533) +++ mmbase/trunk/core/src/main/java/org/mmbase/util/xml/AbstractBuilderReader.java 2010-01-12 15:40:27 UTC (rev 40534) @@ -152,34 +152,88 @@ } } - for (String list : new String[] {"names", "descriptions", "properties"}) { - // if these are found, simply all sub-elements must be added. + // add and replace names and descriptions, identified by xml:lang + mergeElementLists(doc, overrides, "names", "singular", "xml:lang", true); + mergeElementLists(doc, overrides, "names", "plural", "xml:lang", true); + mergeElementLists(doc, overrides, "descriptions", "description", "xml:lang", true); - List<Element> elementList = getChildElements(doc.getDocumentElement(), list); - Element element; - if (elementList.size() == 0) { - element = doc.createElement(list); - doc.getDocumentElement().appendChild(element); - } else { - element = elementList.get(elementList.size() - 1); - } - for (Element overridesList : getChildElements(overrides.getDocumentElement(), list)) { - for (Element e : getChildElements(overridesList, "*")) { - Element newE = (Element) doc.importNode(e, true); - element.appendChild(newE); - } - } - } + // add and replace properties, identified by name + mergeElementLists(doc, overrides, "properties", "property", "name", true); - for (String list : new String[] {"fieldlist", "functionlist", "indexlist"}) { - // if these are found, they simply must be added too. + // add and merge fields, functions, and indices, identified by name + // (or replace them if the override attribute is set to replace) + mergeElementLists(doc, overrides, "fieldlist", "field", "name", false); + mergeElementLists(doc, overrides, "functionlist", "function", "name", false); + mergeElementLists(doc, overrides, "indexlist", "index", "name", false); - for(Element el : getChildElements(overrides.getDocumentElement(), list)) { + } + + /** + * Copy a list of elements, identified by an attribute, from overrides to doc. + * Replace or merge those elements if they already exist in doc under that attribute. + * Merging an element means either adding or replacing the sub tags of that element. + * @param doc The receiving builder xml document. This one will be changed. + * @param overrides The builder xml document that provided overriding information. This one will only + * be read. + * @param list The tagname of list element(s) containign the items + * @param item The tagname of the list item element + * @param attr The attribute identifying the item (i.e. "name" or "xml:lang") + * @param replace if <code>true</code>, the item is entirely replaced. If <code>false</code>, it is merged. + * @since MMBase-1.9 + */ + protected static void mergeElementLists(Document doc, Document overrides, String list, String item, String attr, boolean replace) { + Element docListEl = getElementByPath(doc.getDocumentElement(), "builder." + list); + for (Element listEl : getChildElements(overrides.getDocumentElement(), list)) { + for (Element el : getChildElements(listEl, item)) { + if (docListEl == null) { + docListEl = doc.createElement(list); + doc.getDocumentElement().appendChild(docListEl); + } Element newEl = (Element) doc.importNode(el, true); - doc.getDocumentElement().appendChild(newEl); + String name = newEl.getAttribute(attr); + // determine if an item should be replaced or merged + boolean replaceItem = replace; + String replaceAttr = newEl.getAttribute("override"); + if (replaceAttr != null) { + replaceItem = replaceAttr.equals("replace"); + } + Element docEl = null; + if (name != null && !(name.equals(""))) { + for(Element orgListEl : getChildElements(doc.getDocumentElement(), list)) { + for(Element orgEl : getChildElements(docListEl, item)) { + if (name.equals(orgEl.getAttribute(attr))) { + docListEl = orgListEl; + docEl = orgEl; + break; + } + } + } + } + if (docEl != null) { + if (replaceItem) { // replace an item + docListEl.replaceChild(newEl, docEl); + } else { // merge an item (iow add and or replace subtags) + // merge attributes + NamedNodeMap attributes = newEl.getAttributes(); + for (int i = 0; i < attributes.getLength(); i++) { + Attr attribute = (Attr) (attributes.item(i).cloneNode(true)); + docEl.setAttributeNode(attribute); + } + // merge element tags + for (Element newFel : getChildElements(newEl)) { + Element docFel = getElementByPath(docEl, "field." + newFel.getLocalName()); + if (docFel != null) { + docEl.replaceChild(newFel,docFel); + } else { + docEl.appendChild(newFel); + } + } + } + } else { + docListEl.appendChild(newEl); + } } } - } /** Modified: mmbase/trunk/core/src/main/java/org/mmbase/util/xml/resources/builder.xsd =================================================================== --- mmbase/trunk/core/src/main/java/org/mmbase/util/xml/resources/builder.xsd 2010-01-12 15:35:47 UTC (rev 40533) +++ mmbase/trunk/core/src/main/java/org/mmbase/util/xml/resources/builder.xsd 2010-01-12 15:40:27 UTC (rev 40534) @@ -137,6 +137,14 @@ </xsd:restriction> </xsd:simpleType> </xsd:attribute> + <xsd:attribute name="override"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="replace" /> + <xsd:enumeration value="merge" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> <xsd:attribute name="readonly"> <xsd:simpleType> <xsd:restriction base="xsd:string"> @@ -267,12 +275,21 @@ <xsd:attribute ref="xml:base" /> </xsd:complexType> </xsd:element> + <xsd:element name="index"> <xsd:complexType> <xsd:sequence> <xsd:element ref="indexfield" maxOccurs="unbounded" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> + <xsd:attribute name="override"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="replace" /> + <xsd:enumeration value="merge" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> <xsd:attribute name="unique"> <xsd:simpleType> <xsd:restriction base="xsd:string"> @@ -283,6 +300,7 @@ </xsd:attribute> </xsd:complexType> </xsd:element> + <xsd:element name="indexfield"> <xsd:complexType> <xsd:attribute name="name" type="xsd:string" use="required" /> @@ -297,6 +315,7 @@ <xsd:attribute ref="xml:base" /> </xsd:complexType> </xsd:element> + <xsd:element name="function"> <xsd:complexType> <xsd:sequence> @@ -305,6 +324,14 @@ <xsd:attribute ref="xml:base" /> <xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="key" type="xsd:string" /> + <xsd:attribute name="override"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="replace" /> + <xsd:enumeration value="merge" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> </xsd:complexType> </xsd:element> _______________________________________________ Cvs mailing list Cvs@lists.mmbase.org http://lists.mmbase.org/mailman/listinfo/cvs