1 /*
2 * The MIT License
3 *
4 * Original work sponsored and donated by National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
5 *
6 * Copyright (C) 2011 National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy of
9 * this software and associated documentation files (the "Software"), to deal in
10 * the Software without restriction, including without limitation the rights to
11 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is furnished to do
13 * so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *
26 * $HeadURL: https://svn.softwareborsen.dk/sosi/trunk/modules/seal/src/main/java/dk/sosi/seal/model/Message.java $
27 * $Id: Message.java 8697 2011-09-02 10:33:55Z chg@lakeside.dk $
28 */
29 package dk.sosi.seal.model;
30
31 import dk.sosi.seal.SOSIFactory;
32 import dk.sosi.seal.model.constants.DGWSConstants;
33 import dk.sosi.seal.vault.CredentialVault;
34 import dk.sosi.seal.xml.XmlUtil;
35 import org.w3c.dom.Document;
36 import org.w3c.dom.Element;
37
38 import java.util.ArrayList;
39 import java.util.Date;
40 import java.util.List;
41
42 /**
43 * The superclass for all SOSI messages.
44 *
45 * @author Jan Riis
46 * @author $LastChangedBy: chg@lakeside.dk $
47 * @since 1.0
48 */
49 public abstract class Message {
50
51 private Date creationDate = new Date();
52 private IDCard idCard;
53
54 private String messageID;
55 private String flowID;
56 private String dgwsVersion;
57
58 private Element body = null;
59 private List<Element> nonSOSIHeaders = null;
60
61 // Back reference to the factory that created this instance.
62 private final SOSIFactory factory;
63 protected IDCardValidator validator;
64 protected boolean isFault;
65
66 Message(String dgwsVersion, String flowID, SOSIFactory factory) {
67 super();
68 if(!DGWSConstants.SUPPORTED_VERSIONS.contains(dgwsVersion))
69 throw new ModelException("DGWS version '" + dgwsVersion + "' not supported. Supported versions are: " + DGWSConstants.SUPPORTED_VERSIONS);
70 this.dgwsVersion = dgwsVersion;
71 this.validator = new IDCardValidator();
72 this.flowID = flowID;
73 this.messageID = XmlUtil.createNonce();
74 this.factory = factory;
75 }
76
77 Message(String dgwsVersion, SOSIFactory factory) {
78 this(dgwsVersion, null, factory);
79 }
80
81 /**
82 * Returns the content of soap:body, or <code>null</code> if none set.
83 */
84 public Element getBody() {
85 return body;
86 }
87
88 /**
89 * Sets the content of soap:body
90 *
91 * @param body
92 * The content of the soap:body element
93 */
94 public void setBody(Element body) {
95 this.body = body;
96 }
97
98 /**
99 * Returns the non sosi headers of soap:header, or <code>null</code> if none set.
100 */
101 public List<Element> getNonSOSIHeaders() {
102 return nonSOSIHeaders;
103 }
104
105 /**
106 * Adds a non sosi header to soap:header
107 *
108 * @param header
109 */
110 public void addNonSOSIHeader(Element header) {
111 if(nonSOSIHeaders == null)
112 nonSOSIHeaders = new ArrayList<Element>();
113 nonSOSIHeaders.add(header);
114 }
115
116 /**
117 * Returns the creation date+time for this message.
118 */
119 public Date getCreationDate() {
120
121 return creationDate;
122 }
123
124 /**
125 * Sets creation date+time for this message.
126 */
127 public void setCreationDate(Date date) {
128
129 creationDate = date;
130 }
131
132 /**
133 * Returns the aggregated <code>IDCard</code> instance (composition)
134 *
135 * @return <code>IDCard</code> or <code>null</code> if the relation is uninitialized.
136 */
137 public IDCard getIDCard() {
138
139 return idCard;
140 }
141
142 /**
143 * Associates a (new) <code>IDCard</code> instance to this message.
144 *
145 * @param newIDCard
146 * the new <code>IDCard</code> to associate.
147 */
148 public void setIDCard(IDCard newIDCard) {
149 if(!isFault())
150 validator.validateIDCard(newIDCard);
151 idCard = newIDCard;
152 }
153
154 /**
155 * Returns a globally unique ID for this message. This attribute is also a nonce that is globally unique (with high propability) within the last 5 minutes window.
156 */
157 public String getMessageID() {
158
159 return messageID;
160 }
161
162 /**
163 * Sets a globally unique ID for this message.
164 */
165 public void setMessageID(String msgID) {
166
167 messageID = msgID;
168 }
169
170 /**
171 * Returns the unique flow ID for this message. This attribute is used when sending correlated messages (e.g. messages in the same message "flow"), and can be used by service providers and consumers to discover messages that are correlated.
172 * <p/>
173 * Many messages may share the same flow ID, whereas the <code>MessageID</code> is unique for this one message. The <code>flowID</code> may be <code>null</code> if flows are not used/supported. In this case, the <code>flowID</code> will have the same value as the <code>messageID</code>.
174 */
175 public String getFlowID() {
176
177 return flowID;
178 }
179
180 /**
181 * Sets a unique flow ID for this message.
182 */
183 public void setFlowID(String flowID) {
184
185 this.flowID = flowID;
186 }
187
188 // ====================================
189 // DOM generation stuff
190 // ====================================
191
192 /**
193 * Returns a DOM representation of this <code>Message</code>. The DOM is essentially a SOAP envelope with a SOSI compliant Header and an empty body. The body must be set afterwards.
194 * <p/>
195 * The DOM representation is regenerated on demand if the message (or composed model elements) are "dirty".
196 */
197 public Document serialize2DOMDocument(Document doc) {
198 CredentialVault credentialVault = null;
199 if(factory != null)
200 credentialVault = factory.getCredentialVault();
201 regenerateDOM(doc, credentialVault);
202 return doc;
203 }
204
205 public Document serialize2DOMDocument() {
206 Document doc = XmlUtil.createEmptyDocument();
207 serialize2DOMDocument(doc);
208 return doc;
209 }
210
211 /**
212 * Regenerates the DOM representation (subclasses).
213 */
214 protected abstract Document regenerateDOM(Document document, CredentialVault vault);
215
216 // ====================================
217 // Overridden methods
218 // ====================================
219
220 /**
221 * @see Object#equals(java.lang.Object)
222 */
223 public boolean equals(Object obj) {
224
225 return obj == this || obj != null && obj.getClass() == getClass() && obj.hashCode() == hashCode() && getDGWSVersion().equals(((Message)obj).getDGWSVersion()) && (getCreationDate().getTime() / 1000 == ((Message)obj).getCreationDate().getTime() / 1000)
226 && ((getIDCard() == null && ((Message)obj).getIDCard() == null) || (getIDCard() != null && getIDCard().equals(((Message)obj).getIDCard()))) && ((getFlowID() == null && ((Message)obj).getFlowID() == null) || (getFlowID() != null && getFlowID().equals(((Message)obj).getFlowID())));
227 }
228
229 /**
230 * @see Object#hashCode()
231 */
232 public int hashCode() {
233
234 return messageID.hashCode();
235 }
236
237 /**
238 * Returns the SOSIFactory.
239 */
240 public SOSIFactory getFactory() {
241
242 return factory;
243 }
244
245 public boolean isFault() {
246
247 return isFault;
248 }
249
250 public String getDGWSVersion() {
251 return dgwsVersion;
252 }
253
254 public void setDGWSVersion(String dgwsVersion) {
255 this.dgwsVersion = dgwsVersion;
256 }
257 }