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

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
child 374
72e03566f0a6
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

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

mercurial