Coverage Report - org.codeforamerica.open311.internals.parsing.XMLParser
 
Classes in this File Line Coverage Branch Coverage Complexity
XMLParser
91%
165/180
61%
42/68
4
 
 1  
 package org.codeforamerica.open311.internals.parsing;
 2  
 
 3  
 import java.io.ByteArrayInputStream;
 4  
 import java.io.IOException;
 5  
 import java.io.UnsupportedEncodingException;
 6  
 import java.net.MalformedURLException;
 7  
 import java.net.URL;
 8  
 import java.util.Date;
 9  
 import java.util.HashMap;
 10  
 import java.util.LinkedList;
 11  
 import java.util.List;
 12  
 import java.util.Map;
 13  
 
 14  
 import javax.xml.parsers.DocumentBuilder;
 15  
 import javax.xml.parsers.DocumentBuilderFactory;
 16  
 import javax.xml.parsers.ParserConfigurationException;
 17  
 
 18  
 import org.codeforamerica.open311.facade.EndpointType;
 19  
 import org.codeforamerica.open311.facade.Format;
 20  
 import org.codeforamerica.open311.facade.data.AttributeInfo;
 21  
 import org.codeforamerica.open311.facade.data.AttributeInfo.Datatype;
 22  
 import org.codeforamerica.open311.facade.data.Endpoint;
 23  
 import org.codeforamerica.open311.facade.data.POSTServiceRequestResponse;
 24  
 import org.codeforamerica.open311.facade.data.Service;
 25  
 import org.codeforamerica.open311.facade.data.ServiceDefinition;
 26  
 import org.codeforamerica.open311.facade.data.ServiceDiscoveryInfo;
 27  
 import org.codeforamerica.open311.facade.data.ServiceRequest;
 28  
 import org.codeforamerica.open311.facade.data.ServiceRequest.Status;
 29  
 import org.codeforamerica.open311.facade.data.ServiceRequestIdResponse;
 30  
 import org.codeforamerica.open311.facade.exceptions.DataParsingException;
 31  
 import org.codeforamerica.open311.facade.exceptions.GeoReportV2Error;
 32  
 import org.w3c.dom.Document;
 33  
 import org.w3c.dom.Element;
 34  
 import org.w3c.dom.Node;
 35  
 import org.w3c.dom.NodeList;
 36  
 import org.xml.sax.InputSource;
 37  
 import org.xml.sax.SAXException;
 38  
 
 39  
 /**
 40  
  * Parses XML files using DOM.
 41  
  * 
 42  
  * @author Santiago MunĂ­n <santimunin@gmail.com>
 43  
  * 
 44  
  */
 45  
 public class XMLParser extends AbstractParser {
 46  
 
 47  
         private DocumentBuilder dBuilder;
 48  23
         private DateParser dateParser = new DateParser();
 49  
 
 50  
         /**
 51  
          * Creates an instance of an XMLParser creating a {@link DocumentBuilder}.
 52  
          */
 53  23
         public XMLParser() {
 54  
                 try {
 55  23
                         dBuilder = DocumentBuilderFactory.newInstance()
 56  
                                         .newDocumentBuilder();
 57  0
                 } catch (ParserConfigurationException e) {
 58  0
                         throw new Error(
 59  
                                         "Cannot create a DocumentBuilder which satisfies the configuration requested.");
 60  23
                 }
 61  23
         }
 62  
 
 63  
         @Override
 64  
         public List<Service> parseServiceList(String rawData)
 65  
                         throws DataParsingException {
 66  5
                 List<Service> result = new LinkedList<Service>();
 67  
                 try {
 68  5
                         Document doc = getDocument(rawData);
 69  4
                         NodeList serviceNodeList = doc.getElementsByTagName(SERVICE_TAG);
 70  12
                         for (int i = 0; i < serviceNodeList.getLength(); i++) {
 71  8
                                 Node serviceNode = serviceNodeList.item(i);
 72  8
                                 if (serviceNode.getNodeType() == Node.ELEMENT_NODE) {
 73  8
                                         result.add(getService((Element) serviceNode));
 74  
                                 }
 75  
                         }
 76  1
                 } catch (Exception e) {
 77  1
                         throw new DataParsingException(e.getMessage());
 78  4
                 }
 79  4
                 return result;
 80  
         }
 81  
 
 82  
         /**
 83  
          * Builds a {@link Service} object from an {@link Element} of the DOM.
 84  
          * 
 85  
          * @param serviceElement
 86  
          *            A valid element node of a service.
 87  
          * @return An object wrapping the information contained in the given
 88  
          *         element.
 89  
          */
 90  
         private Service getService(Element serviceElement) {
 91  8
                 String code = getTagContent(serviceElement, SERVICE_CODE_TAG);
 92  8
                 String name = getTagContent(serviceElement, SERVICE_NAME_TAG);
 93  8
                 String description = getTagContent(serviceElement, DESCRIPTION_TAG);
 94  8
                 Boolean metadata = parseBoolean(getTagContent(serviceElement,
 95  
                                 METADATA_TAG));
 96  8
                 String group = getTagContent(serviceElement, SERVICE_GROUP_TAG);
 97  8
                 String[] keywords = getKeywords(getTagContent(serviceElement,
 98  
                                 KEYWORDS_TAG));
 99  8
                 Service.Type type = Service.Type.getFromString(getTagContent(
 100  
                                 serviceElement, TYPE_TAG));
 101  8
                 return new Service(code, name, description, metadata, type, keywords,
 102  
                                 group);
 103  
         }
 104  
 
 105  
         @Override
 106  
         public ServiceDefinition parseServiceDefinition(String rawData)
 107  
                         throws DataParsingException {
 108  
                 try {
 109  5
                         Document doc = getDocument(rawData);
 110  4
                         NodeList serviceDefinitionNodeList = doc
 111  
                                         .getElementsByTagName(SERVICE_DEFINITION_TAG);
 112  4
                         for (int i = 0; i < serviceDefinitionNodeList.getLength(); i++) {
 113  4
                                 Node serviceDefinitionNode = serviceDefinitionNodeList.item(i);
 114  4
                                 if (serviceDefinitionNode.getNodeType() == Node.ELEMENT_NODE) {
 115  4
                                         return getServiceDefinition((Element) serviceDefinitionNode);
 116  
                                 }
 117  
                         }
 118  1
                 } catch (Exception e) {
 119  1
                         throw new DataParsingException(e.getMessage());
 120  0
                 }
 121  0
                 return null;
 122  
         }
 123  
 
 124  
         /**
 125  
          * Builds a {@link ServiceDefinition} object from an {@link Element} of the
 126  
          * DOM.
 127  
          * 
 128  
          * @param serviceDefinitionElement
 129  
          *            A valid element node of a service definition.
 130  
          * @return An object wrapping the information contained in the given
 131  
          *         element.
 132  
          */
 133  
         private ServiceDefinition getServiceDefinition(
 134  
                         Element serviceDefinitionElement) {
 135  4
                 String serviceCode = getTagContent(serviceDefinitionElement,
 136  
                                 SERVICE_CODE_TAG);
 137  4
                 NodeList attributesNodeList = serviceDefinitionElement
 138  
                                 .getElementsByTagName(ATTRIBUTE_TAG);
 139  4
                 List<AttributeInfo> attributes = new LinkedList<AttributeInfo>();
 140  8
                 for (int j = 0; j < attributesNodeList.getLength(); j++) {
 141  4
                         Node attributeNode = attributesNodeList.item(j);
 142  4
                         if (attributeNode.getNodeType() == Node.ELEMENT_NODE) {
 143  4
                                 Element attributeElement = (Element) attributeNode;
 144  4
                                 Boolean variable = parseBoolean(getTagContent(attributeElement,
 145  
                                                 VARIABLE_TAG));
 146  4
                                 String code = getTagContent(attributeElement, CODE_TAG);
 147  4
                                 Datatype datatype = Datatype.getFromString(getTagContent(
 148  
                                                 attributeElement, DATATYPE_TAG));
 149  4
                                 Boolean required = parseBoolean(getTagContent(attributeElement,
 150  
                                                 REQUIRED_TAG));
 151  4
                                 String datatypeDescription = getTagContent(attributeElement,
 152  
                                                 DATATYPE_DESCRIPTION_TAG);
 153  4
                                 Integer order = parseInt(getTagContent(attributeElement,
 154  
                                                 ORDER_TAG));
 155  4
                                 String description = getTagContent(attributeElement,
 156  
                                                 DESCRIPTION_TAG);
 157  4
                                 Map<String, String> values = new HashMap<String, String>();
 158  4
                                 NodeList valuesNodeList = attributeElement
 159  
                                                 .getElementsByTagName(VALUE_TAG);
 160  12
                                 for (int k = 0; k < valuesNodeList.getLength(); k++) {
 161  8
                                         Node valueNode = valuesNodeList.item(k);
 162  8
                                         if (valueNode.getNodeType() == Node.ELEMENT_NODE) {
 163  8
                                                 Element valueElement = (Element) valueNode;
 164  8
                                                 String key = getTagContent(valueElement, KEY_TAG);
 165  8
                                                 String name = getTagContent(valueElement, NAME_TAG);
 166  8
                                                 values.put(key, name);
 167  
                                         }
 168  
                                 }
 169  4
                                 attributes.add(new AttributeInfo(variable, code, datatype,
 170  
                                                 required, datatypeDescription, order, description,
 171  
                                                 values));
 172  
                         }
 173  
 
 174  
                 }
 175  4
                 return new ServiceDefinition(serviceCode, attributes);
 176  
         }
 177  
 
 178  
         @Override
 179  
         public ServiceRequestIdResponse parseServiceRequestIdFromAToken(
 180  
                         String rawData) throws DataParsingException {
 181  
                 try {
 182  3
                         Document doc = getDocument(rawData);
 183  2
                         NodeList serviceRequestsIdList = doc
 184  
                                         .getElementsByTagName(SERVICE_REQUEST_TAG);
 185  2
                         for (int i = 0; i < serviceRequestsIdList.getLength(); i++) {
 186  2
                                 Node serviceRequestIdNode = serviceRequestsIdList.item(i);
 187  2
                                 if (serviceRequestIdNode.getNodeType() == Node.ELEMENT_NODE) {
 188  2
                                         return getServiceRequestIdResponse((Element) serviceRequestIdNode);
 189  
                                 }
 190  
                         }
 191  0
                         return null;
 192  1
                 } catch (Exception e) {
 193  1
                         throw new DataParsingException(e.getMessage());
 194  
                 }
 195  
         }
 196  
 
 197  
         /**
 198  
          * Builds a {@link ServiceRequestIdResponse} object from an {@link Element}
 199  
          * of the DOM.
 200  
          * 
 201  
          * @param serviceRequestIdElement
 202  
          *            A valid element node of a service request id.
 203  
          * @return An object wrapping the information contained in the given
 204  
          *         element.
 205  
          */
 206  
         private ServiceRequestIdResponse getServiceRequestIdResponse(
 207  
                         Element serviceRequestIdElement) {
 208  2
                 String token = getTagContent(serviceRequestIdElement, TOKEN_TAG);
 209  2
                 String serviceRequestId = getTagContent(serviceRequestIdElement,
 210  
                                 SERVICE_REQUEST_ID_TAG);
 211  2
                 return new ServiceRequestIdResponse(serviceRequestId, token);
 212  
         }
 213  
 
 214  
         @Override
 215  
         public List<ServiceRequest> parseServiceRequests(String rawData)
 216  
                         throws DataParsingException {
 217  6
                 List<ServiceRequest> result = new LinkedList<ServiceRequest>();
 218  
                 try {
 219  6
                         Document doc = getDocument(rawData);
 220  5
                         NodeList serviceRequestsIdList = doc
 221  
                                         .getElementsByTagName(SERVICE_REQUEST_TAG);
 222  15
                         for (int i = 0; i < serviceRequestsIdList.getLength(); i++) {
 223  10
                                 Node serviceRequestIdNode = serviceRequestsIdList.item(i);
 224  10
                                 if (serviceRequestIdNode.getNodeType() == Node.ELEMENT_NODE) {
 225  10
                                         result.add(getServiceRequest((Element) serviceRequestIdNode));
 226  
                                 }
 227  
                         }
 228  1
                 } catch (Exception e) {
 229  1
                         throw new DataParsingException(e.getMessage());
 230  5
                 }
 231  5
                 return result;
 232  
         }
 233  
 
 234  
         /**
 235  
          * Builds a {@link ServiceRequest} object from an {@link Element} of the
 236  
          * DOM.
 237  
          * 
 238  
          * @param serviceRequestElement
 239  
          *            A valid element node of a service request.
 240  
          * @return An object wrapping the information contained in the given
 241  
          *         element.
 242  
          * @throws MalformedURLException
 243  
          *             If the URL given in the {@link Element} object is not valid.
 244  
          */
 245  
         private ServiceRequest getServiceRequest(Element serviceRequestElement)
 246  
                         throws MalformedURLException {
 247  10
                 String serviceRequestId = getTagContent(serviceRequestElement,
 248  
                                 SERVICE_REQUEST_ID_TAG);
 249  10
                 Status status = Status.getFromString(getTagContent(
 250  
                                 serviceRequestElement, STATUS_TAG));
 251  10
                 String statusNotes = getTagContent(serviceRequestElement,
 252  
                                 STATUS_NOTES_TAG);
 253  10
                 String serviceName = getTagContent(serviceRequestElement,
 254  
                                 SERVICE_NAME_TAG);
 255  10
                 String serviceCode = getTagContent(serviceRequestElement,
 256  
                                 SERVICE_CODE_TAG);
 257  10
                 String description = getTagContent(serviceRequestElement,
 258  
                                 DESCRIPTION_TAG);
 259  10
                 String agencyResponsible = getTagContent(serviceRequestElement,
 260  
                                 AGENCY_RESPONSIBLE_TAG);
 261  10
                 String serviceNotice = getTagContent(serviceRequestElement,
 262  
                                 SERVICE_NOTICE_TAG);
 263  10
                 Date requestedDatetime = dateParser.parseDate((getTagContent(
 264  
                                 serviceRequestElement, REQUESTED_DATETIME_TAG)));
 265  10
                 Date updatedDatetime = dateParser.parseDate((getTagContent(
 266  
                                 serviceRequestElement, UPDATED_DATETIME_TAG)));
 267  10
                 Date expectedDatetime = dateParser.parseDate((getTagContent(
 268  
                                 serviceRequestElement, EXPECTED_DATETIME_TAG)));
 269  10
                 String address = getTagContent(serviceRequestElement, ADDRESS_TAG);
 270  10
                 Long addressId = parseLong(getTagContent(serviceRequestElement,
 271  
                                 ADDRESS_ID_TAG));
 272  10
                 Integer zipCode = parseInt(getTagContent(serviceRequestElement,
 273  
                                 ZIPCODE_TAG));
 274  10
                 Float latitude = parseFloat(getTagContent(serviceRequestElement,
 275  
                                 LATITUDE_TAG));
 276  10
                 Float longitude = parseFloat(getTagContent(serviceRequestElement,
 277  
                                 LONGITUDE_TAG));
 278  10
                 String rawMediaUrl = getTagContent(serviceRequestElement, MEDIA_URL_TAG)
 279  
                                 .trim();
 280  10
                 URL mediaUrl = buildUrl(rawMediaUrl);
 281  10
                 return new ServiceRequest(serviceRequestId, status, statusNotes,
 282  
                                 serviceName, serviceCode, description, agencyResponsible,
 283  
                                 serviceNotice, requestedDatetime, updatedDatetime,
 284  
                                 expectedDatetime, address, addressId, zipCode, latitude,
 285  
                                 longitude, mediaUrl);
 286  
         }
 287  
 
 288  
         @Override
 289  
         public POSTServiceRequestResponse parsePostServiceRequestResponse(
 290  
                         String rawData) throws DataParsingException {
 291  
                 try {
 292  6
                         Document doc = getDocument(rawData);
 293  5
                         NodeList serviceRequestsIdList = doc
 294  
                                         .getElementsByTagName(SERVICE_REQUEST_TAG);
 295  5
                         for (int i = 0; i < serviceRequestsIdList.getLength(); i++) {
 296  4
                                 Node serviceRequestIdNode = serviceRequestsIdList.item(i);
 297  4
                                 if (serviceRequestIdNode.getNodeType() == Node.ELEMENT_NODE) {
 298  4
                                         return getPostServiceRequestResponse((Element) serviceRequestIdNode);
 299  
                                 }
 300  
                         }
 301  1
                 } catch (Exception e) {
 302  1
                         throw new DataParsingException(e.getMessage());
 303  1
                 }
 304  1
                 throw new DataParsingException(
 305  
                                 "The obtained response couldn't be parsed, it may be an error.");
 306  
         }
 307  
 
 308  
         /**
 309  
          * Builds a {@link POSTServiceRequestResponse} object from an
 310  
          * {@link Element} of the DOM.
 311  
          * 
 312  
          * @param postServiceRequestResponseElement
 313  
          *            A valid element node of a post service request response..
 314  
          * @return An object wrapping the information contained in the given
 315  
          *         element.
 316  
          */
 317  
         private POSTServiceRequestResponse getPostServiceRequestResponse(
 318  
                         Element postServiceRequestResponseElement) {
 319  4
                 String token = getTagContent(postServiceRequestResponseElement,
 320  
                                 TOKEN_TAG);
 321  4
                 String serviceRequestId = getTagContent(
 322  
                                 postServiceRequestResponseElement, SERVICE_REQUEST_ID_TAG);
 323  4
                 String serviceNotice = getTagContent(postServiceRequestResponseElement,
 324  
                                 SERVICE_NOTICE_TAG);
 325  4
                 String accountId = getTagContent(postServiceRequestResponseElement,
 326  
                                 ACCOUNT_ID_TAG);
 327  4
                 return new POSTServiceRequestResponse(serviceRequestId, token,
 328  
                                 serviceNotice, accountId);
 329  
         }
 330  
 
 331  
         @Override
 332  
         public GeoReportV2Error parseGeoReportV2Errors(String rawData)
 333  
                         throws DataParsingException {
 334  
                 try {
 335  3
                         Document doc = getDocument(rawData);
 336  2
                         NodeList errorNodes = doc.getElementsByTagName(ERROR_TAG);
 337  2
                         for (int i = 0; i < errorNodes.getLength(); i++) {
 338  2
                                 Node errorNode = errorNodes.item(i);
 339  2
                                 if (errorNode.getNodeType() == Node.ELEMENT_NODE) {
 340  2
                                         return getGeoReportErrorFromXMLElement((Element) errorNode);
 341  
                                 }
 342  
                         }
 343  0
                         throw new DataParsingException(
 344  
                                         "The obtained response is not an error object");
 345  1
                 } catch (Exception e) {
 346  1
                         throw new DataParsingException(e.getMessage());
 347  
                 }
 348  
         }
 349  
 
 350  
         /**
 351  
          * Builds a {@link GeoReportV2Error} object from an {@link Element} of the
 352  
          * DOM.
 353  
          * 
 354  
          * @param geoReportErrorElement
 355  
          *            Valid element node of a geo report error.
 356  
          * @return An object wrapping the information contained in the given
 357  
          *         element.
 358  
          */
 359  
         private GeoReportV2Error getGeoReportErrorFromXMLElement(
 360  
                         Element geoReportErrorElement) {
 361  2
                 String code = getTagContent(geoReportErrorElement, CODE_TAG);
 362  2
                 String description = getTagContent(geoReportErrorElement,
 363  
                                 DESCRIPTION_TAG);
 364  2
                 return new GeoReportV2Error(code, description);
 365  
         }
 366  
 
 367  
         @Override
 368  
         public ServiceDiscoveryInfo parseServiceDiscovery(String rawData)
 369  
                         throws DataParsingException {
 370  
                 try {
 371  6
                         Document doc = getDocument(rawData);
 372  6
                         NodeList serviceDiscoveryNodes = doc
 373  
                                         .getElementsByTagName(DISCOVERY_TAG);
 374  6
                         for (int i = 0; i < serviceDiscoveryNodes.getLength(); i++) {
 375  6
                                 Node serviceDiscoveryNode = serviceDiscoveryNodes.item(i);
 376  6
                                 if (serviceDiscoveryNode.getNodeType() == Node.ELEMENT_NODE) {
 377  6
                                         Element serviceDiscoveryElement = (Element) serviceDiscoveryNode;
 378  6
                                         Date changeset = dateParser.parseDate(getTagContent(
 379  
                                                         serviceDiscoveryElement, CHANGESET_TAG));
 380  6
                                         String contact = getTagContent(serviceDiscoveryElement,
 381  
                                                         CONTACT_TAG);
 382  6
                                         String keyService = getTagContent(serviceDiscoveryElement,
 383  
                                                         KEY_SERVICE_TAG);
 384  6
                                         return new ServiceDiscoveryInfo(changeset, contact,
 385  
                                                         keyService,
 386  
                                                         parseEndpoints(serviceDiscoveryElement
 387  
                                                                         .getElementsByTagName(ENDPOINT_TAG),
 388  
                                                                         serviceDiscoveryElement));
 389  
                                 }
 390  
                         }
 391  0
                 } catch (Exception e) {
 392  0
                         throw new DataParsingException(e.getMessage());
 393  0
                 }
 394  0
                 return null;
 395  
         }
 396  
 
 397  
         /**
 398  
          * Builds a list of endpoints.
 399  
          * 
 400  
          * @param endpointsList
 401  
          *            List of nodes with the "endpoint" tag.
 402  
          * @param serviceDiscoveryElement
 403  
          *            In some service discovery files, the specification url is not
 404  
          *            inside the endpoint field but in the same level. This
 405  
          *            parameter allows to fetch it in that case.
 406  
          * @return List of endpoints.
 407  
          */
 408  
         private List<Endpoint> parseEndpoints(NodeList endpointsList,
 409  
                         Element serviceDiscoveryElement) {
 410  6
                 List<Endpoint> result = new LinkedList<Endpoint>();
 411  30
                 for (int i = 0; i < endpointsList.getLength(); i++) {
 412  24
                         Node endpointNode = endpointsList.item(i);
 413  24
                         if (endpointNode.getNodeType() == Node.ELEMENT_NODE) {
 414  24
                                 Element endpointElement = (Element) endpointNode;
 415  24
                                 String specificationUrl = getTagContent(endpointElement,
 416  
                                                 SPECIFICATION_TAG);
 417  24
                                 if (specificationUrl.length() == 0) {
 418  0
                                         specificationUrl = getTagContent(serviceDiscoveryElement,
 419  
                                                         SPECIFICATION_TAG);
 420  
                                 }
 421  24
                                 String url = getTagContent(endpointElement, URL_TAG);
 422  24
                                 Date changeset = dateParser.parseDate(getTagContent(
 423  
                                                 endpointElement, CHANGESET_TAG));
 424  24
                                 EndpointType type = EndpointType.getFromString(getTagContent(
 425  
                                                 endpointElement, TYPE_TAG));
 426  24
                                 NodeList formatNodes = endpointElement
 427  
                                                 .getElementsByTagName(FORMAT_TAG);
 428  24
                                 List<Format> formats = new LinkedList<Format>();
 429  48
                                 for (int j = 0; j < formatNodes.getLength(); j++) {
 430  24
                                         Node formatNode = formatNodes.item(j);
 431  24
                                         if (formatNode.getNodeType() == Node.ELEMENT_NODE) {
 432  24
                                                 Element formatElement = (Element) formatNode;
 433  24
                                                 formats.add(Format
 434  
                                                                 .getFromHTTPContentTypeString(formatElement
 435  
                                                                                 .getTextContent()));
 436  
                                         }
 437  
                                 }
 438  24
                                 if (url != null && url.length() > 0) {
 439  24
                                         result.add(new Endpoint(specificationUrl, url, changeset,
 440  
                                                         type, formats));
 441  
                                 }
 442  
                         }
 443  
                 }
 444  6
                 return result;
 445  
         }
 446  
 
 447  
         /**
 448  
          * Returns a {@link Document} representing the DOM of the XML string.
 449  
          * 
 450  
          * @param rawData
 451  
          *            XML UTF-8 encoded string.
 452  
          * @return A document built with the given data.
 453  
          * @throws UnsupportedEncodingException
 454  
          * @throws SAXException
 455  
          * @throws IOException
 456  
          */
 457  
         private Document getDocument(String rawData)
 458  
                         throws UnsupportedEncodingException, SAXException, IOException {
 459  34
                 Document doc = dBuilder.parse(new InputSource(new ByteArrayInputStream(
 460  
                                 rawData.getBytes(DataParser.TEXT_FORMAT))));
 461  28
                 doc.getDocumentElement().normalize();
 462  28
                 return doc;
 463  
         }
 464  
 
 465  
         /**
 466  
          * Returns the value of a tag inside an element.
 467  
          * 
 468  
          * @param element
 469  
          *            Element.
 470  
          * @param tag
 471  
          *            Tag inside the element.
 472  
          * @return content of the tag inside the element or <code>""</code> if the
 473  
          *         tag doesn't exists.
 474  
          */
 475  
         private String getTagContent(Element element, String tag) {
 476  412
                 NodeList nodeList = element.getElementsByTagName(tag);
 477  412
                 if (nodeList.getLength() > 0) {
 478  408
                         return nodeList.item(0).getTextContent();
 479  
                 }
 480  4
                 return "";
 481  
         }
 482  
 
 483  
         /**
 484  
          * Parses a string and returns an integer. <b>NOTE<b>: Be careful and notice
 485  
          * that this function will return a <code>null</code> if the given string is
 486  
          * not valid. This approach works well here, but not generally.
 487  
          * 
 488  
          * @param rawInt
 489  
          *            A string which represents an integer number.
 490  
          * @return The integer value (or <code>null</code> if the rawInt is empty or
 491  
          *         <code>null</code>).
 492  
          */
 493  
         private int parseInt(String rawInt) {
 494  
                 try {
 495  14
                         return (rawInt != null && rawInt.length() > 0) ? Integer
 496  
                                         .parseInt(rawInt) : 0;
 497  0
                 } catch (NumberFormatException e) {
 498  0
                         return -1;
 499  
                 }
 500  
         }
 501  
 
 502  
         /**
 503  
          * Parses a string and returns a long. <b>NOTE<b>: Be careful and notice
 504  
          * that this function will return a <code>null</code> if the given string is
 505  
          * not valid. This approach works well here, but not generally.
 506  
          * 
 507  
          * @param rawLong
 508  
          *            A string which represents a long number.
 509  
          * @return The long value (or <code>null</code> if the rawLong is empty or
 510  
          *         <code>null</code>).
 511  
          */
 512  
         private long parseLong(String rawLong) {
 513  
                 try {
 514  10
                         return (rawLong != null && rawLong.length() > 0) ? Long
 515  
                                         .parseLong(rawLong) : 0;
 516  0
                 } catch (NumberFormatException e) {
 517  0
                         return -1;
 518  
                 }
 519  
         }
 520  
 
 521  
         /**
 522  
          * Parses a string and returns a float. <b>NOTE<b>: Be careful and notice
 523  
          * that this function will return a <code>null</code> if the given string is
 524  
          * not valid.
 525  
          * 
 526  
          * @param rawFloat
 527  
          *            A string which represents a float number.
 528  
          * @return The float value (or <code>null</code> if the rawFloat is empty or
 529  
          *         <code>null</code>).
 530  
          */
 531  
         private Float parseFloat(String rawFloat) {
 532  20
                 return (rawFloat != null && rawFloat.length() > 0) ? Float
 533  
                                 .valueOf(rawFloat) : null;
 534  
         }
 535  
 
 536  
         /**
 537  
          * Parses a string and returns a boolean. <b>NOTE<b>: Be careful and notice
 538  
          * that this function will return a <code>null</code> if the given string is
 539  
          * not valid.
 540  
          * 
 541  
          * @param rawBoolean
 542  
          *            A string which represents a boolean.
 543  
          * @return The float value (or <code>null</code> if the rawBoolean is empty
 544  
          *         or <code>null</code>).
 545  
          */
 546  
         private Boolean parseBoolean(String rawBoolean) {
 547  16
                 return (rawBoolean != null && rawBoolean.length() > 0) ? Boolean
 548  
                                 .valueOf(rawBoolean) : Boolean.FALSE;
 549  
         }
 550  
 }