1 /* 2 * Copyright (C) 2013 4th Line GmbH, Switzerland 3 * 4 * The contents of this file are subject to the terms of either the GNU 5 * Lesser General Public License Version 2 or later ("LGPL") or the 6 * Common Development and Distribution License Version 1 or later 7 * ("CDDL") (collectively, the "License"). You may not use this file 8 * except in compliance with the License. See LICENSE.txt for more 9 * information. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 */ 15 16 package org.fourthline.cling.protocol; 17 18 import org.fourthline.cling.UpnpService; 19 import org.fourthline.cling.model.message.StreamRequestMessage; 20 import org.fourthline.cling.model.message.StreamResponseMessage; 21 import org.fourthline.cling.model.profile.RemoteClientInfo; 22 import org.fourthline.cling.transport.RouterException; 23 24 import java.util.logging.Logger; 25 26 /** 27 * Supertype for all synchronously executing protocols, handling reception of UPnP messages and return a response. 28 * <p> 29 * After instantiation by the {@link ProtocolFactory}, this protocol <code>run()</code>s and 30 * calls its own {@link #waitBeforeExecution()} method. By default, the protocol does not wait 31 * before then proceeding with {@link #executeSync()}. 32 * </p> 33 * <p> 34 * The returned response will be available to the client of this protocol. The 35 * client will then call either {@link #responseSent(org.fourthline.cling.model.message.StreamResponseMessage)} 36 * or {@link #responseException(Throwable)}, depending on whether the response was successfully 37 * delivered. The protocol can override these methods to decide if the whole procedure it is 38 * implementing was successful or not, including not only creation but also delivery of the response. 39 * </p> 40 * 41 * @param <IN> The type of incoming UPnP message handled by this protocol. 42 * @param <OUT> The type of response UPnP message created by this protocol. 43 * 44 * @author Christian Bauer 45 */ 46 public abstract class ReceivingSync<IN extends StreamRequestMessage, OUT extends StreamResponseMessage> extends ReceivingAsync<IN> { 47 48 final private static Logger log = Logger.getLogger(UpnpService.class.getName()); 49 50 final protected RemoteClientInfo remoteClientInfo; 51 protected OUT outputMessage; 52 53 protected ReceivingSync(UpnpService upnpService, IN inputMessage) { 54 super(upnpService, inputMessage); 55 this.remoteClientInfo = new RemoteClientInfo(inputMessage); 56 } 57 58 public OUT getOutputMessage() { 59 return outputMessage; 60 } 61 62 final protected void execute() throws RouterException { 63 outputMessage = executeSync(); 64 65 if (outputMessage != null && getRemoteClientInfo().getExtraResponseHeaders().size() > 0) { 66 log.fine("Setting extra headers on response message: " + getRemoteClientInfo().getExtraResponseHeaders().size()); 67 outputMessage.getHeaders().putAll(getRemoteClientInfo().getExtraResponseHeaders()); 68 } 69 } 70 71 protected abstract OUT executeSync() throws RouterException; 72 73 /** 74 * Called by the client of this protocol after the returned response has been successfully delivered. 75 * <p> 76 * NOOP by default. 77 * </p> 78 */ 79 public void responseSent(StreamResponseMessage responseMessage) { 80 } 81 82 /** 83 * Called by the client of this protocol if the returned response was not delivered. 84 * <p> 85 * NOOP by default. 86 * </p> 87 * 88 * @param t The reason why the response wasn't delivered. 89 */ 90 public void responseException(Throwable t) { 91 } 92 93 public RemoteClientInfo getRemoteClientInfo() { 94 return remoteClientInfo; 95 } 96 97 @Override 98 public String toString() { 99 return "(" + getClass().getSimpleName() + ")"; 100 } 101 102 }