/*******************************************************************************
* 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.communication;
import java.io.IOException;
import java.io.OutputStream;
import org.ws4d.java.DPWSFramework;
import org.ws4d.java.communication.monitor.MonitorStreamFactory;
import org.ws4d.java.communication.monitor.MonitoredMessageReceiver;
import org.ws4d.java.communication.monitor.MonitoringContext;
import org.ws4d.java.communication.protocol.http.HTTPResponse;
import org.ws4d.java.communication.protocol.mime.MIMEBodyHeader;
import org.ws4d.java.communication.protocol.mime.MIMEEntityInput;
import org.ws4d.java.communication.protocol.mime.MIMEEntityOutput;
import org.ws4d.java.communication.protocol.mime.MIMEHandler;
import org.ws4d.java.communication.protocol.soap.SOAPResponse;
import org.ws4d.java.communication.protocol.soap.generator.MessageReceiver;
import org.ws4d.java.communication.protocol.soap.generator.SOAPMessageGeneratorFactory;
import org.ws4d.java.constants.SOAPConstants;
import org.ws4d.java.dispatch.MessageInformer;
import org.ws4d.java.message.FaultMessage;
import org.ws4d.java.message.InvokeMessage;
import org.ws4d.java.message.SOAPException;
import org.ws4d.java.message.discovery.ByeMessage;
import org.ws4d.java.message.discovery.HelloMessage;
import org.ws4d.java.message.discovery.ProbeMatchesMessage;
import org.ws4d.java.message.discovery.ProbeMessage;
import org.ws4d.java.message.discovery.ResolveMatchesMessage;
import org.ws4d.java.message.discovery.ResolveMessage;
import org.ws4d.java.message.eventing.GetStatusMessage;
import org.ws4d.java.message.eventing.GetStatusResponseMessage;
import org.ws4d.java.message.eventing.RenewMessage;
import org.ws4d.java.message.eventing.RenewResponseMessage;
import org.ws4d.java.message.eventing.SubscribeMessage;
import org.ws4d.java.message.eventing.SubscribeResponseMessage;
import org.ws4d.java.message.eventing.SubscriptionEndMessage;
import org.ws4d.java.message.eventing.UnsubscribeMessage;
import org.ws4d.java.message.eventing.UnsubscribeResponseMessage;
import org.ws4d.java.message.metadata.GetMessage;
import org.ws4d.java.message.metadata.GetMetadataMessage;
import org.ws4d.java.message.metadata.GetMetadataResponseMessage;
import org.ws4d.java.message.metadata.GetResponseMessage;
import org.ws4d.java.service.OperationDescription;
import org.ws4d.java.service.parameter.ParameterValue;
import org.ws4d.java.structures.HashMap;
import org.ws4d.java.structures.Queue;
import org.ws4d.java.util.ParameterUtil;
/**
*
*/
final class IncomingMIMEReceiver implements MIMEHandler, MessageReceiver {
private static abstract class SimpleMIMEEntityOutput implements MIMEEntityOutput {
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.mime.MIMEEntityOutput#serialize
* (java.io.OutputStream)
*/
public void serialize(OutputStream out) throws IOException {
// do nothing, getHTTPResponse() takes care of everything
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.mime.MIMEBase#getEntityHeader()
*/
public MIMEBodyHeader getEntityHeader() {
// do nothing, getHTTPResponse() takes care of everything
return null;
}
}
private static final MessageInformer MESSAGE_INFORMER = MessageInformer.getInstance();
private final IncomingMessageListener listener;
// key = thread, value = MIMEEntity
private final HashMap responses = new HashMap();
/**
* @param content
* @param protocolData
*/
static void storeMIMEContext(ParameterValue content, ProtocolData protocolData) {
if (content != null && ParameterUtil.hasAttachment(content)) {
ParameterUtil.setAttachmentScope(content, protocolData.getCurrentMIMEContext());
}
}
/**
* @param listener
*/
IncomingMIMEReceiver(IncomingMessageListener listener) {
super();
this.listener = listener;
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.mime.MIMEHandler#handleRequest(org
* .ws4d.java.communication.protocol.mime.MIMEEntityInput,
* org.ws4d.java.structures.Queue, org.ws4d.java.communication.ProtocolData,
* org.ws4d.java.io.monitor.MonitoringContext)
*/
public void handleRequest(MIMEEntityInput part, Queue responseContainer, ProtocolData protocolData, MonitoringContext context) {
final MessageReceiver r;
MonitorStreamFactory monFac = DPWSFramework.getMonitorStreamFactory();
if (monFac != null) {
r = new MonitoredMessageReceiver(this, context);
} else {
r = this;
}
SOAPMessageGeneratorFactory.getInstance().getSOAP2MessageGeneratorForCurrentThread().deliverMessage(part.getBodyInputStream(), r, protocolData);
MIMEEntityOutput response;
synchronized (this.responses) {
response = (MIMEEntityOutput) this.responses.remove(Thread.currentThread());
}
if (response != null) {
responseContainer.enqueue(response);
}
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.mime.MIMEHandler#handleResponse(
* org.ws4d.java.communication.protocol.mime.MIMEEntityInput,
* org.ws4d.java.communication.ProtocolData,
* org.ws4d.java.io.monitor.MonitoringContext)
*/
public void handleResponse(MIMEEntityInput part, ProtocolData protocolData, MonitoringContext context) throws IOException {
// not needed on the server side
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.discovery.HelloMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(HelloMessage hello, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.discovery.ByeMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(ByeMessage bye, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.discovery.ProbeMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(ProbeMessage probe, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.discovery.ProbeMatchesMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(ProbeMatchesMessage probeMatches, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.discovery.ResolveMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(ResolveMessage resolve, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.discovery.ResolveMatchesMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(ResolveMatchesMessage resolveMatches, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.metadata.GetMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(GetMessage get, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.metadata.GetResponseMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(GetResponseMessage getResponse, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.metadata.GetMetadataMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(GetMetadataMessage getMetadata, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.metadata. GetMetadataResponseMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(GetMetadataResponseMessage getMetadataResponse, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.SubscribeMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(SubscribeMessage subscribe, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.SubscribeResponseMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(SubscribeResponseMessage subscribeResponse, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.GetStatusMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(GetStatusMessage getStatus, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.GetStatusResponseMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(GetStatusResponseMessage getStatusResponse, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.RenewMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(RenewMessage renew, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.RenewResponseMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(RenewResponseMessage renewResponse, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.UnsubscribeMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(UnsubscribeMessage unsubscribe, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.UnsubscribeResponseMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(UnsubscribeResponseMessage unsubscribeResponse, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.eventing.SubscriptionEndMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(SubscriptionEndMessage subscriptionEnd, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.invocation.InvokeMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(InvokeMessage invoke, ProtocolData protocolData) {
storeMIMEContext(invoke.getContent(), protocolData);
IncomingSOAPReceiver.markIncoming(invoke);
try {
InvokeMessage responseMessage = listener.handle(invoke, protocolData);
MESSAGE_INFORMER.forwardMessage(invoke, protocolData);
respondWithMessage(responseMessage);
} catch (SOAPException e) {
MESSAGE_INFORMER.forwardMessage(invoke, protocolData);
respondWithFault(e);
}
}
/*
* (non-Javadoc)
* @see org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#
* getOperation(java.lang.String)
*/
public OperationDescription getOperation(String action) {
return listener.getOperation(action);
}
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#receive
* (org.ws4d.java.message.FaultMessage,
* org.ws4d.java.communication.ProtocolData)
*/
public void receive(FaultMessage fault, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#
* receiveFailed(java.lang.Exception,
* org.ws4d.java.communication.ProtocolData)
*/
public void receiveFailed(Exception e, ProtocolData protocolData) {
sendBadRequest();
}
/*
* (non-Javadoc)
* @see org.ws4d.java.communication.protocol.soap.generator.MessageReceiver#
* sendFailed(java.lang.Exception, org.ws4d.java.communication.ProtocolData)
*/
public void sendFailed(Exception e, ProtocolData protocolData) {
/*
* as this receiver will always be used on the server side, it never
* sends requests, thus this method can not get called
*/
}
/**
* @param responseMessage
*/
private void respondWithMessage(final InvokeMessage responseMessage) {
MIMEEntityOutput response;
if (responseMessage != null) {
IncomingSOAPReceiver.markOutgoing(responseMessage);
response = new SimpleMIMEEntityOutput() {
/*
* (non-Javadoc)
* @seeorg.ws4d.java.communication.protocol.mime.MIMEEntity#
* getHTTPResponse()
*/
public HTTPResponse getHTTPResponse() {
return new SOAPResponse(200, responseMessage); // TODO
}
};
synchronized (responses) {
responses.put(Thread.currentThread(), response);
}
}
// DefaultMIMEHandler will send an empty 202 response in that case
}
/**
* @param e
*/
private void respondWithFault(SOAPException e) {
final FaultMessage fault = e.getFault();
IncomingSOAPReceiver.markOutgoing(fault);
MIMEEntityOutput response = new SimpleMIMEEntityOutput() {
/*
* (non-Javadoc)
* @see
* org.ws4d.java.communication.protocol.mime.MIMEEntity#getHTTPResponse
* ()
*/
public HTTPResponse getHTTPResponse() {
if (SOAPConstants.SOAP_FAULT_SENDER.equals(fault.getCode())) {
return new SOAPResponse(400, fault); // TODO
} else {
return new SOAPResponse(500, fault); // TODO
}
}
};
synchronized (responses) {
responses.put(Thread.currentThread(), response);
}
}
private void sendBadRequest() {
/*
* send a HTTP 400 Bad Request, as we don't support MIME packages
* containing other SOAP envelopes than operation invocations
*/
synchronized (responses) {
responses.put(Thread.currentThread(), new SOAPResponse(400, null)); // TODO
}
}
}