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/MessageModelBuilder.java $
27   * $Id: MessageModelBuilder.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.IDCard;
33  import dk.sosi.seal.model.Message;
34  import dk.sosi.seal.model.Request;
35  import dk.sosi.seal.model.constants.DGWSConstants;
36  import dk.sosi.seal.model.constants.MedComTags;
37  import dk.sosi.seal.model.constants.NameSpaces;
38  import dk.sosi.seal.xml.XmlUtil;
39  import org.w3c.dom.Document;
40  import org.w3c.dom.Element;
41  import org.w3c.dom.Node;
42  import org.w3c.dom.NodeList;
43  
44  import java.text.ParseException;
45  import java.util.Date;
46  
47  /**
48   * Builds Message model objects from a DOM document.
49   *
50   * @author Jan Riis
51   * @author $LastChangedBy: chg@lakeside.dk $
52   * @since 1.0
53   */
54  public abstract class MessageModelBuilder {
55  
56  	protected SOSIFactory factory;
57  
58  	public MessageModelBuilder(SOSIFactory fac) {
59  		super();
60  		factory = fac;
61  	}
62  
63  	/**
64  	 * Builds a Message objects from a DOM document.
65  	 *
66  	 * @param msg
67  	 *            The Message object that must be build.
68  	 * @param doc
69  	 *            The DOM document used for the Message.
70  	 */
71  	protected void buildModel(Message msg, Document doc) throws ModelBuildException {
72  
73  		ModelPrefixResolver prefixResolver = new ModelPrefixResolver();
74  
75  		// Get soap:Header
76  		Element elmSoapHeader = XmlUtil.selectSingleElement(doc, "//" + NameSpaces.NS_SOAP + ":Envelope/" + NameSpaces.NS_SOAP + ":Header", prefixResolver);
77  
78  		// Get creation date
79  		Element elmCreated = XmlUtil.selectSingleElement(elmSoapHeader, NameSpaces.NS_WSSE + ":Security/" + NameSpaces.NS_WSU + ":Timestamp/" + NameSpaces.NS_WSU + ":Created", prefixResolver);
80  
81  		String xmlTimestamp = XmlUtil.getTextNodeValue(elmCreated);
82  		Date created;
83  		try {
84  			created = XmlUtil.fromXMLTimeStamp(xmlTimestamp);
85  		} catch (ParseException e) {
86  			throw new ModelBuildException("Unable to parse timestamp from <wsu:Created>", e);
87  		}
88  		msg.setCreationDate(created);
89  
90  		// DGWS Version
91  		String dgwsVersion = XmlUtil.isZuluTimeFormat(xmlTimestamp) ? DGWSConstants.VERSION_1_0_1 : DGWSConstants.VERSION_1_0;
92  		msg.setDGWSVersion(dgwsVersion);
93  
94  		// IDCard - must be present on all requests
95  		IDCard idCard = new IDCardModelBuilder().buildModel(doc);
96  		if ((idCard == null) && (msg instanceof Request))
97  			throw new ModelBuildException("No IDCard present in Request");
98  
99  		if (idCard != null) msg.setIDCard(idCard);
100 
101 		// MessageID
102 		if (doc.getElementsByTagNameNS(NameSpaces.MEDCOM_SCHEMA, MedComTags.MESSAGE_ID).getLength() > 0) {
103 			String msgID = doc.getElementsByTagNameNS(NameSpaces.MEDCOM_SCHEMA, MedComTags.MESSAGE_ID).item(0).getChildNodes().item(0).getNodeValue();
104 			msg.setMessageID(msgID);
105 		} else {
106 			// SecurityTokenRequest or SecurityTokenResponse
107 			String msgID = ((Element) doc.getElementsByTagNameNS(NameSpaces.WSSE_SCHEMA,"Security").item(0)).getAttribute("id");
108 			msg.setMessageID(msgID);
109 		}
110 
111 		// FlowID
112 		if (doc.getElementsByTagNameNS(NameSpaces.MEDCOM_SCHEMA, MedComTags.FLOW_ID).getLength() > 0) {
113 			NodeList flowIDs = doc.getElementsByTagNameNS(NameSpaces.MEDCOM_SCHEMA, MedComTags.FLOW_ID);
114 			String flowID = flowIDs.item(0).getChildNodes().item(0).getNodeValue();
115 			msg.setFlowID(flowID);
116 		}
117 
118         // Other headers
119         NodeList headerList = doc.getElementsByTagNameNS(NameSpaces.SOAP_SCHEMA,"Header");
120         if (headerList.getLength() > 0) {
121             // get first element child node - we dont want ex. indentation nodes.
122             for (int i = 0; i < headerList.item(0).getChildNodes().getLength(); i++) {
123                 Node n = headerList.item(0).getChildNodes().item(i);
124                 if(n.getNodeType() == Node.ELEMENT_NODE) {
125                     Element e = (Element) n;
126                     if(!("Security".equals(e.getLocalName()) && NameSpaces.WSSE_SCHEMA.equals(e.getNamespaceURI())) &&
127                        !(MedComTags.HEADER.equals(e.getLocalName()) && NameSpaces.MEDCOM_SCHEMA.equals(e.getNamespaceURI()))) {
128                         msg.addNonSOSIHeader(e);
129                     }
130                 }
131             }
132         }
133 
134 		// Body
135 		NodeList bodyList = doc.getElementsByTagNameNS(NameSpaces.SOAP_SCHEMA,"Body");
136 		if (bodyList.getLength() > 0) {
137             // get first element child node - we dont want ex. indentation nodes.
138             for (int i = 0; i < bodyList.item(0).getChildNodes().getLength(); i++) {
139                 if(bodyList.item(0).getChildNodes().item(i).getNodeType() == Node.ELEMENT_NODE) {
140                     msg.setBody((Element)bodyList.item(0).getChildNodes().item(i));
141                     break;
142                 }
143             }
144 		}
145 	}
146 }