SOAPFaultDetailImpl.java
/*
** Module : SOAPFaultDetailImpl.java
** Abstract : Implementation for the SOAP-FAULT-DETAIL resource.
**
** Copyright (c) 2013-2017, Golden Code Development Corporation.
**
** -#- -I- --Date-- --------------------------------Description-----------------------------------
** 001 CA 20130216 Created initial version.
** 002 CA 20130221 Added Deletable support. Fixed NAME and TYPE support.
** 003 OM 20130304 Refactored isValid and isUnknown of WrappedResource to valid and unknown.
** 004 CA 20130927 Added LegacyResource annotation, to determine resource type.
** 005 CA 20140104 Added runtime implementation for this resource.
** 006 GES 20171220 Changes to match new silent error mode.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program 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 Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.util;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import com.goldencode.p2j.xml.*;
import com.goldencode.util.*;
/**
* A class for implementing the SOAP-FAULT-DETAIL method and attributes.
*/
@LegacyResource(resource = LegacyResource.SOAP_FAULT_DETAIL)
public class SOAPFaultDetailImpl
extends HandleResource
implements SOAPEntity,
Deletable
{
/** The DOM {@link Node} instance associated with the fault detail. */
private final Element faultDetail;
/** Flag indicating this resource was deleted or not. */
private boolean deleted = false;
/**
* Create a new SOAP Fault detail instance.
*
* @param xml
* The serialized XML payload associated.
*/
SOAPFaultDetailImpl(String xml)
{
// TODO: it looks like 4GL modifies the XML by adding the XMLNS attribute nodes defined at
// the SOAP envelope node, beside the XMLNS declarations necessary for this node.
try
{
Document doc = XmlHelper.parse(new ByteArrayInputStream(xml.getBytes()),
false, null, true);
this.faultDetail = doc.getDocumentElement();
doc.setUserData(XNodeRefImpl.RESTRICTED_DOCUMENT, true, null);
}
catch (ParserConfigurationException | IOException | SAXException e)
{
// this should never happen, as the received XML is read from the SOAP Envelope, which
// is assumed to be valid.
final String msg = "Unable to load SOAP Fault Detail XML: %s";
throw new RuntimeException(String.format(msg, xml), e);
}
}
/**
* Gets the X-NODEREF object that refers to the XML underlying a SOAP-HEADER-ENTRYREF object or
* SOAP-FAULT entry and sets it to the given handle.
* <p>
* This method returns a logical even though the Progress 4GL documentation explicitly states
* otherwise. Actual working code has proven that the original documentation is incorrect.
* This implementation matches the actual runtime behavior of the 4GL.
*
* @param xNode
* The handle where the resource will be set.
*
* @return <code>true</code> if the operation was possible.
*/
public logical getNode(handle xNode)
{
if (xNode._isValid() && xNode.getResource() instanceof XNodeRefImpl)
{
XNodeRefImpl nodeRef = new XNodeRefImpl();
nodeRef.setNode(faultDetail);
xNode.assign(nodeRef);
return new logical(true);
}
// if the passed handle is not a valid X-Noderef, this should throw an error, but there is
// no message recorded/displayed. In NO-ERROR mode, just the ERROR-STATUS:ERROR flag is
// set. This might be related to the fact that the NO-ERROR clause deletes the SOAP Fault
// and the SOAP Fault Detail resources.
if (ErrorManager.isSilentError())
{
// ERROR-STATUS:ERROR flag is set, but no error is recorded
ErrorManager.setPending(true);
}
// TODO: we probably should implement an EM worker for this instead of throwing this
// directly
// just throw an ERROR condition
throw new ErrorConditionException("GET-NODE requires a valid X-NODEREF!");
}
/**
* Returns a LONGCHAR that contains the serialized form of the XML underlying the
* SOAP-HEADER-ENTRYREF or SOAP-FAULT entry.
*
* @return See above.
*/
public longchar getSerialized()
{
longchar lc = new longchar("");
ByteArrayOutputStream output = new ByteArrayOutputStream();
try
{
XmlHelper.write(faultDetail.getOwnerDocument(), output, false, true);
}
catch (IOException e)
{
throw new RuntimeException("Could not serialize SOAP Fault document!", e);
}
lc.assign(output.toString());
return lc;
}
/**
* Reports if this object is valid for use.
*
* @return <code>true</code> if we are valid (can be used).
*/
public boolean valid()
{
return !deleted;
}
/**
* Delete this resource. This just sets the {@link #deleted} flag to {@code true}.
*/
@Override
public void delete()
{
if (deleted)
{
return;
}
this.deleted = true;
}
}