Tue, 23 Apr 2013 18:33:20 -0700
8012643: JDK8 b86 source with GPL header errors
Reviewed-by: dholmes, alanb
1 /*
2 * Copyright (c) 1997, 2013, 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 package com.oracle.webservices.internal.api.message;
27 import com.sun.istack.internal.NotNull;
28 import com.sun.istack.internal.Nullable;
29 import com.sun.xml.internal.ws.api.message.Packet;
30 import com.sun.xml.internal.ws.client.RequestContext;
31 import com.sun.xml.internal.ws.client.ResponseContext;
33 import javax.xml.ws.WebServiceContext;
35 import java.util.AbstractMap;
36 import java.util.Map.Entry;
37 import java.util.HashSet;
38 import java.util.IdentityHashMap;
39 import java.util.Map;
40 import java.util.Set;
42 /**
43 * {@link PropertySet} that combines properties exposed from multiple
44 * {@link PropertySet}s into one.
45 *
46 * <p>
47 * This implementation allows one {@link PropertySet} to assemble
48 * all properties exposed from other "satellite" {@link PropertySet}s.
49 * (A satellite may itself be a {@link DistributedPropertySet}, so
50 * in general this can form a tree.)
51 *
52 * <p>
53 * This is useful for JAX-WS because the properties we expose to the application
54 * are contributed by different pieces, and therefore we'd like each of them
55 * to have a separate {@link PropertySet} implementation that backs up
56 * the properties. For example, this allows FastInfoset to expose its
57 * set of properties to {@link RequestContext} by using a strongly-typed fields.
58 *
59 * <p>
60 * This is also useful for a client-side transport to expose a bunch of properties
61 * into {@link ResponseContext}. It simply needs to create a {@link PropertySet}
62 * object with methods for each property it wants to expose, and then add that
63 * {@link PropertySet} to {@link Packet}. This allows property values to be
64 * lazily computed (when actually asked by users), thus improving the performance
65 * of the typical case where property values are not asked.
66 *
67 * <p>
68 * A similar benefit applies on the server-side, for a transport to expose
69 * a bunch of properties to {@link WebServiceContext}.
70 *
71 * <p>
72 * To achieve these benefits, access to {@link DistributedPropertySet} is slower
73 * compared to {@link PropertySet} (such as get/set), while adding a satellite
74 * object is relatively fast.
75 *
76 * @author Kohsuke Kawaguchi
77 */
78 public abstract class BaseDistributedPropertySet extends BasePropertySet implements DistributedPropertySet {
80 /**
81 * All {@link PropertySet}s that are bundled into this {@link PropertySet}.
82 */
83 private final Map<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet> satellites
84 = new IdentityHashMap<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet>();
86 private final Map<String, Object> viewthis;
88 public BaseDistributedPropertySet() {
89 this.viewthis = super.createView();
90 }
92 @Override
93 public void addSatellite(@NotNull PropertySet satellite) {
94 addSatellite(satellite.getClass(), satellite);
95 }
97 @Override
98 public void addSatellite(@NotNull Class<? extends com.oracle.webservices.internal.api.message.PropertySet> keyClass, @NotNull PropertySet satellite) {
99 satellites.put(keyClass, satellite);
100 }
102 @Override
103 public void removeSatellite(PropertySet satellite) {
104 satellites.remove(satellite.getClass());
105 }
107 public void copySatelliteInto(@NotNull DistributedPropertySet r) {
108 for (Map.Entry<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet> entry : satellites.entrySet()) {
109 r.addSatellite(entry.getKey(), entry.getValue());
110 }
111 }
113 @Override
114 public void copySatelliteInto(MessageContext r) {
115 copySatelliteInto((DistributedPropertySet)r);
116 }
118 @Override
119 public @Nullable <T extends com.oracle.webservices.internal.api.message.PropertySet> T getSatellite(Class<T> satelliteClass) {
120 T satellite = (T) satellites.get(satelliteClass);
121 if (satellite != null) {
122 return satellite;
123 }
125 for (PropertySet child : satellites.values()) {
126 if (satelliteClass.isInstance(child)) {
127 return satelliteClass.cast(child);
128 }
130 if (DistributedPropertySet.class.isInstance(child)) {
131 satellite = DistributedPropertySet.class.cast(child).getSatellite(satelliteClass);
132 if (satellite != null) {
133 return satellite;
134 }
135 }
136 }
137 return null;
138 }
140 @Override
141 public Map<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, com.oracle.webservices.internal.api.message.PropertySet> getSatellites() {
142 return satellites;
143 }
145 @Override
146 public Object get(Object key) {
147 // check satellites
148 for (PropertySet child : satellites.values()) {
149 if (child.supports(key)) {
150 return child.get(key);
151 }
152 }
154 // otherwise it must be the master
155 return super.get(key);
156 }
158 @Override
159 public Object put(String key, Object value) {
160 // check satellites
161 for (PropertySet child : satellites.values()) {
162 if(child.supports(key)) {
163 return child.put(key,value);
164 }
165 }
167 // otherwise it must be the master
168 return super.put(key,value);
169 }
171 @Override
172 public boolean containsKey(Object key) {
173 if (viewthis.containsKey(key))
174 return true;
175 for (PropertySet child : satellites.values()) {
176 if (child.containsKey(key)) {
177 return true;
178 }
179 }
180 return false;
181 }
183 @Override
184 public boolean supports(Object key) {
185 // check satellites
186 for (PropertySet child : satellites.values()) {
187 if (child.supports(key)) {
188 return true;
189 }
190 }
192 return super.supports(key);
193 }
195 @Override
196 public Object remove(Object key) {
197 // check satellites
198 for (PropertySet child : satellites.values()) {
199 if (child.supports(key)) {
200 return child.remove(key);
201 }
202 }
204 return super.remove(key);
205 }
207 @Override
208 protected void createEntrySet(Set<Entry<String, Object>> core) {
209 super.createEntrySet(core);
210 for (PropertySet child : satellites.values()) {
211 ((BasePropertySet) child).createEntrySet(core);
212 }
213 }
215 protected Map<String, Object> asMapLocal() {
216 return viewthis;
217 }
219 protected boolean supportsLocal(Object key) {
220 return super.supports(key);
221 }
223 class DistributedMapView extends AbstractMap<String, Object> {
224 @Override
225 public Object get(Object key) {
226 for (PropertySet child : satellites.values()) {
227 if (child.supports(key)) {
228 return child.get(key);
229 }
230 }
232 return viewthis.get(key);
233 }
235 @Override
236 public int size() {
237 int size = viewthis.size();
238 for (PropertySet child : satellites.values()) {
239 size += child.asMap().size();
240 }
241 return size;
242 }
244 @Override
245 public boolean containsKey(Object key) {
246 if (viewthis.containsKey(key))
247 return true;
248 for (PropertySet child : satellites.values()) {
249 if (child.containsKey(key))
250 return true;
251 }
252 return false;
253 }
255 @Override
256 public Set<Entry<String, Object>> entrySet() {
257 Set<Entry<String, Object>> entries = new HashSet<Entry<String, Object>>();
258 for (PropertySet child : satellites.values()) {
259 for (Entry<String,Object> entry : child.asMap().entrySet()) {
260 // the code below is here to avoid entries.addAll(child.asMap().entrySet()); which works differently on JDK6/7
261 // see DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
262 entries.add(new SimpleImmutableEntry<String, Object>(entry.getKey(), entry.getValue()));
263 }
264 }
265 for (Entry<String,Object> entry : viewthis.entrySet()) {
266 // the code below is here to avoid entries.addAll(child.asMap().entrySet()); which works differently on JDK6/7
267 // see DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
268 entries.add(new SimpleImmutableEntry<String, Object>(entry.getKey(), entry.getValue()));
269 }
271 return entries;
272 }
274 @Override
275 public Object put(String key, Object value) {
276 for (PropertySet child : satellites.values()) {
277 if (child.supports(key)) {
278 return child.put(key, value);
279 }
280 }
282 return viewthis.put(key, value);
283 }
285 @Override
286 public void clear() {
287 satellites.clear();
288 viewthis.clear();
289 }
291 @Override
292 public Object remove(Object key) {
293 for (PropertySet child : satellites.values()) {
294 if (child.supports(key)) {
295 return child.remove(key);
296 }
297 }
299 return viewthis.remove(key);
300 }
301 }
303 @Override
304 protected Map<String, Object> createView() {
305 return new DistributedMapView();
306 }
307 }