View Javadoc

1   package ca.uhn.hl7v2.hoh.llp;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.io.OutputStream;
6   import java.nio.charset.Charset;
7   
8   import ca.uhn.hl7v2.app.TwoPortService;
9   import ca.uhn.hl7v2.hoh.api.IAuthorizationClientCallback;
10  import ca.uhn.hl7v2.hoh.api.IAuthorizationServerCallback;
11  import ca.uhn.hl7v2.hoh.sign.ISigner;
12  import ca.uhn.hl7v2.hoh.util.ServerRoleEnum;
13  import ca.uhn.hl7v2.llp.HL7Reader;
14  import ca.uhn.hl7v2.llp.HL7Writer;
15  import ca.uhn.hl7v2.llp.LLPException;
16  import ca.uhn.hl7v2.llp.LowerLayerProtocol;
17  
18  /**
19   * <p>
20   * LowerLayerProtocol implementation which use the HL7 over HTTP specification
21   * as a transport layer.
22   * </p>
23   * 
24   * <p>
25   * Note that this implementation has limitations:
26   * <ul>
27   * <li>It will not work on a duel socket server such as {@link TwoPortService}
28   * </ul>
29   * </p>
30   */
31  public class Hl7OverHttpLowerLayerProtocol extends LowerLayerProtocol {
32  
33  	private IAuthorizationClientCallback myAuthorizationClientCallback;
34  	private IAuthorizationServerCallback myAuthorizationServerCallback;
35  	private HohLlpReader myNextReader;
36  	private HohLlpWriter myNextWriter;
37  	private ServerRoleEnum myRole;
38  	private ISigner mySigner;
39  	private String myUriPath = "/";
40  	private Charset myPreferredCharset;
41  	
42  	public Hl7OverHttpLowerLayerProtocol(ServerRoleEnum theRole) {
43  		myRole = theRole;
44  
45  		if (myRole == null) {
46  			throw new NullPointerException("Role can not be null");
47  		}
48  	}
49  	/**
50  	 * @return the authorizationClientCallback
51  	 */
52  	IAuthorizationClientCallback getAuthorizationClientCallback() {
53  		return myAuthorizationClientCallback;
54  	}
55  
56  	/**
57  	 * Provide the authorization callback, if any
58  	 */
59  	IAuthorizationServerCallback getAuthorizationServerCallback() {
60  		return myAuthorizationServerCallback;
61  	}
62  
63  	/**
64  	 * {@inheritDoc}
65  	 */
66  	@Override
67  	public HL7Reader getReader(InputStream theArg0) throws LLPException {
68  		if (myNextReader == null && myNextWriter != null) {
69  			myNextWriter = null;
70  			throw new LLPException("Hl7OverHttpLowerLayerProtocol can not be used with a multi socket implementation");
71  		}
72  		prepareReadersIfNeeded();
73  		HohLlpReader retVal = myNextReader;
74  		try {
75  			retVal.setInputStream(theArg0);
76  		} catch (IOException e) {
77  			throw new LLPException("Failed to set stream: " + e.getMessage(), e);
78  		}
79  
80  		myNextReader = null;
81  		return retVal;
82  	}
83  
84  	/**
85  	 * Returns the server role this protocol implementation is being used for
86  	 */
87  	public ServerRoleEnum getRole() {
88  		return myRole;
89  	}
90  
91  	/**
92  	 * @return The signature profile signer
93  	 * @see #setSigner(ISigner)
94  	 */
95  	ISigner getSigner() {
96  		return mySigner;
97  	}
98  
99  	/**
100 	 * @return The URI to use for this LLP implementation
101 	 * @see #setUriPath(String)
102 	 */
103 	public String getUriPath() {
104 		return myUriPath;
105 	}
106 
107 	/**
108 	 * {@inheritDoc}
109 	 */
110 	@Override
111 	public HL7Writer getWriter(OutputStream theArg0) throws LLPException {
112 		if (myNextReader != null && myNextWriter == null) {
113 			myNextReader = null;
114 			throw new LLPException("Hl7OverHttpLowerLayerProtocol can not be used with a multi socket implementation");
115 		}
116 		prepareReadersIfNeeded();
117 		HohLlpWriter retVal = myNextWriter;
118 		retVal.setPreferredCharset(myPreferredCharset);
119 		try {
120 			retVal.setOutputStream(theArg0);
121 		} catch (IOException e) {
122 			throw new LLPException("Failed to set stream: " + e.getMessage(), e);
123 		}
124 
125 		myNextWriter = null;
126 		return retVal;
127 	}
128 
129 	private void prepareReadersIfNeeded() {
130 		if (myNextReader == null && myNextWriter == null) {
131 			myNextReader = new HohLlpReader(this);
132 			myNextWriter = new HohLlpWriter(this);
133 			myNextReader.setWriter(myNextWriter);
134 		}
135 	}
136 
137 	/**
138 	 * Provides an authorization callback for authorizing incoming requests. This method
139 	 * must only be called of this LLP instance is in {@link ServerRoleEnum#SERVER SERVER} mode.
140 	 */
141 	public void setAuthorizationCallback(IAuthorizationClientCallback theAuthorizationClientCallback) {
142 		if (myRole == ServerRoleEnum.SERVER) {
143 			throw new IllegalStateException("This LLP implementation is in CLIENT mode, so it can not use an authorization callback");
144 		}
145 		myAuthorizationClientCallback = theAuthorizationClientCallback;
146 	}
147 
148 	/**
149 	 * Provides an authorization callback for authorizing incoming requests. This method
150 	 * must only be called of this LLP instance is in {@link ServerRoleEnum#SERVER SERVER} mode.
151 	 */
152 	public void setAuthorizationCallback(IAuthorizationServerCallback theAuthorizationCallback) {
153 		if (myRole == ServerRoleEnum.CLIENT) {
154 			throw new IllegalStateException("This LLP implementation is in CLIENT mode, so it can not use an authorization callback");
155 		}
156 		myAuthorizationServerCallback = theAuthorizationCallback;
157 	}
158 
159 	/**
160 	 * @param theSigner The signature profile signer
161 	 */
162 	public void setSigner(ISigner theSigner) {
163 		mySigner = theSigner;
164 	}
165 
166 	/**
167 	 * The URI path to use for this protocol. The URI path is the portion of the address (URL) which
168 	 * is being accessed which designates the location on the host (i.e. the "path"). By 
169 	 * default this is set to "/" 
170 	 * 
171 	 * @param theUriPath the uri to set
172 	 */
173 	public void setUriPath(String theUriPath) {
174 		myUriPath = theUriPath;
175 	}
176 	
177 	/**
178 	 * Sets the charset which will be used for any initiated outgoing messages. What this
179 	 * means is that if a message is sent as a response (e.g. an ACK) using this LLP,
180 	 * the LLP will ignore the charset provided by this method and will attempt to use
181 	 * the charset used in the original incoming message. On the other hand, if a new
182 	 * outgoing message is transmitted using this LLP (i.e. not an ACK), the charset
183 	 * specified here will be used. 
184 	 */
185 	public void setPreferredCharset(Charset thePreferredCharset) {
186 		myPreferredCharset = thePreferredCharset;
187 	}
188 
189 }