/**
* 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;
}
}