/******************************************************************************* * Copyright (c) 2009 MATERNA Information & Communications. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html. For further * project-related information visit http://www.ws4d.org. The most recent * version of the JMEDS framework can be obtained from * http://sourceforge.net/projects/ws4d-javame. ******************************************************************************/ package org.ws4d.java.message; import org.ws4d.java.DPWSFramework; import org.ws4d.java.communication.CommunicationManager; import org.ws4d.java.communication.CommunicationUtil; import org.ws4d.java.constants.ConstantsHelper; import org.ws4d.java.constants.SOAPConstants; import org.ws4d.java.constants.WSAConstants; import org.ws4d.java.constants.WSDConstants; import org.ws4d.java.constants.WSSecurityConstants; import org.ws4d.java.schema.PredefinedSchemaTypes; import org.ws4d.java.service.parameter.ParameterValue; import org.ws4d.java.service.parameter.StringValue; import org.ws4d.java.structures.ArrayList; import org.ws4d.java.structures.DataStructure; import org.ws4d.java.types.LocalizedString; import org.ws4d.java.types.QName; import org.ws4d.java.util.StringUtil; /** * */ public class FaultMessage extends Message { public static final String ACTION_ADDRESSING = WSAConstants.WSA_ACTION_ADDRESSING_FAULT; public static final String ACTION_SOAP = WSAConstants.WSA_ACTION_SOAP_FAULT; public static final String ACTION_WSD = WSDConstants.WSD_ACTION_WSD_FAULT; private QName code; private QName subcode; private QName subsubcode; private DataStructure reason; private ParameterValue detail; public static FaultMessage createActionNotSupportedFault(Message request) { String communicationManagerId = request.getHeader().getCommunicationManagerID(); CommunicationManager comMan = DPWSFramework.getCommunicationManager(request.getHeader().getCommunicationManagerID()); CommunicationUtil comUtil = comMan.getCommunicationUtil(); ConstantsHelper helper = comUtil.getHelper(request.getProtocolInfo().getVersion()); String inputAction = request.getAction().toString(); /* * create a SOAP Exception with code Sender and Subcode * wsa:ActionNotSupported */ FaultMessage fault = new FaultMessage(helper.getWSAActionAddressingFault(), communicationManagerId); fault.setResponseTo(request); fault.setCode(SOAPConstants.SOAP_FAULT_SENDER); // fill in subcode, reason and detail fault.setSubcode(helper.getWSAFaultActionNotSupported()); LocalizedString reason = new LocalizedString("The endpoint at the specified address " + request.getTo() + " doesn't support the requested action " + inputAction + ".", null); fault.addReason(reason); ParameterValue detail = ParameterValue.createElementValue(PredefinedSchemaTypes.WSA_PROBLEM_ACTION); ParameterValue action = detail.get(WSAConstants.WSA_ELEM_ACTION); if (detail.getValueType() == ParameterValue.TYPE_STRING) { StringValue value = (StringValue) action; value.set(inputAction); } fault.setDetail(detail); return fault; } public static FaultMessage createEndpointUnavailableFault(Message message) { String communicationManagerId = message.getHeader().getCommunicationManagerID(); CommunicationManager comMan = DPWSFramework.getCommunicationManager(message.getHeader().getCommunicationManagerID()); CommunicationUtil comUtil = comMan.getCommunicationUtil(); ConstantsHelper helper = comUtil.getHelper(message.getProtocolInfo().getVersion()); FaultMessage fault = new FaultMessage(helper.getWSAActionAddressingFault(), communicationManagerId); fault.setResponseTo(message); // send Fault wsa:EndpointUnavailable fault.setCode(SOAPConstants.SOAP_FAULT_RECEIVER); fault.setSubcode(helper.getWSAfaultEndpointUnavailable()); LocalizedString reason = new LocalizedString("The endpoint at the specified address " + message.getTo() + " is unable to process the message at this time.", null); fault.addReason(reason); return fault; } public static FaultMessage createMessageAddressingHeaderRequired(String communicationManagerId) { FaultMessage fault = new FaultMessage(WSAConstants.WSA_ACTION_ADDRESSING_FAULT, communicationManagerId); // send Fault wsa:MessageAddressingHeaderRequired fault.setCode(SOAPConstants.SOAP_FAULT_SENDER); fault.setSubcode(WSAConstants.WSA_FAULT_MESSAGE_ADDRESSING_HEADER_REQUIRED); LocalizedString reason = new LocalizedString("A required header representing a Message Addressing Property is not present", null); fault.addReason(reason); return fault; } public static FaultMessage createAuthenticationFault(Message message) { String communicationManagerId = message.getHeader().getCommunicationManagerID(); FaultMessage fault = new FaultMessage(WSSecurityConstants.WS_SECURITY, communicationManagerId); fault.setResponseTo(message); fault.setCode(SOAPConstants.SOAP_FAULT_SENDER); fault.setSubcode(WSSecurityConstants.WSSE_FAULT_AUTHENTICATION); LocalizedString reason = new LocalizedString("The security token could not be authenticated or authorized.", null); fault.addReason(reason); return fault; } /** * Crates a new fault message with the given <code>action</code>, which is * expected to be a valid absolute URI. * * @param action the action URI of the fault message */ public FaultMessage(String action, String communicationManagerId) { this(SOAPHeader.createHeader(action, communicationManagerId)); } /** * @param header */ public FaultMessage(SOAPHeader header) { this(header, null, null); } /** * @param header * @param code * @param subcode */ public FaultMessage(SOAPHeader header, QName code, QName subcode) { super(header); this.code = code; this.subcode = subcode; } /* * (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(StringUtil.formatClassName(getClass())); sb.append(" [ header=").append(header); sb.append(", inbound=").append(inbound); sb.append(", code=").append(code); sb.append(", subcode=").append(subcode); sb.append(", subsubcode=").append(subsubcode); sb.append(", reason=").append(reason); sb.append(", detail=").append(detail); sb.append(" ]"); return sb.toString(); } /* * (non-Javadoc) * @see org.ws4d.java.message.DPWSMessage#getType() */ public int getType() { return FAULT_MESSAGE; } /** * Returns the SOAP fault code. * * @return the SOAP fault code */ public QName getCode() { return code; } /** * Returns the SOAP fault subcode. * * @return the SOAP fault subcode */ public QName getSubcode() { return subcode; } /** * Returns the SOAP fault subsubcode. * * @return the SOAP fault subsubcode */ public QName getSubsubcode() { return subsubcode; } /** * Returns the list of reasons. * * @return the list of reasons */ // list of LocalizedStrings public DataStructure getReason() { return reason; } /** * Returns the SOAP fault detail. * * @return the SOAP fault detail */ public ParameterValue getDetail() { return detail; } /** * @param code the code to set */ public void setCode(QName code) { this.code = code; } /** * @param subcode the subcode to set */ public void setSubcode(QName subcode) { this.subcode = subcode; } /** * @param subsubcode the subsubcode to set */ public void setSubsubcode(QName subsubcode) { this.subsubcode = subsubcode; } /** * @param reason the reason to set */ public void setReason(DataStructure reason) { this.reason = reason; } /** * @param detail the detail to set */ public void setDetail(ParameterValue detail) { this.detail = detail; } public void addReason(LocalizedString reason) { if (this.reason == null) { this.reason = new ArrayList(); } this.reason.add(reason); } }