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 
  26 package com.sun.xml.internal.ws.server.sei;
  27 
  28 import com.sun.xml.internal.ws.api.model.Parameter;
  29 import com.sun.xml.internal.ws.model.ParameterImpl;
  30 
  31 import javax.xml.ws.Holder;
  32 
  33 /**
  34  * Moves a Java value unmarshalled from a response message
  35  * to the right place.
  36  *
  37  * <p>
  38  * Sometimes values are returned as a return value, and
  39  * others are returned in the {@link Holder} value. Instances
  40  * of this interface abstracts this detail.
  41  *
  42  * <p>
  43  * {@link EndpointValueSetter} is a stateless behavior encapsulation.
  44  *
  45  * @author Jitendra Kotamraju
  46  */
  47 public abstract class EndpointValueSetter {
  48     private EndpointValueSetter() {}
  49 
  50     /**
  51      * Moves the value to the expected place.
  52      *
  53      * @param obj
  54      *      The unmarshalled object.
  55      * @param args
  56      *      The arguments that need to be given to the Java method invocation. If <tt>obj</tt>
  57      *      is supposed to be returned as a {@link Holder} value, a suitable
  58      *      {@link Holder} is obtained from this argument list and <tt>obj</tt>
  59      *      is set.
  60      *
  61      */
  62     abstract void put(Object obj, Object[] args);
  63 
  64     /**
  65      * {@link Param}s with small index numbers are used often,
  66      * so we pool them to reduce the footprint.
  67      */
  68     private static final EndpointValueSetter[] POOL = new EndpointValueSetter[16];
  69 
  70     static {
  71         for( int i=0; i<POOL.length; i++ )
  72             POOL[i] = new Param(i);
  73     }
  74 
  75     /**
  76      * Returns a {@link EndpointValueSetter} suitable for the given {@link Parameter}.
  77      */
  78     public static EndpointValueSetter get(ParameterImpl p) {
  79         int idx = p.getIndex();
  80         if (p.isIN()) {
  81             if (idx<POOL.length) {
  82                 return POOL[idx];
  83             } else {
  84                 return new Param(idx);
  85             }
  86         } else {
  87             return new HolderParam(idx);
  88         }
  89     }
  90 
  91     static class Param extends EndpointValueSetter {
  92         /**
  93          * Index of the argument to put the value to.
  94          */
  95         protected final int idx;
  96 
  97         public Param(int idx) {
  98             this.idx = idx;
  99         }
 100 
 101         void put(Object obj, Object[] args) {
 102             if (obj != null) {
 103                 args[idx] = obj;
 104             }
 105         }
 106     }
 107 
 108     static final class HolderParam extends Param {
 109 
 110         public HolderParam(int idx) {
 111             super(idx);
 112         }
 113 
 114         @Override
 115         void put(Object obj, Object[] args) {
 116             Holder holder = new Holder();
 117             if (obj != null) {
 118                 holder.value = obj;
 119             }
 120             args[idx] = holder;
 121         }
 122     }
 123 }