/* * FrontlineSMS <http://www.frontlinesms.com> * Copyright 2007, 2008 kiwanja * * This file is part of FrontlineSMS. * * FrontlineSMS is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * FrontlineSMS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FrontlineSMS. If not, see <http://www.gnu.org/licenses/>. */ package net.frontlinesms; import java.io.IOException; import java.io.InputStream; import java.util.LinkedList; import net.frontlinesms.data.XMLMessage; import org.apache.log4j.Logger; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; /** * This class is used to read XML files, which contains frontlineSMS commands, for instance, * sending messages to numbers, contacts or groups. * * * TODO i am a pointless comment; please delete me * * @author Carlos Eduardo Genz */ public class XMLReader { private static final String ATTRIBUTE_GROUP = "group"; private static final String ATTRIBUTE_CONTACT = "contact"; private static final String ATTRIBUTE_NUMBER = "number"; private static final String ELEMENT_TO = "to"; private static final String ELEMENT_TEXT = "text"; private static final String ELEMENT_DATA = "data"; private static final String TYPE_BINARY = "binary"; private static final String ATTRIBUTE_TYPE = "type"; private static final String ELEMENT_SMS = "sms"; private Document doc; private static Logger LOG = FrontlineUtils.getLogger(XMLReader.class); public XMLReader(InputStream toRead) throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); doc = builder.build(toRead); } /** * This method reads the XML file looking for instances of message (<sms/>). * * @return A list with all message instances. */ public LinkedList<XMLMessage> readMessages() { Element root = doc.getRootElement(); LinkedList<XMLMessage> messages = new LinkedList<XMLMessage>(); for (Object o : root.getChildren()) { Element child = (Element) o; if (ELEMENT_SMS.equalsIgnoreCase(child.getName())) { try { //new message XMLMessage current = new XMLMessage(); getMessageType(child, current); getData(child, current); getRecipients(child, current); messages.add(current); } catch (RuntimeException e) { LOG.debug("Error reading message", e); } } } return messages; } /** * This method searches for <to/> elements into the supplied element and * add the useful information to the supplied XMLMessage instance. * * @param child * @param current */ private static void getRecipients(Element child, XMLMessage current) { if (child.getChildren(ELEMENT_TO).size() == 0) { throw new RuntimeException("No [to] elements were found inside [" + ELEMENT_SMS + "]. Discarding message."); } for (Object to : child.getChildren(ELEMENT_TO)) { Element toElement = (Element) to; if (toElement.getAttributes().size() == 1) { Attribute recipient = (Attribute) toElement.getAttributes().get(0); if (!recipient.getValue().equals("")) { if (recipient.getName().equalsIgnoreCase(ATTRIBUTE_NUMBER)) { current.addNumber(recipient.getValue()); } else if (recipient.getName().equalsIgnoreCase(ATTRIBUTE_CONTACT)) { current.addContact(recipient.getValue()); } else if (recipient.getName().equalsIgnoreCase(ATTRIBUTE_GROUP)) { current.addGroup(recipient.getValue()); } } } } } /** * This method searches for <data/> or <text/> elements into the supplied element and * sets the data into the supplied XMLMessage instance. * * @param child * @param current */ private static void getData(Element child, XMLMessage current) { if (current.getType() == XMLMessage.TYPE_BINARY) { Attribute dataAttr = child.getAttribute(ELEMENT_DATA); if (dataAttr == null || dataAttr.getValue().equalsIgnoreCase("")) { Element data = child.getChild(ELEMENT_DATA); if (data == null || data.getValue().equalsIgnoreCase("")) { //PROBLEM.. data not found. throw new RuntimeException("[data] inside [" + ELEMENT_SMS + "] is missing or blank."); } current.setData(data.getValue().trim()); } else { current.setData(dataAttr.getValue().trim()); } } else { Attribute textAttr = child.getAttribute(ELEMENT_TEXT); if (textAttr == null || textAttr.getValue().equalsIgnoreCase("")) { Element text = child.getChild(ELEMENT_TEXT); if (text == null || text.getValue().equalsIgnoreCase("")) { //PROBLEM.. text not found. throw new RuntimeException("[text] inside [" + ELEMENT_SMS + "] is missing or blank."); } current.setData(text.getValue().trim()); } else { current.setData(textAttr.getValue().trim()); } } } /** * This method searches for a <code>type</code> attribute into the supplied element and * set the type of the supplied XMLMessage instance. * * @param child * @param current */ private static void getMessageType(Element child, XMLMessage current) { //Verify if type attribute is defined. if (child.getAttribute(ATTRIBUTE_TYPE) != null) { String type = child.getAttributeValue(ATTRIBUTE_TYPE); if (TYPE_BINARY.equalsIgnoreCase(type)) { current.setType(XMLMessage.TYPE_BINARY); } } } }