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

     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 }

mercurial