/** * Copyright 1999-2009 The Pegadi Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * This class has some static methods frequently needed when working * with XML DOMs. * * @author HÃ¥vard Wigtil <havardw at pvv.org> * @version $Revision$, $Date$ */ package org.pegadi.util; // XML imports import no.dusken.common.model.Person; import org.pegadi.model.LoginContext; import org.pegadi.server.NoAccessException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.*; import java.util.Vector; import static org.pegadi.util.PersonUtils.getInitials; public class XMLUtil { private static Logger log = LoggerFactory.getLogger(XMLUtil.class); /** * This methods extracts the text for a named element under the * <code>root</code>. For the moment it uses only the first text node, * and only the first element of that type. * * @param root The element is contained within this root. * @param tagname The elemet name to search for * @return The text under the tag, or <code>null</code> if it is not found * or an error occured. */ public static String getElementText(Element root, String tagname) { NodeList nameList = root.getElementsByTagName(tagname); if (nameList.getLength() > 0) { Node text = nameList.item(0).getFirstChild(); // Find the first text node while ((text != null) && !(text instanceof Text)) { text = text.getNextSibling(); } if (text == null) { return null; } else { try { return text.getNodeValue(); } catch (DOMException de) { return null; } } } else { return null; } } /** * Gets a named element from a documents schema. * * @param name The name of the element. * @return The element, or <code>null</code> if it was not found. * @see org.w3c.dom.Node */ public static Element getSchemaElement(String name, Element schema) { if (schema == null) { log.error("XMLUtil.getSchemaElement: schema element is NULL, can't continue!"); return null; } NodeList nl = schema.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); if (n instanceof Element) { //Log.m("XMLUtil.getSchemaElement: Checking element " + n.toString() + "(" + n.getClass().getName() + ")"); String elemName = ((Element) n).getAttribute("name"); if (elemName.equals(name)) { return (Element) n; } } } return null; } /** * Get an element as a child of the root node. If the element * is a type or a reference, the referenced element will be returned. * * @param name The name of the element. * @param root The root for this search. * @return The definition of the element with <code>name</code>. */ public static Element getSchemaReference(String name, Node root) { // FIXME: Use a stack when we move to JDK 1.2 Vector elements = new Vector(20, 10); elements.addElement(root); int j = 1; while (!elements.isEmpty()) { Node n = (Node) elements.lastElement(); elements.removeElement(n); //debugDump(n, "NODE " + (j++) + ": ", System.err); NodeList children = n.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { elements.addElement(children.item(i)); } if (n instanceof Element) { String ename = ((Element) n).getAttribute("name"); if (ename.equals(name)) { //Log.m("XMLUtil.getSchemaReference: Match found on name"); String type = ((Element) n).getAttribute("type"); String ref = ((Element) n).getAttribute("ref"); if (type != null) { Element typeElem = getSchemaElement(type, root.getOwnerDocument().getDocumentElement()); if (typeElem != null) { //Log.m("XMLUtil.getSchemaReference: Returning element from type"); return typeElem; } } else if (ref != null) { Element refElem = getSchemaElement(ref, root.getOwnerDocument().getDocumentElement()); if (refElem != null) { //Log.m("XMLUtil.getSchemaReference: Returning element from ref"); return refElem; } } else { //Log.m("XMLUtil.getSchemaReference: Returning found element"); return (Element) n; } } // If name matches //Log.m("XMLUtil.getSchemaReference: No match on element " + name); } // if n is an Element } // While elements in list //Log.m("XMLUtil.getSchemaReference: No match, returning NULL."); return null; } public static final String PERSON_TAG = "person"; public static final String NAME_TAG = "name"; public static final String EMAIL_TAG = "email"; public static final String INITIALS_TAG = "initials"; /** * Converts an xml-person-element to a User-object * * @param xml The element to load. An <code>IllegalArgumentException</code> * will be thrown if the element is not of type PERSON_TAG. */ public static Person xml2user(Element xml) throws IllegalArgumentException { if (xml == null) return null; if (!xml.getTagName().equals(PERSON_TAG)) { throw new IllegalArgumentException("PersonPane.setXML can only process \"person\" tags."); } Person person = null; String idstring = xml.getAttribute("ID").trim(); if (idstring != null) { try { try { Integer id = Integer.valueOf(idstring); person = LoginContext.server.getUserByLegacyId(id, LoginContext.sessionKey); } catch (NumberFormatException e) { person = LoginContext.server.getUserByUsername(idstring, LoginContext.sessionKey); } } catch (NoAccessException e) { log.error("Error fetching person by id {}", idstring, e); } } return person; } /** * Makes an XML-element of a User. * * @param user The User to be converted. * @param doc The containing document of the element that is to be returned. * The parameter is needed because when a new pane without * content is created the pane has no reference to the XML * Document class, and a Document instance is needed to create * new elements. I hope to create a more elegant solution some * day. :( * @return An element of type person */ public static Element user2xml(Person user, Document doc) { if (user == null || doc == null) return null; Element p = doc.createElement(PERSON_TAG); if (user.getId() != null) { p.setAttribute("ID", user.getUsername()); } String name = (user.getName()); if (name.length() > 0) { Element nameNode = doc.createElement(NAME_TAG); nameNode.appendChild(doc.createTextNode(name)); p.appendChild(nameNode); } String email = user.getEmailAddress(); if (email.length() > 0) { Element emailNode = doc.createElement(EMAIL_TAG); emailNode.appendChild(doc.createTextNode(email)); p.appendChild(emailNode); } String initials = getInitials(user); if (initials.length() > 0) { Element inNode = doc.createElement(INITIALS_TAG); inNode.appendChild(doc.createTextNode(initials)); p.appendChild(inNode); } return p; } }