private Pair<Namespace, String> parseAttributeName( String attributeName, String separator, String id, Element md, Dbms dbms, EditLib editLib) throws Exception { Integer indexColon = attributeName.indexOf(separator); String localname = attributeName; Namespace attrNS = Namespace.NO_NAMESPACE; // ... with qualified name if (indexColon != -1) { String prefix = attributeName.substring(0, indexColon); localname = attributeName.substring(indexColon + separator.length()); String schema = dataManager.getMetadataSchema(dbms, id); String namespace = editLib.getNamespace(prefix + ":" + localname, md, dataManager.getSchema(schema)); attrNS = Namespace.getNamespace(prefix, namespace); } return Pair.write(attrNS, localname); }
/** * For Ajax Editing : adds an element or an attribute to a metadata element ([add] link). * * @param dbms * @param session * @param id * @param ref * @param name * @param childName * @return * @throws Exception */ public synchronized Element addElementEmbedded( Dbms dbms, UserSession session, String id, String ref, String name, String childName) throws Exception { String schema = dataManager.getMetadataSchema(dbms, id); // --- get metadata from session Element md = getMetadataFromSession(session, id); // --- ref is parent element so find it EditLib editLib = dataManager.getEditLib(); Element el = editLib.findElement(md, ref); if (el == null) throw new IllegalStateException(MSG_ELEMENT_NOT_FOUND_AT_REF + ref); // --- locate the geonet:element and geonet:info elements and clone for // --- later re-use Element refEl = (Element) (el.getChild(Edit.RootChild.ELEMENT, Edit.NAMESPACE)).clone(); Element info = (Element) (md.getChild(Edit.RootChild.INFO, Edit.NAMESPACE)).clone(); md.removeChild(Edit.RootChild.INFO, Edit.NAMESPACE); Element child = null; MetadataSchema mds = dataManager.getSchema(schema); if (childName != null) { if (childName.equals("geonet:attribute")) { String defaultValue = ""; List attributeDefs = el.getChildren(Edit.RootChild.ATTRIBUTE, Edit.NAMESPACE); for (Object a : attributeDefs) { Element attributeDef = (Element) a; if (attributeDef != null && attributeDef.getAttributeValue(Edit.Attribute.Attr.NAME).equals(name)) { Element defaultChild = attributeDef.getChild(Edit.Attribute.Child.DEFAULT, Edit.NAMESPACE); if (defaultChild != null) { defaultValue = defaultChild.getAttributeValue(Edit.Attribute.Attr.VALUE); } } } Pair<Namespace, String> attInfo = parseAttributeName(name, ":", id, md, dbms, editLib); // --- Add new attribute with default value el.setAttribute(new Attribute(attInfo.two(), defaultValue, attInfo.one())); // TODO : add attribute should be false and del true after adding an attribute child = el; } else { // --- normal element child = editLib.addElement(schema, el, name); if (!childName.equals("")) { // --- or element String uChildName = editLib.getUnqualifiedName(childName); String prefix = editLib.getPrefix(childName); String ns = editLib.getNamespace(childName, md, mds); if (prefix.equals("")) { prefix = editLib.getPrefix(el.getName()); ns = editLib.getNamespace(el.getName(), md, mds); } Element orChild = new Element(uChildName, prefix, ns); child.addContent(orChild); // --- add mandatory sub-tags editLib.fillElement(schema, child, orChild); } } } else { child = editLib.addElement(schema, el, name); } // --- now enumerate the new child (if not a simple attribute) if (childName == null || !childName.equals("geonet:attribute")) { // --- now add the geonet:element back again to keep ref number el.addContent(refEl); int iRef = editLib.findMaximumRef(md); editLib.expandElements(schema, child); editLib.enumerateTreeStartingAt(child, iRef + 1, Integer.parseInt(ref)); // --- add editing info to everything from the parent down editLib.expandTree(mds, el); } // --- attach the info element to the child child.addContent(info); // --- attach the info element to the metadata root) md.addContent((Element) info.clone()); // --- store the metadata in the session again setMetadataIntoSession(session, (Element) md.clone(), id); // Return element added return child; }
/** * TODO javadoc. * * @param dbms * @param id * @param changes * @param currVersion * @return * @throws Exception */ private Element applyChanges(Dbms dbms, String id, Hashtable changes, String currVersion) throws Exception { Lib.resource.checkEditPrivilege(context, id); Element md = xmlSerializer.select(dbms, "Metadata", id, context); // --- check if the metadata has been deleted if (md == null) { return null; } EditLib editLib = dataManager.getEditLib(); String schema = dataManager.getMetadataSchema(dbms, id); editLib.expandElements(schema, md); editLib.enumerateTree(md); // --- check if the metadata has been modified from last time if (currVersion != null && !editLib.getVersion(id).equals(currVersion)) { return null; } // --- update elements for (Enumeration e = changes.keys(); e.hasMoreElements(); ) { String ref = ((String) e.nextElement()).trim(); String val = ((String) changes.get(ref)).trim(); String attr = null; if (updatedLocalizedTextElement(md, ref, val, editLib)) { continue; } int at = ref.indexOf('_'); if (at != -1) { attr = ref.substring(at + 1); ref = ref.substring(0, at); } boolean xmlContent = false; if (ref.startsWith("X")) { ref = ref.substring(1); xmlContent = true; } Element el = editLib.findElement(md, ref); if (el == null) throw new IllegalStateException("Element not found at ref = " + ref); if (attr != null) { // The following work-around decodes any attribute name that has a COLON in it // The : is replaced by the word COLON in the xslt so that it can be processed // by the XML Serializer when an update is submitted - a better solution is // to modify the argument handler in Jeeves to store arguments with their name // as a value rather than as the element itself Integer indexColon = attr.indexOf("COLON"); if (indexColon != -1) { String prefix = attr.substring(0, indexColon); String localname = attr.substring(indexColon + 5); String namespace = editLib.getNamespace(prefix + ":" + localname, md, dataManager.getSchema(schema)); Namespace attrNS = Namespace.getNamespace(prefix, namespace); if (el.getAttribute(localname, attrNS) != null) { el.setAttribute(new Attribute(localname, val, attrNS)); } // End of work-around } else { if (el.getAttribute(attr) != null) el.setAttribute(new Attribute(attr, val)); } } else if (xmlContent) { if (Log.isDebugEnabled(Geonet.EDITOR)) Log.debug(Geonet.EDITOR, "replacing XML content"); el.removeContent(); val = addNamespaceToFragment(val); el.addContent(Xml.loadString(val, false)); } else { List content = el.getContent(); for (int i = 0; i < content.size(); i++) { if (content.get(i) instanceof Text) { el.removeContent((Text) content.get(i)); i--; } } el.addContent(val); } } // --- remove editing info added by previous call editLib.removeEditingInfo(md); editLib.contractElements(md); return md; }