View Javadoc

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 }