|
1 /* |
|
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.xml.internal.ws.policy.sourcemodel.attach; |
|
27 |
|
28 import com.sun.xml.internal.ws.policy.Policy; |
|
29 import com.sun.xml.internal.ws.policy.PolicyConstants; |
|
30 import com.sun.xml.internal.ws.policy.PolicyException; |
|
31 import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages; |
|
32 import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger; |
|
33 import com.sun.xml.internal.ws.policy.sourcemodel.PolicyModelTranslator; |
|
34 import com.sun.xml.internal.ws.policy.sourcemodel.PolicyModelUnmarshaller; |
|
35 import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel; |
|
36 |
|
37 import java.io.Reader; |
|
38 import java.net.URI; |
|
39 import java.net.URISyntaxException; |
|
40 import java.util.Collections; |
|
41 import java.util.HashMap; |
|
42 import java.util.Map; |
|
43 import javax.xml.namespace.QName; |
|
44 import javax.xml.stream.Location; |
|
45 import javax.xml.stream.XMLEventReader; |
|
46 import javax.xml.stream.XMLInputFactory; |
|
47 import javax.xml.stream.XMLStreamConstants; |
|
48 import javax.xml.stream.XMLStreamException; |
|
49 import javax.xml.stream.events.Characters; |
|
50 import javax.xml.stream.events.EndElement; |
|
51 import javax.xml.stream.events.StartElement; |
|
52 import javax.xml.stream.events.XMLEvent; |
|
53 |
|
54 /** |
|
55 * Unmarshal external policy attachments. |
|
56 * |
|
57 * @author Fabian Ritzmann |
|
58 */ |
|
59 public class ExternalAttachmentsUnmarshaller { |
|
60 |
|
61 private static final PolicyLogger LOGGER = PolicyLogger.getLogger(ExternalAttachmentsUnmarshaller.class); |
|
62 |
|
63 public static final URI BINDING_ID; |
|
64 public static final URI BINDING_OPERATION_ID; |
|
65 public static final URI BINDING_OPERATION_INPUT_ID; |
|
66 public static final URI BINDING_OPERATION_OUTPUT_ID; |
|
67 public static final URI BINDING_OPERATION_FAULT_ID; |
|
68 |
|
69 static { |
|
70 try { |
|
71 BINDING_ID = new URI("urn:uuid:c9bef600-0d7a-11de-abc1-0002a5d5c51b"); |
|
72 BINDING_OPERATION_ID = new URI("urn:uuid:62e66b60-0d7b-11de-a1a2-0002a5d5c51b"); |
|
73 BINDING_OPERATION_INPUT_ID = new URI("urn:uuid:730d8d20-0d7b-11de-84e9-0002a5d5c51b"); |
|
74 BINDING_OPERATION_OUTPUT_ID = new URI("urn:uuid:85b0f980-0d7b-11de-8e9d-0002a5d5c51b"); |
|
75 BINDING_OPERATION_FAULT_ID = new URI("urn:uuid:917cb060-0d7b-11de-9e80-0002a5d5c51b"); |
|
76 } catch (URISyntaxException e) { |
|
77 throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0094_INVALID_URN()), e); |
|
78 } |
|
79 } |
|
80 |
|
81 private static final QName POLICY_ATTACHMENT = new QName("http://www.w3.org/ns/ws-policy", "PolicyAttachment"); |
|
82 private static final QName APPLIES_TO = new QName("http://www.w3.org/ns/ws-policy", "AppliesTo"); |
|
83 private static final QName POLICY = new QName("http://www.w3.org/ns/ws-policy", "Policy"); |
|
84 private static final QName URI = new QName("http://www.w3.org/ns/ws-policy", "URI"); |
|
85 private static final QName POLICIES = new QName(PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "Policies"); |
|
86 private static final ContextClassloaderLocal<XMLInputFactory> XML_INPUT_FACTORY = new ContextClassloaderLocal<XMLInputFactory>() { |
|
87 @Override |
|
88 protected XMLInputFactory initialValue() throws Exception { |
|
89 return XMLInputFactory.newInstance(); |
|
90 } |
|
91 }; |
|
92 |
|
93 private static final PolicyModelUnmarshaller POLICY_UNMARSHALLER = PolicyModelUnmarshaller.getXmlUnmarshaller(); |
|
94 |
|
95 private final Map<URI, Policy> map = new HashMap<URI, Policy>(); |
|
96 private URI currentUri = null; |
|
97 private Policy currentPolicy = null; |
|
98 |
|
99 public static Map<URI, Policy> unmarshal(final Reader source) throws PolicyException { |
|
100 LOGGER.entering(source); |
|
101 try { |
|
102 XMLEventReader reader = XML_INPUT_FACTORY.get().createXMLEventReader(source); |
|
103 ExternalAttachmentsUnmarshaller instance = new ExternalAttachmentsUnmarshaller(); |
|
104 final Map<URI, Policy> map = instance.unmarshal(reader, null); |
|
105 LOGGER.exiting(map); |
|
106 return Collections.unmodifiableMap(map); |
|
107 } catch (XMLStreamException ex) { |
|
108 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0086_FAILED_CREATE_READER(source)), ex); |
|
109 } |
|
110 } |
|
111 |
|
112 private Map<URI, Policy> unmarshal(final XMLEventReader reader, final StartElement parentElement) throws PolicyException { |
|
113 XMLEvent event = null; |
|
114 while (reader.hasNext()) { |
|
115 try { |
|
116 event = reader.peek(); |
|
117 switch (event.getEventType()) { |
|
118 case XMLStreamConstants.START_DOCUMENT: |
|
119 case XMLStreamConstants.COMMENT: |
|
120 reader.nextEvent(); |
|
121 break; |
|
122 |
|
123 case XMLStreamConstants.CHARACTERS: |
|
124 processCharacters(event.asCharacters(), parentElement, map); |
|
125 reader.nextEvent(); |
|
126 break; |
|
127 |
|
128 case XMLStreamConstants.END_ELEMENT: |
|
129 processEndTag(event.asEndElement(), parentElement); |
|
130 reader.nextEvent(); |
|
131 return map; |
|
132 |
|
133 case XMLStreamConstants.START_ELEMENT: |
|
134 final StartElement element = event.asStartElement(); |
|
135 processStartTag(element, parentElement, reader, map); |
|
136 break; |
|
137 |
|
138 case XMLStreamConstants.END_DOCUMENT: |
|
139 return map; |
|
140 |
|
141 default: |
|
142 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0087_UNKNOWN_EVENT(event))); |
|
143 } |
|
144 } catch (XMLStreamException e) { |
|
145 final Location location = event == null ? null : event.getLocation(); |
|
146 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0088_FAILED_PARSE(location)), e); |
|
147 } |
|
148 } |
|
149 return map; |
|
150 } |
|
151 |
|
152 private void processStartTag(final StartElement element, final StartElement parent, |
|
153 final XMLEventReader reader, final Map<URI, Policy> map) |
|
154 throws PolicyException { |
|
155 try { |
|
156 final QName name = element.getName(); |
|
157 if (parent == null) { |
|
158 if (!name.equals(POLICIES)) { |
|
159 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<Policies>", name, element.getLocation()))); |
|
160 } |
|
161 } else { |
|
162 final QName parentName = parent.getName(); |
|
163 if (parentName.equals(POLICIES)) { |
|
164 if (!name.equals(POLICY_ATTACHMENT)) { |
|
165 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<PolicyAttachment>", name, element.getLocation()))); |
|
166 } |
|
167 } else if (parentName.equals(POLICY_ATTACHMENT)) { |
|
168 if (name.equals(POLICY)) { |
|
169 readPolicy(reader); |
|
170 return; |
|
171 } else if (!name.equals(APPLIES_TO)) { |
|
172 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<AppliesTo> or <Policy>", name, element.getLocation()))); |
|
173 } |
|
174 } else if (parentName.equals(APPLIES_TO)) { |
|
175 if (!name.equals(URI)) { |
|
176 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<URI>", name, element.getLocation()))); |
|
177 } |
|
178 } else { |
|
179 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0090_UNEXPECTED_ELEMENT(name, element.getLocation()))); |
|
180 } |
|
181 } |
|
182 reader.nextEvent(); |
|
183 this.unmarshal(reader, element); |
|
184 } catch (XMLStreamException e) { |
|
185 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0088_FAILED_PARSE(element.getLocation()), e)); |
|
186 } |
|
187 } |
|
188 |
|
189 private void readPolicy(final XMLEventReader reader) throws PolicyException { |
|
190 final PolicySourceModel policyModel = POLICY_UNMARSHALLER.unmarshalModel(reader); |
|
191 final PolicyModelTranslator translator = PolicyModelTranslator.getTranslator(); |
|
192 final Policy policy = translator.translate(policyModel); |
|
193 if (this.currentUri != null) { |
|
194 map.put(this.currentUri, policy); |
|
195 this.currentUri = null; |
|
196 this.currentPolicy = null; |
|
197 } |
|
198 else { |
|
199 this.currentPolicy = policy; |
|
200 } |
|
201 } |
|
202 |
|
203 private void processEndTag(EndElement element, StartElement startElement) throws PolicyException { |
|
204 checkEndTagName(startElement.getName(), element); |
|
205 } |
|
206 |
|
207 private void checkEndTagName(final QName expectedName, final EndElement element) throws PolicyException { |
|
208 final QName actualName = element.getName(); |
|
209 if (!expectedName.equals(actualName)) { |
|
210 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0091_END_ELEMENT_NO_MATCH(expectedName, element, element.getLocation()))); |
|
211 } |
|
212 |
|
213 } |
|
214 |
|
215 private void processCharacters(final Characters chars, final StartElement currentElement, final Map<URI, Policy> map) |
|
216 throws PolicyException { |
|
217 if (chars.isWhiteSpace()) { |
|
218 return; |
|
219 } |
|
220 else { |
|
221 final String data = chars.getData(); |
|
222 if ((currentElement != null) && URI.equals(currentElement.getName())) { |
|
223 processUri(chars, map); |
|
224 return; |
|
225 } else { |
|
226 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0092_CHARACTER_DATA_UNEXPECTED(currentElement, data, chars.getLocation()))); |
|
227 } |
|
228 |
|
229 } |
|
230 } |
|
231 |
|
232 private void processUri(final Characters chars, final Map<URI, Policy> map) throws PolicyException { |
|
233 final String data = chars.getData().trim(); |
|
234 try { |
|
235 final URI uri = new URI(data); |
|
236 if (this.currentPolicy != null) { |
|
237 map.put(uri, this.currentPolicy); |
|
238 this.currentUri = null; |
|
239 this.currentPolicy = null; |
|
240 } else { |
|
241 this.currentUri = uri; |
|
242 } |
|
243 } catch (URISyntaxException e) { |
|
244 throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0093_INVALID_URI(data, chars.getLocation())), e); |
|
245 } |
|
246 } |
|
247 |
|
248 } |