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/modelbuilders/ReplyModelBuilder.java $
27   * $Id: ReplyModelBuilder.java 8697 2011-09-02 10:33:55Z chg@lakeside.dk $
28   */
29  package dk.sosi.seal.modelbuilders;
30  
31  import dk.sosi.seal.SOSIFactory;
32  import dk.sosi.seal.model.Reply;
33  import dk.sosi.seal.model.SignatureUtil;
34  import dk.sosi.seal.model.constants.*;
35  import dk.sosi.seal.xml.XmlUtil;
36  import org.w3c.dom.Document;
37  import org.w3c.dom.Element;
38  
39  /**
40   * Build the Model assuming compliance with DGWS 1.0 format
41   *
42   * @author Jan Riis
43   * @author $LastChangedBy: chg@lakeside.dk $
44   * @since 1.0
45   */
46  public class ReplyModelBuilder extends MessageModelBuilder {
47  
48  	public ReplyModelBuilder(SOSIFactory fac) {
49  		super(fac);
50  	}
51  
52  	/**
53  	 * Builds a Reply objects from a DOM document.
54  	 *
55  	 * @param doc
56  	 *            The DOM document used for the Reply.
57  	 */
58  	public Reply buildModel(Document doc) throws ModelBuildException {
59  
60  		ModelPrefixResolver prefixResolver = new ModelPrefixResolver();
61  
62  		// Get soap:Header
63  		Element elmSoapHeader = XmlUtil.selectSingleElement(doc, "//" + NameSpaces.NS_SOAP + ":Envelope/" + NameSpaces.NS_SOAP + ":Header", prefixResolver);
64  		// Get creation date
65  		Element elmCreated = XmlUtil.selectSingleElement(elmSoapHeader, NameSpaces.NS_WSSE + ":Security/" + NameSpaces.NS_WSU + ":Timestamp/" + NameSpaces.NS_WSU + ":Created", prefixResolver);
66  
67  		String xmlTimestamp = XmlUtil.getTextNodeValue(elmCreated);
68  		String dgwsVersion = XmlUtil.isZuluTimeFormat(xmlTimestamp) ? DGWSConstants.VERSION_1_0_1 : DGWSConstants.VERSION_1_0;
69  
70  
71  		Element elmMedcomHeader = XmlUtil.selectSingleElement(elmSoapHeader, MedComTags.HEADER_PREFIXED, prefixResolver);
72  		// Get medcom:Linking
73  		Element elmLinking = XmlUtil.selectSingleElement(elmMedcomHeader, MedComTags.LINKING_PREFIXED, prefixResolver);
74  		// Get the values of the (potentially) 3 elements in the medcom:Linking
75  		// root
76  		String inResponseToMessageID = null;
77  		String flowID = null;
78  
79  		Element elmInResponseToMessageId = XmlUtil.selectSingleElement(elmLinking, MedComTags.IN_RESPONSE_TO_MESSAGE_ID_PREFIXED, prefixResolver);
80  		if (elmInResponseToMessageId != null) {
81  			inResponseToMessageID = XmlUtil.getTextNodeValue(elmInResponseToMessageId);
82  		}
83  		Element elmFlowID = XmlUtil.selectSingleElement(elmLinking, MedComTags.FLOW_ID_PREFIXED, prefixResolver);
84  		if (elmFlowID != null) {
85  			flowID = XmlUtil.getTextNodeValue(elmFlowID);
86  		}
87  
88  		// medcom:FlowStatus
89  		Element elmFlowStatus, elmMedcomFaultCode, elmFaultString, elmFaultCode;
90  		Reply reply;
91  
92  		elmFlowStatus = XmlUtil.selectSingleElement(elmMedcomHeader, MedComTags.FLOW_STATUS_PREFIXED, prefixResolver);
93  
94  		if (elmFlowStatus == null) {
95  			// This could be a fault. Check for soap:Fault in the body.
96  			Element fault = XmlUtil.selectSingleElement(doc, "//" + SOAPTags.BODY_PREFIXED + '/' + SOAPTags.FAULT_PREFIXED, prefixResolver);
97  			if (fault == null) {
98  				throw new ModelBuildException("No " + MedComTags.FLOW_STATUS_PREFIXED + " present in document and no " + SOAPTags.FAULT_PREFIXED + " in "
99  						+ SOAPTags.BODY_PREFIXED + "!");
100 			}
101 
102 			elmFaultCode = XmlUtil.selectSingleElement(fault,SOAPTags.FAULTCODE, prefixResolver);
103 			elmMedcomFaultCode = XmlUtil.selectSingleElement(fault, SOAPTags.DETAIL + '/' + MedComTags.FAULT_CODE_PREFIXED, prefixResolver);
104 			elmFaultString = XmlUtil.selectSingleElement(fault, SOAPTags.FAULTSTRING, prefixResolver);
105 
106 			if (elmFaultCode == null)
107 				throw new ModelBuildException("No " + SOAPTags.FAULTCODE + " in " + SOAPTags.FAULT_PREFIXED);
108 
109 			if (elmMedcomFaultCode == null)
110 				throw new ModelBuildException("No " + MedComTags.FAULT_CODE_PREFIXED + " in " + SOAPTags.FAULT_PREFIXED);
111 
112 			if (elmFaultString == null)
113 				throw new ModelBuildException("No " + SOAPTags.FAULTSTRING + " in " + SOAPTags.FAULT_PREFIXED);
114 
115 			reply = factory.createNewErrorReply(dgwsVersion, inResponseToMessageID, flowID, XmlUtil.getTextNodeValue(elmMedcomFaultCode),
116 					XmlUtil.getTextNodeValue(elmFaultString));
117 		} else {
118 			reply = factory.createNewReply(dgwsVersion, inResponseToMessageID, flowID, XmlUtil.getTextNodeValue(elmFlowStatus));
119 		}
120 
121 		// Message parameters
122 		super.buildModel(reply, doc);
123 
124 		// Validate Signature
125 		SignatureUtil.validateAllSignatures(reply, doc.getElementsByTagNameNS(NameSpaces.DSIG_SCHEMA, DSTags.SIGNATURE), factory.getFederation(), factory.getCredentialVault(),true);
126 
127 		return reply;
128 	}
129 }