Tue, 09 Apr 2013 14:51:13 +0100
8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
5 *
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common Development
8 * and Distribution License("CDDL") (collectively, the "License"). You
9 * may not use this file except in compliance with the License. You can
10 * obtain a copy of the License at
11 * http://glassfish.java.net/public/CDDL+GPL_1_1.html
12 * or packager/legal/LICENSE.txt. See the License for the specific
13 * language governing permissions and limitations under the License.
14 *
15 * When distributing the software, include this License Header Notice in each
16 * file and include the License file at packager/legal/LICENSE.txt.
17 *
18 * GPL Classpath Exception:
19 * Oracle designates this particular file as subject to the "Classpath"
20 * exception as provided by Oracle in the GPL Version 2 section of the License
21 * file that accompanied this code.
22 *
23 * Modifications:
24 * If applicable, add the following below the License Header, with the fields
25 * enclosed by brackets [] replaced by your own identifying information:
26 * "Portions Copyright [year] [name of copyright owner]"
27 *
28 * Contributor(s):
29 * If you wish your version of this file to be governed by only the CDDL or
30 * only the GPL Version 2, indicate your decision by adding "[Contributor]
31 * elects to include this software in this distribution under the [CDDL or GPL
32 * Version 2] license." If you don't indicate a single choice of license, a
33 * recipient has the option to distribute your version of this file under
34 * either the CDDL, the GPL Version 2 or to extend the choice of license to
35 * its licensees as provided above. However, if you add GPL Version 2 code
36 * and therefore, elected the GPL Version 2 license, then the option applies
37 * only if the new code is made subject to such option by the copyright
38 * holder.
39 */
41 package com.oracle.webservices.internal.api.message;
43 import com.sun.istack.internal.NotNull;
44 import com.sun.istack.internal.Nullable;
45 import com.sun.xml.internal.ws.api.message.Packet;
46 import com.sun.xml.internal.ws.client.RequestContext;
47 import com.sun.xml.internal.ws.client.ResponseContext;
49 import javax.xml.ws.WebServiceContext;
51 import java.util.AbstractMap;
52 import java.util.Map.Entry;
53 import java.util.HashSet;
54 import java.util.IdentityHashMap;
55 import java.util.Map;
56 import java.util.Set;
58 /**
59 * {@link PropertySet} that combines properties exposed from multiple
60 * {@link PropertySet}s into one.
61 *
62 * <p>
63 * This implementation allows one {@link PropertySet} to assemble
64 * all properties exposed from other "satellite" {@link PropertySet}s.
65 * (A satellite may itself be a {@link DistributedPropertySet}, so
66 * in general this can form a tree.)
67 *
68 * <p>
69 * This is useful for JAX-WS because the properties we expose to the application
70 * are contributed by different pieces, and therefore we'd like each of them
71 * to have a separate {@link PropertySet} implementation that backs up
72 * the properties. For example, this allows FastInfoset to expose its
73 * set of properties to {@link RequestContext} by using a strongly-typed fields.
74 *
75 * <p>
76 * This is also useful for a client-side transport to expose a bunch of properties
77 * into {@link ResponseContext}. It simply needs to create a {@link PropertySet}
78 * object with methods for each property it wants to expose, and then add that
79 * {@link PropertySet} to {@link Packet}. This allows property values to be
80 * lazily computed (when actually asked by users), thus improving the performance
81 * of the typical case where property values are not asked.
82 *
83 * <p>
84 * A similar benefit applies on the server-side, for a transport to expose
85 * a bunch of properties to {@link WebServiceContext}.
86 *
87 * <p>
88 * To achieve these benefits, access to {@link DistributedPropertySet} is slower
89 * compared to {@link PropertySet} (such as get/set), while adding a satellite
90 * object is relatively fast.
91 *
92 * @author Kohsuke Kawaguchi
93 */
94 public abstract class BaseDistributedPropertySet extends BasePropertySet implements DistributedPropertySet {
96 /**
97 * All {@link PropertySet}s that are bundled into this {@link PropertySet}.
98 */
99 private final Map<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet> satellites
100 = new IdentityHashMap<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet>();
102 private final Map<String, Object> viewthis;
104 public BaseDistributedPropertySet() {
105 this.viewthis = super.createView();
106 }
108 @Override
109 public void addSatellite(@NotNull PropertySet satellite) {
110 addSatellite(satellite.getClass(), satellite);
111 }
113 @Override
114 public void addSatellite(@NotNull Class<? extends com.oracle.webservices.internal.api.message.PropertySet> keyClass, @NotNull PropertySet satellite) {
115 satellites.put(keyClass, satellite);
116 }
118 @Override
119 public void removeSatellite(PropertySet satellite) {
120 satellites.remove(satellite.getClass());
121 }
123 public void copySatelliteInto(@NotNull DistributedPropertySet r) {
124 for (Map.Entry<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet> entry : satellites.entrySet()) {
125 r.addSatellite(entry.getKey(), entry.getValue());
126 }
127 }
129 @Override
130 public void copySatelliteInto(MessageContext r) {
131 copySatelliteInto((DistributedPropertySet)r);
132 }
134 @Override
135 public @Nullable <T extends com.oracle.webservices.internal.api.message.PropertySet> T getSatellite(Class<T> satelliteClass) {
136 T satellite = (T) satellites.get(satelliteClass);
137 if (satellite != null) {
138 return satellite;
139 }
141 for (PropertySet child : satellites.values()) {
142 if (satelliteClass.isInstance(child)) {
143 return satelliteClass.cast(child);
144 }
146 if (DistributedPropertySet.class.isInstance(child)) {
147 satellite = DistributedPropertySet.class.cast(child).getSatellite(satelliteClass);
148 if (satellite != null) {
149 return satellite;
150 }
151 }
152 }
153 return null;
154 }
156 @Override
157 public Map<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, com.oracle.webservices.internal.api.message.PropertySet> getSatellites() {
158 return satellites;
159 }
161 @Override
162 public Object get(Object key) {
163 // check satellites
164 for (PropertySet child : satellites.values()) {
165 if (child.supports(key)) {
166 return child.get(key);
167 }
168 }
170 // otherwise it must be the master
171 return super.get(key);
172 }
174 @Override
175 public Object put(String key, Object value) {
176 // check satellites
177 for (PropertySet child : satellites.values()) {
178 if(child.supports(key)) {
179 return child.put(key,value);
180 }
181 }
183 // otherwise it must be the master
184 return super.put(key,value);
185 }
187 @Override
188 public boolean containsKey(Object key) {
189 if (viewthis.containsKey(key))
190 return true;
191 for (PropertySet child : satellites.values()) {
192 if (child.containsKey(key)) {
193 return true;
194 }
195 }
196 return false;
197 }
199 @Override
200 public boolean supports(Object key) {
201 // check satellites
202 for (PropertySet child : satellites.values()) {
203 if (child.supports(key)) {
204 return true;
205 }
206 }
208 return super.supports(key);
209 }
211 @Override
212 public Object remove(Object key) {
213 // check satellites
214 for (PropertySet child : satellites.values()) {
215 if (child.supports(key)) {
216 return child.remove(key);
217 }
218 }
220 return super.remove(key);
221 }
223 @Override
224 protected void createEntrySet(Set<Entry<String, Object>> core) {
225 super.createEntrySet(core);
226 for (PropertySet child : satellites.values()) {
227 ((BasePropertySet) child).createEntrySet(core);
228 }
229 }
231 protected Map<String, Object> asMapLocal() {
232 return viewthis;
233 }
235 protected boolean supportsLocal(Object key) {
236 return super.supports(key);
237 }
239 class DistributedMapView extends AbstractMap<String, Object> {
240 @Override
241 public Object get(Object key) {
242 for (PropertySet child : satellites.values()) {
243 if (child.supports(key)) {
244 return child.get(key);
245 }
246 }
248 return viewthis.get(key);
249 }
251 @Override
252 public int size() {
253 int size = viewthis.size();
254 for (PropertySet child : satellites.values()) {
255 size += child.asMap().size();
256 }
257 return size;
258 }
260 @Override
261 public boolean containsKey(Object key) {
262 if (viewthis.containsKey(key))
263 return true;
264 for (PropertySet child : satellites.values()) {
265 if (child.containsKey(key))
266 return true;
267 }
268 return false;
269 }
271 @Override
272 public Set<Entry<String, Object>> entrySet() {
273 Set<Entry<String, Object>> entries = new HashSet<Entry<String, Object>>();
274 for (PropertySet child : satellites.values()) {
275 for (Entry<String,Object> entry : child.asMap().entrySet()) {
276 // the code below is here to avoid entries.addAll(child.asMap().entrySet()); which works differently on JDK6/7
277 // see DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
278 entries.add(new SimpleImmutableEntry<String, Object>(entry.getKey(), entry.getValue()));
279 }
280 }
281 for (Entry<String,Object> entry : viewthis.entrySet()) {
282 // the code below is here to avoid entries.addAll(child.asMap().entrySet()); which works differently on JDK6/7
283 // see DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
284 entries.add(new SimpleImmutableEntry<String, Object>(entry.getKey(), entry.getValue()));
285 }
287 return entries;
288 }
290 @Override
291 public Object put(String key, Object value) {
292 for (PropertySet child : satellites.values()) {
293 if (child.supports(key)) {
294 return child.put(key, value);
295 }
296 }
298 return viewthis.put(key, value);
299 }
301 @Override
302 public void clear() {
303 satellites.clear();
304 viewthis.clear();
305 }
307 @Override
308 public Object remove(Object key) {
309 for (PropertySet child : satellites.values()) {
310 if (child.supports(key)) {
311 return child.remove(key);
312 }
313 }
315 return viewthis.remove(key);
316 }
317 }
319 @Override
320 protected Map<String, Object> createView() {
321 return new DistributedMapView();
322 }
323 }