src/share/jaxws_classes/com/oracle/webservices/internal/api/message/BaseDistributedPropertySet.java

Tue, 23 Apr 2013 18:33:20 -0700

author
katleman
date
Tue, 23 Apr 2013 18:33:20 -0700
changeset 374
72e03566f0a6
parent 368
0989ad8c0860
child 384
8f2986ff0235
permissions
-rw-r--r--

8012643: JDK8 b86 source with GPL header errors
Reviewed-by: dholmes, alanb

alanb@368 1 /*
katleman@374 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
katleman@374 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
alanb@368 4 *
katleman@374 5 * This code is free software; you can redistribute it and/or modify it
katleman@374 6 * under the terms of the GNU General Public License version 2 only, as
katleman@374 7 * published by the Free Software Foundation. Oracle designates this
katleman@374 8 * particular file as subject to the "Classpath" exception as provided
katleman@374 9 * by Oracle in the LICENSE file that accompanied this code.
alanb@368 10 *
katleman@374 11 * This code is distributed in the hope that it will be useful, but WITHOUT
katleman@374 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
katleman@374 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
katleman@374 14 * version 2 for more details (a copy is included in the LICENSE file that
katleman@374 15 * accompanied this code).
alanb@368 16 *
katleman@374 17 * You should have received a copy of the GNU General Public License version
katleman@374 18 * 2 along with this work; if not, write to the Free Software Foundation,
katleman@374 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
alanb@368 20 *
katleman@374 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
katleman@374 22 * or visit www.oracle.com if you need additional information or have any
katleman@374 23 * questions.
alanb@368 24 */
alanb@368 25 package com.oracle.webservices.internal.api.message;
alanb@368 26
alanb@368 27 import com.sun.istack.internal.NotNull;
alanb@368 28 import com.sun.istack.internal.Nullable;
alanb@368 29 import com.sun.xml.internal.ws.api.message.Packet;
alanb@368 30 import com.sun.xml.internal.ws.client.RequestContext;
alanb@368 31 import com.sun.xml.internal.ws.client.ResponseContext;
alanb@368 32
alanb@368 33 import javax.xml.ws.WebServiceContext;
alanb@368 34
alanb@368 35 import java.util.AbstractMap;
alanb@368 36 import java.util.Map.Entry;
alanb@368 37 import java.util.HashSet;
alanb@368 38 import java.util.IdentityHashMap;
alanb@368 39 import java.util.Map;
alanb@368 40 import java.util.Set;
alanb@368 41
alanb@368 42 /**
alanb@368 43 * {@link PropertySet} that combines properties exposed from multiple
alanb@368 44 * {@link PropertySet}s into one.
alanb@368 45 *
alanb@368 46 * <p>
alanb@368 47 * This implementation allows one {@link PropertySet} to assemble
alanb@368 48 * all properties exposed from other "satellite" {@link PropertySet}s.
alanb@368 49 * (A satellite may itself be a {@link DistributedPropertySet}, so
alanb@368 50 * in general this can form a tree.)
alanb@368 51 *
alanb@368 52 * <p>
alanb@368 53 * This is useful for JAX-WS because the properties we expose to the application
alanb@368 54 * are contributed by different pieces, and therefore we'd like each of them
alanb@368 55 * to have a separate {@link PropertySet} implementation that backs up
alanb@368 56 * the properties. For example, this allows FastInfoset to expose its
alanb@368 57 * set of properties to {@link RequestContext} by using a strongly-typed fields.
alanb@368 58 *
alanb@368 59 * <p>
alanb@368 60 * This is also useful for a client-side transport to expose a bunch of properties
alanb@368 61 * into {@link ResponseContext}. It simply needs to create a {@link PropertySet}
alanb@368 62 * object with methods for each property it wants to expose, and then add that
alanb@368 63 * {@link PropertySet} to {@link Packet}. This allows property values to be
alanb@368 64 * lazily computed (when actually asked by users), thus improving the performance
alanb@368 65 * of the typical case where property values are not asked.
alanb@368 66 *
alanb@368 67 * <p>
alanb@368 68 * A similar benefit applies on the server-side, for a transport to expose
alanb@368 69 * a bunch of properties to {@link WebServiceContext}.
alanb@368 70 *
alanb@368 71 * <p>
alanb@368 72 * To achieve these benefits, access to {@link DistributedPropertySet} is slower
alanb@368 73 * compared to {@link PropertySet} (such as get/set), while adding a satellite
alanb@368 74 * object is relatively fast.
alanb@368 75 *
alanb@368 76 * @author Kohsuke Kawaguchi
alanb@368 77 */
alanb@368 78 public abstract class BaseDistributedPropertySet extends BasePropertySet implements DistributedPropertySet {
alanb@368 79
alanb@368 80 /**
alanb@368 81 * All {@link PropertySet}s that are bundled into this {@link PropertySet}.
alanb@368 82 */
alanb@368 83 private final Map<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet> satellites
alanb@368 84 = new IdentityHashMap<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet>();
alanb@368 85
alanb@368 86 private final Map<String, Object> viewthis;
alanb@368 87
alanb@368 88 public BaseDistributedPropertySet() {
alanb@368 89 this.viewthis = super.createView();
alanb@368 90 }
alanb@368 91
alanb@368 92 @Override
alanb@368 93 public void addSatellite(@NotNull PropertySet satellite) {
alanb@368 94 addSatellite(satellite.getClass(), satellite);
alanb@368 95 }
alanb@368 96
alanb@368 97 @Override
alanb@368 98 public void addSatellite(@NotNull Class<? extends com.oracle.webservices.internal.api.message.PropertySet> keyClass, @NotNull PropertySet satellite) {
alanb@368 99 satellites.put(keyClass, satellite);
alanb@368 100 }
alanb@368 101
alanb@368 102 @Override
alanb@368 103 public void removeSatellite(PropertySet satellite) {
alanb@368 104 satellites.remove(satellite.getClass());
alanb@368 105 }
alanb@368 106
alanb@368 107 public void copySatelliteInto(@NotNull DistributedPropertySet r) {
alanb@368 108 for (Map.Entry<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, PropertySet> entry : satellites.entrySet()) {
alanb@368 109 r.addSatellite(entry.getKey(), entry.getValue());
alanb@368 110 }
alanb@368 111 }
alanb@368 112
alanb@368 113 @Override
alanb@368 114 public void copySatelliteInto(MessageContext r) {
alanb@368 115 copySatelliteInto((DistributedPropertySet)r);
alanb@368 116 }
alanb@368 117
alanb@368 118 @Override
alanb@368 119 public @Nullable <T extends com.oracle.webservices.internal.api.message.PropertySet> T getSatellite(Class<T> satelliteClass) {
alanb@368 120 T satellite = (T) satellites.get(satelliteClass);
alanb@368 121 if (satellite != null) {
alanb@368 122 return satellite;
alanb@368 123 }
alanb@368 124
alanb@368 125 for (PropertySet child : satellites.values()) {
alanb@368 126 if (satelliteClass.isInstance(child)) {
alanb@368 127 return satelliteClass.cast(child);
alanb@368 128 }
alanb@368 129
alanb@368 130 if (DistributedPropertySet.class.isInstance(child)) {
alanb@368 131 satellite = DistributedPropertySet.class.cast(child).getSatellite(satelliteClass);
alanb@368 132 if (satellite != null) {
alanb@368 133 return satellite;
alanb@368 134 }
alanb@368 135 }
alanb@368 136 }
alanb@368 137 return null;
alanb@368 138 }
alanb@368 139
alanb@368 140 @Override
alanb@368 141 public Map<Class<? extends com.oracle.webservices.internal.api.message.PropertySet>, com.oracle.webservices.internal.api.message.PropertySet> getSatellites() {
alanb@368 142 return satellites;
alanb@368 143 }
alanb@368 144
alanb@368 145 @Override
alanb@368 146 public Object get(Object key) {
alanb@368 147 // check satellites
alanb@368 148 for (PropertySet child : satellites.values()) {
alanb@368 149 if (child.supports(key)) {
alanb@368 150 return child.get(key);
alanb@368 151 }
alanb@368 152 }
alanb@368 153
alanb@368 154 // otherwise it must be the master
alanb@368 155 return super.get(key);
alanb@368 156 }
alanb@368 157
alanb@368 158 @Override
alanb@368 159 public Object put(String key, Object value) {
alanb@368 160 // check satellites
alanb@368 161 for (PropertySet child : satellites.values()) {
alanb@368 162 if(child.supports(key)) {
alanb@368 163 return child.put(key,value);
alanb@368 164 }
alanb@368 165 }
alanb@368 166
alanb@368 167 // otherwise it must be the master
alanb@368 168 return super.put(key,value);
alanb@368 169 }
alanb@368 170
alanb@368 171 @Override
alanb@368 172 public boolean containsKey(Object key) {
alanb@368 173 if (viewthis.containsKey(key))
alanb@368 174 return true;
alanb@368 175 for (PropertySet child : satellites.values()) {
alanb@368 176 if (child.containsKey(key)) {
alanb@368 177 return true;
alanb@368 178 }
alanb@368 179 }
alanb@368 180 return false;
alanb@368 181 }
alanb@368 182
alanb@368 183 @Override
alanb@368 184 public boolean supports(Object key) {
alanb@368 185 // check satellites
alanb@368 186 for (PropertySet child : satellites.values()) {
alanb@368 187 if (child.supports(key)) {
alanb@368 188 return true;
alanb@368 189 }
alanb@368 190 }
alanb@368 191
alanb@368 192 return super.supports(key);
alanb@368 193 }
alanb@368 194
alanb@368 195 @Override
alanb@368 196 public Object remove(Object key) {
alanb@368 197 // check satellites
alanb@368 198 for (PropertySet child : satellites.values()) {
alanb@368 199 if (child.supports(key)) {
alanb@368 200 return child.remove(key);
alanb@368 201 }
alanb@368 202 }
alanb@368 203
alanb@368 204 return super.remove(key);
alanb@368 205 }
alanb@368 206
alanb@368 207 @Override
alanb@368 208 protected void createEntrySet(Set<Entry<String, Object>> core) {
alanb@368 209 super.createEntrySet(core);
alanb@368 210 for (PropertySet child : satellites.values()) {
alanb@368 211 ((BasePropertySet) child).createEntrySet(core);
alanb@368 212 }
alanb@368 213 }
alanb@368 214
alanb@368 215 protected Map<String, Object> asMapLocal() {
alanb@368 216 return viewthis;
alanb@368 217 }
alanb@368 218
alanb@368 219 protected boolean supportsLocal(Object key) {
alanb@368 220 return super.supports(key);
alanb@368 221 }
alanb@368 222
alanb@368 223 class DistributedMapView extends AbstractMap<String, Object> {
alanb@368 224 @Override
alanb@368 225 public Object get(Object key) {
alanb@368 226 for (PropertySet child : satellites.values()) {
alanb@368 227 if (child.supports(key)) {
alanb@368 228 return child.get(key);
alanb@368 229 }
alanb@368 230 }
alanb@368 231
alanb@368 232 return viewthis.get(key);
alanb@368 233 }
alanb@368 234
alanb@368 235 @Override
alanb@368 236 public int size() {
alanb@368 237 int size = viewthis.size();
alanb@368 238 for (PropertySet child : satellites.values()) {
alanb@368 239 size += child.asMap().size();
alanb@368 240 }
alanb@368 241 return size;
alanb@368 242 }
alanb@368 243
alanb@368 244 @Override
alanb@368 245 public boolean containsKey(Object key) {
alanb@368 246 if (viewthis.containsKey(key))
alanb@368 247 return true;
alanb@368 248 for (PropertySet child : satellites.values()) {
alanb@368 249 if (child.containsKey(key))
alanb@368 250 return true;
alanb@368 251 }
alanb@368 252 return false;
alanb@368 253 }
alanb@368 254
alanb@368 255 @Override
alanb@368 256 public Set<Entry<String, Object>> entrySet() {
alanb@368 257 Set<Entry<String, Object>> entries = new HashSet<Entry<String, Object>>();
alanb@368 258 for (PropertySet child : satellites.values()) {
alanb@368 259 for (Entry<String,Object> entry : child.asMap().entrySet()) {
alanb@368 260 // the code below is here to avoid entries.addAll(child.asMap().entrySet()); which works differently on JDK6/7
alanb@368 261 // see DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
alanb@368 262 entries.add(new SimpleImmutableEntry<String, Object>(entry.getKey(), entry.getValue()));
alanb@368 263 }
alanb@368 264 }
alanb@368 265 for (Entry<String,Object> entry : viewthis.entrySet()) {
alanb@368 266 // the code below is here to avoid entries.addAll(child.asMap().entrySet()); which works differently on JDK6/7
alanb@368 267 // see DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
alanb@368 268 entries.add(new SimpleImmutableEntry<String, Object>(entry.getKey(), entry.getValue()));
alanb@368 269 }
alanb@368 270
alanb@368 271 return entries;
alanb@368 272 }
alanb@368 273
alanb@368 274 @Override
alanb@368 275 public Object put(String key, Object value) {
alanb@368 276 for (PropertySet child : satellites.values()) {
alanb@368 277 if (child.supports(key)) {
alanb@368 278 return child.put(key, value);
alanb@368 279 }
alanb@368 280 }
alanb@368 281
alanb@368 282 return viewthis.put(key, value);
alanb@368 283 }
alanb@368 284
alanb@368 285 @Override
alanb@368 286 public void clear() {
alanb@368 287 satellites.clear();
alanb@368 288 viewthis.clear();
alanb@368 289 }
alanb@368 290
alanb@368 291 @Override
alanb@368 292 public Object remove(Object key) {
alanb@368 293 for (PropertySet child : satellites.values()) {
alanb@368 294 if (child.supports(key)) {
alanb@368 295 return child.remove(key);
alanb@368 296 }
alanb@368 297 }
alanb@368 298
alanb@368 299 return viewthis.remove(key);
alanb@368 300 }
alanb@368 301 }
alanb@368 302
alanb@368 303 @Override
alanb@368 304 protected Map<String, Object> createView() {
alanb@368 305 return new DistributedMapView();
alanb@368 306 }
alanb@368 307 }

mercurial