1 /* 2 * Copyright (c) 1997, 2014, 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.model; 27 28 import com.sun.xml.internal.bind.api.Bridge; 29 import com.sun.xml.internal.bind.api.TypeReference; 30 import com.sun.xml.internal.ws.api.model.JavaMethod; 31 import com.sun.xml.internal.ws.api.model.Parameter; 32 import com.sun.xml.internal.ws.api.model.ParameterBinding; 33 import com.sun.xml.internal.ws.spi.db.RepeatedElementBridge; 34 import com.sun.xml.internal.ws.spi.db.WrapperComposite; 35 import com.sun.xml.internal.ws.spi.db.XMLBridge; 36 import com.sun.xml.internal.ws.spi.db.TypeInfo; 37 38 import javax.jws.WebParam.Mode; 39 import javax.xml.namespace.QName; 40 import javax.xml.ws.Holder; 41 import java.util.List; 42 43 /** 44 * runtime Parameter that abstracts the annotated java parameter 45 * 46 * <p> 47 * A parameter may be bound to a header, a body, or an attachment. 48 * Note that when it's bound to a body, it's bound to a body, 49 * it binds to the whole payload. 50 * 51 * <p> 52 * Sometimes multiple Java parameters are packed into the payload, 53 * in which case the subclass {@link WrapperParameter} is used. 54 * 55 * @author Vivek Pandey 56 */ 57 public class ParameterImpl implements Parameter { 58 59 private ParameterBinding binding; 60 private ParameterBinding outBinding; 61 private String partName; 62 private final int index; 63 private final Mode mode; 64 /** @deprecated */ 65 private TypeReference typeReference; 66 private TypeInfo typeInfo; 67 private QName name; 68 private final JavaMethodImpl parent; 69 70 WrapperParameter wrapper; 71 TypeInfo itemTypeInfo; 72 73 public ParameterImpl(JavaMethodImpl parent, TypeInfo type, Mode mode, int index) { 74 assert type != null; 75 76 this.typeInfo = type; 77 this.name = type.tagName; 78 this.mode = mode; 79 this.index = index; 80 this.parent = parent; 81 } 82 83 public AbstractSEIModelImpl getOwner() { 84 return parent.owner; 85 } 86 87 public JavaMethod getParent() { 88 return parent; 89 } 90 91 /** 92 * @return Returns the name. 93 */ 94 public QName getName() { 95 return name; 96 } 97 98 public XMLBridge getXMLBridge() { 99 return getOwner().getXMLBridge(typeInfo); 100 } 101 102 public XMLBridge getInlinedRepeatedElementBridge() { 103 TypeInfo itemType = getItemType(); 104 if (itemType != null && itemType.getWrapperType() == null) { 105 XMLBridge xb = getOwner().getXMLBridge(itemType); 106 if (xb != null) return new RepeatedElementBridge(typeInfo, xb); 107 } 108 return null; 109 } 110 111 public TypeInfo getItemType() { 112 if (itemTypeInfo != null) return itemTypeInfo; 113 //RpcLit cannot inline repeated element in wrapper 114 if (parent.getBinding().isRpcLit() || wrapper == null) return null; 115 //InlinedRepeatedElementBridge is only used for dynamic wrapper (no wrapper class) 116 if (!WrapperComposite.class.equals(wrapper.getTypeInfo().type)) return null; 117 if (!getBinding().isBody()) return null; 118 itemTypeInfo = typeInfo.getItemType(); 119 return itemTypeInfo; 120 } 121 122 /** @deprecated */ 123 public Bridge getBridge() { 124 return getOwner().getBridge(typeReference); 125 } 126 /** @deprecated */ 127 protected Bridge getBridge(TypeReference typeRef) { 128 return getOwner().getBridge(typeRef); 129 } 130 131 /** 132 * TODO: once the model gets JAXBContext, shouldn't {@link Bridge}s 133 * be made available from model objects? 134 * @deprecated use getTypeInfo 135 * @return Returns the TypeReference associated with this Parameter 136 */ 137 public TypeReference getTypeReference() { 138 return typeReference; 139 } 140 public TypeInfo getTypeInfo() { 141 return typeInfo; 142 } 143 144 /** 145 * Sometimes we need to overwrite the typeReferenc, such as during patching for rpclit 146 * @see AbstractSEIModelImpl#applyRpcLitParamBinding(JavaMethodImpl, WrapperParameter, WSDLBoundPortType, WebParam.Mode) 147 * @deprecated 148 */ 149 void setTypeReference(TypeReference type){ 150 typeReference = type; 151 name = type.tagName; 152 } 153 154 155 public Mode getMode() { 156 return mode; 157 } 158 159 public int getIndex() { 160 return index; 161 } 162 163 /** 164 * @return true if {@code this instanceof} {@link WrapperParameter}. 165 */ 166 public boolean isWrapperStyle() { 167 return false; 168 } 169 170 public boolean isReturnValue() { 171 return index==-1; 172 } 173 174 /** 175 * @return the Binding for this Parameter 176 */ 177 public ParameterBinding getBinding() { 178 if(binding == null) 179 return ParameterBinding.BODY; 180 return binding; 181 } 182 183 /** 184 * @param binding 185 */ 186 public void setBinding(ParameterBinding binding) { 187 this.binding = binding; 188 } 189 190 public void setInBinding(ParameterBinding binding){ 191 this.binding = binding; 192 } 193 194 public void setOutBinding(ParameterBinding binding){ 195 this.outBinding = binding; 196 } 197 198 public ParameterBinding getInBinding(){ 199 return binding; 200 } 201 202 public ParameterBinding getOutBinding(){ 203 if(outBinding == null) 204 return binding; 205 return outBinding; 206 } 207 208 public boolean isIN() { 209 return mode==Mode.IN; 210 } 211 212 public boolean isOUT() { 213 return mode==Mode.OUT; 214 } 215 216 public boolean isINOUT() { 217 return mode==Mode.INOUT; 218 } 219 220 /** 221 * If true, this parameter maps to the return value of a method invocation. 222 * 223 * <p> 224 * {@link JavaMethodImpl#getResponseParameters()} is guaranteed to have 225 * at most one such {@link ParameterImpl}. Note that there coule be none, 226 * in which case the method returns {@code void}. 227 */ 228 public boolean isResponse() { 229 return index == -1; 230 } 231 232 233 /** 234 * Gets the holder value if applicable. To be called for inbound client side 235 * message. 236 * 237 * @param obj 238 * @return the holder value if applicable. 239 */ 240 public Object getHolderValue(Object obj) { 241 if (obj != null && obj instanceof Holder) 242 return ((Holder) obj).value; 243 return obj; 244 } 245 246 public String getPartName() { 247 if(partName == null) 248 return name.getLocalPart(); 249 return partName; 250 } 251 252 public void setPartName(String partName) { 253 this.partName = partName; 254 } 255 256 void fillTypes(List<TypeInfo> types) { 257 TypeInfo itemType = getItemType(); 258 if (itemType != null) { 259 types.add(itemType); 260 if (itemType.getWrapperType() != null) types.add(getTypeInfo()); 261 } else { 262 types.add(getTypeInfo()); 263 } 264 } 265 }