All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xins.client.XINSCallResultParser Maven / Gradle / Ivy

There is a newer version: 3.0
Show newest version
/*
 * $Id: XINSCallResultParser.java,v 1.67 2008/07/04 10:22:49 agoubard Exp $
 *
 * Copyright 2003-2008 Online Breedband B.V.
 * See the COPYRIGHT file for redistribution and use restrictions.
 */
package org.xins.client;

import java.io.ByteArrayInputStream;
import java.util.Iterator;
import org.xins.common.MandatoryArgumentChecker;
import org.xins.common.Utils;
import org.xins.common.collections.BasicPropertyReader;
import org.xins.common.collections.PropertyReader;
import org.xins.common.text.ParseException;
import org.xins.common.text.TextUtils;
import org.xins.common.xml.Element;
import org.xins.common.xml.ElementParser;

/**
 * XINS call result parser. XML is parsed to produce a {@link XINSCallResult}
 * object.
 *
 * 

The root element in the XML must be of type result. Inside * this element, param elements optionally define parameters and * an optional data element defines a data section. * *

If the result element contains an errorcode or a * code attribute, then the value of the attribute is interpreted * as the error code. If both these attributes are set and conflicting, then * this is considered a showstopper. * *

TODO: Describe rest of parse process. * *

Note: This parser is * XML Namespaces-aware. * * @version $Revision: 1.67 $ $Date: 2008/07/04 10:22:49 $ * * @author Anthony Goubard * @author Ernst de Haan * * @since XINS 1.0.0 */ public class XINSCallResultParser { /** * The parser used to parse the XML. */ private final ElementParser _parser; /** * Constructs a new XINSCallResultParser. */ public XINSCallResultParser() { _parser = new ElementParser(); } /** * Parses the given XML string to create a XINSCallResultData * object. * * @param xml * the XML to be parsed, not null. * * @return * the parsed result of the call, not null. * * @throws IllegalArgumentException * if xml == null. * * @throws ParseException * if the specified string is not valid XML or if it is not a valid XINS * API function call result. */ public XINSCallResultData parse(byte[] xml) throws IllegalArgumentException, ParseException { // Check preconditions MandatoryArgumentChecker.check("xml", xml); ByteArrayInputStream stream = null; try { // Convert the byte array to an input stream stream = new ByteArrayInputStream(xml); Element resultElement = _parser.parse(stream); return new XINSCallResultDataImpl(resultElement); } catch (Throwable exception) { // Log: Parsing failed String detail = exception.getMessage(); Log.log_2205(exception, detail); // Include the exception message in our error message, if any String message = "Unable to convert the specified string to XML."; if (detail != null) { detail = detail.trim(); if (detail.length() > 0) { message = "Unable to convert the specified string to XML: " + detail; } } // Throw exception with message, and register cause exception throw new ParseException(message, exception, detail); // Always dispose the ByteArrayInputStream } finally { if (stream != null) { try { stream.close(); } catch (Throwable exception) { Utils.logProgrammingError(exception); } } } } /** * SAX event handler that will parse the result from a call to a XINS * service. * * @version $Revision: 1.67 $ $Date: 2008/07/04 10:22:49 $ * @author Anthony Goubard * @author Ernst de Haan */ private static class XINSCallResultDataImpl implements XINSCallResultData { /** * The error code returned by the function or null, if no * error code is returned. * *

The value will never return an empty string, so if the result is * not null, then it is safe to assume the length of the * string is at least 1 character. */ private String _errorCode; /** * The list of the parameters (name/value) returned by the function. * This field is null if there is no output parameters returned. */ private BasicPropertyReader _parameters; /** * The data section of the result, can be null. */ private Element _dataSection; /** * Constructs a new XINSCallResultDataImpl instance. * * @param resultElement * the parsed result, cannot be null. * * @throws ParseException * if the parse XML does not match the XINS protocol. */ private XINSCallResultDataImpl(Element resultElement) throws ParseException { if (!"result".equals(resultElement.getLocalName())) { String detail = "Incorrect root element '" + resultElement.getLocalName() + "'. Excpected 'result'."; throw new ParseException(detail); } if (resultElement.getNamespaceURI() != null) { String detail = "No namespace is allowed for the 'result' element. The namespace used is '" + resultElement.getNamespaceURI() + "'."; throw new ParseException(detail); } if (resultElement.getText() != null && !resultElement.getText().trim().equals("")) { String detail = "No PCDATA is allowed for the 'result' element. The PCDATA returned is '" + resultElement.getText() + "'."; throw new ParseException(detail); } // Get and check the error code if any. _errorCode = resultElement.getAttribute("errorcode"); String oldErrorCode = resultElement.getAttribute("code"); if (TextUtils.isEmpty(_errorCode) && !TextUtils.isEmpty(oldErrorCode)) { _errorCode = oldErrorCode; } if (!TextUtils.isEmpty(_errorCode) && !TextUtils.isEmpty(oldErrorCode) && !_errorCode.equals(oldErrorCode)) { // NOTE: No need to log here. This will be logged already in // Logdoc log message 2205. String detail = "Found conflicting duplicate value for the " + "error code, since attribute errorcode=\"" + _errorCode + "\", while attribute code=\"" + oldErrorCode + "\"."; throw new ParseException(detail); } // Get and check the parameters, if any. Iterator itParamElements = resultElement.getChildElements("param").iterator(); while (itParamElements.hasNext()) { Element nextParam = (Element) itParamElements.next(); String paramName = nextParam.getAttribute("name"); if (TextUtils.isEmpty(paramName)) { throw new ParseException("No parameter name specified for a parameter: " + nextParam.toString()); } String paramValue = nextParam.getText(); if (_parameters != null && _parameters.get(paramName) != null && !_parameters.get(paramName).equals(paramValue)) { String detail = "Duplicate output parameter '" + paramName + "'with different values: '" + _parameters.get(paramName) + "' and '" + paramValue + "'."; throw new ParseException(detail); } if (!TextUtils.isEmpty(paramValue) && nextParam.getNamespaceURI() == null) { if (_parameters == null) { _parameters = new BasicPropertyReader(); } _parameters.set(paramName, paramValue); } } // Get the data section, if any. if (resultElement.getChildElements("data").size() > 0) { _dataSection = resultElement.getUniqueChildElement("data"); } } /** * Returns the error code. If null is returned the call was * successful and thus no error code was returned. Otherwise the call * was unsuccessful. * *

This method will never return an empty string, so if the result is * not null, then it is safe to assume the length of the * string is at least 1 character. * * @return * the returned error code, or null if the call was * successful. */ public String getErrorCode() { return _errorCode; } /** * Get the parameters returned by the function. * * @return * the parameters (name/value) or null if the function * does not have any parameters. */ public PropertyReader getParameters() { return _parameters; } /** * Get the data element returned by the function if any. * * @return * the data element, or null if the function did not * return any data element. */ public Element getDataElement() { return _dataSection; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy