/******************************************************************************* | |
* Copyright (c) 2009 by SAP AG, Walldorf. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* SAP AG - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.jst.ws.jaxws.dom.runtime.persistence.sync; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures.HEADER_ATTRIBUTE; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures.MODE_ATTRIBUTE; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures.NAME_ATTRIBUTE; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures.PART_NAME_ATTRIBUTE; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures.TARGET_NAMESPACE_ATTRIBUTE; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures.WP_ANNOTATION; | |
import java.util.Collection; | |
import java.util.LinkedList; | |
import org.eclipse.jdt.core.IMethod; | |
import org.eclipse.jdt.core.ITypeParameter; | |
import org.eclipse.jdt.core.JavaModelException; | |
import org.eclipse.jdt.core.Signature; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.DomPackage; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebMethod; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebParam; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.WebParamKind; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.IAnnotationSerializer; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.IModelElementSynchronizer; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WPAnnotationFeatures; | |
import org.eclipse.jst.ws.jaxws.utils.annotations.IAnnotation; | |
import org.eclipse.jst.ws.jaxws.utils.annotations.IAnnotationInspector; | |
/** | |
* Class that synchronizes the parameters for {@link IWebMethod} object; | |
* | |
* @author | |
*/ | |
public class ParameterSynchronizer extends ElementSynchronizerImpl | |
{ | |
private static final String RETURN_PARAM_NAME = "return";//$NON-NLS-1$ | |
private static final String HOLDER_CLASS_NAME = "Holder"; //$NON-NLS-1$ | |
private static final String HOLDER_CLASS_FQNAME = "javax.xml.ws.Holder";//$NON-NLS-1$ | |
public ParameterSynchronizer(IModelElementSynchronizer parent) | |
{ | |
super(parent); | |
} | |
public void synchronizeParameters(IWebMethod wm, IMethod method, IAnnotationInspector inspector) throws JavaModelException | |
{ | |
final Collection<IWebParam> mergedParams = new LinkedList<IWebParam>(); | |
if (!Signature.SIG_VOID.equals(method.getReturnType())) | |
{ | |
final IWebParam retParam = obtainInstance(wm, RETURN_PARAM_NAME); | |
mergeParam(retParam, 0, wm, method, method.getReturnType(), inspector); | |
mergedParams.add(retParam); | |
} | |
final String[] names = method.getParameterNames(); | |
final String[] typeSignatures = method.getParameterTypes(); | |
for (int i = 0; i < names.length; i++) | |
{ | |
final IWebParam param = obtainInstance(wm, names[i]); | |
mergeParam(param, i, wm, method, typeSignatures[i], inspector); | |
mergedParams.add(param); | |
} | |
wm.getParameters().retainAll(mergedParams); | |
} | |
private void mergeParam(IWebParam webParam, int pos, IWebMethod webMethod, IMethod method, String typeSign, IAnnotationInspector inspector) throws JavaModelException | |
{ | |
final ITypeParameter typeParam = method.getTypeParameter(webParam.getImplementation()); | |
assert typeParam!= null; | |
final IAnnotation<ITypeParameter> wpAnnotation = isWebResult(webParam) ? null : inspector.inspectParam(typeParam, WP_ANNOTATION); | |
if (! typeSign.equals(webParam.getTypeName())) { | |
util().setFeatureValue(webParam, DomPackage.IWEB_PARAM__TYPE_NAME, typeSign); | |
} | |
final WebParamKind kind = isWebResult(webParam) ? WebParamKind.OUT : calcKind(wpAnnotation, method, typeSign); | |
if (!kind.equals(webParam.getKind())) { | |
webParam.setKind(kind); | |
} | |
final boolean isHeader = calcHeader(wpAnnotation); | |
if (webParam.isHeader() ^ isHeader) { | |
webParam.setHeader(isHeader); | |
} | |
final String name = isWebResult(webParam) ? defCalc().calcWebResultDefaultName(webMethod) : calcName(wpAnnotation, webMethod, pos); | |
if (!name.equals(webParam.getName())) { | |
webParam.setName(name); | |
} | |
final String partName = calcPartName(wpAnnotation, name); | |
if (!partName.equals(webParam.getPartName())) { | |
webParam.setPartName(partName); | |
} | |
final String targetNamespace = calcTargetNamespace(wpAnnotation, webMethod, webParam); | |
if (!targetNamespace.equals(webParam.getTargetNamespace())) { | |
webParam.setTargetNamespace(targetNamespace); | |
} | |
resource().getSerializerFactory().adapt(webParam, IAnnotationSerializer.class); | |
adaptToLocationInterface(webParam, WP_ANNOTATION, wpAnnotation); | |
} | |
private boolean isWebResult(final IWebParam param) | |
{ | |
return param.getImplementation().equals(RETURN_PARAM_NAME); | |
} | |
protected String resolveFullyQualifiedName(final IMethod method, final String typeSignature) throws JavaModelException, IllegalArgumentException | |
{ | |
if (Signature.getTypeSignatureKind(typeSignature) == Signature.BASE_TYPE_SIGNATURE) | |
{ | |
return Signature.toString(typeSignature); | |
} | |
final String[][] resolvedTypes = method.getDeclaringType().resolveType(Signature.toString(typeSignature)); | |
if (resolvedTypes == null) | |
{ | |
return "";//$NON-NLS-1$ | |
} | |
final String pack = resolvedTypes[0][0]; | |
final String className = resolvedTypes[0][1]; | |
if (pack != null && pack.length() != 0) | |
{ | |
return pack + "." + className;//$NON-NLS-1$ | |
} else | |
{ | |
return className; | |
} | |
} | |
protected WebParamKind calcKind(final IAnnotation<ITypeParameter> parmAnnotation, final IMethod method, final String typeSignature) throws JavaModelException, IllegalArgumentException | |
{ | |
if (parmAnnotation != null && parmAnnotation.getPropertyValue(MODE_ATTRIBUTE) != null) | |
{ | |
final String mode = parmAnnotation.getPropertyValue(MODE_ATTRIBUTE); | |
if (WPAnnotationFeatures.WEB_PARAM_MODE_INOUT.endsWith(mode)) | |
{ | |
return WebParamKind.INOUT; | |
} | |
if (WPAnnotationFeatures.WEB_PARAM_MODE_IN.endsWith(mode)) | |
{ | |
return WebParamKind.IN; | |
} | |
if (WPAnnotationFeatures.WEB_PARAM_MODE_OUT.endsWith(mode)) | |
{ | |
return WebParamKind.OUT; | |
} | |
} | |
if (isPossiblyHolderClass(typeSignature)) { | |
final String typeFQName = resolveFullyQualifiedName(method, typeSignature); | |
if (typeFQName.startsWith(HOLDER_CLASS_FQNAME)) { | |
return WebParamKind.INOUT; | |
} | |
} | |
return WebParamKind.IN; | |
} | |
/** | |
* Added due to performance issues CSN 0120061532 0002256925 2009. | |
* The idea is that before calling {@link #resolveFullyQualifiedName(IMethod, String)} | |
* we check if the class is potentially Holder. | |
*/ | |
private boolean isPossiblyHolderClass(final String typeSignature) { | |
final String erasuteTypeName = Signature.getSignatureSimpleName(Signature.getTypeErasure(typeSignature)); | |
if (HOLDER_CLASS_NAME.equals(erasuteTypeName)) { | |
return true; | |
} | |
return false; | |
} | |
private String calcName(IAnnotation<ITypeParameter> parmAnnotation, IWebMethod webMethod, int paramPosition) | |
{ | |
if (parmAnnotation != null && parmAnnotation.getPropertyValue(NAME_ATTRIBUTE) != null) { | |
return parmAnnotation.getPropertyValue(NAME_ATTRIBUTE); | |
} | |
return defCalc().calcWebParamDefaultName(webMethod, paramPosition); | |
} | |
private String calcPartName(final IAnnotation<ITypeParameter> wpAnnotation, final String name) | |
{ | |
if (wpAnnotation!=null && wpAnnotation.getPropertyValue(PART_NAME_ATTRIBUTE)!=null) { | |
return wpAnnotation.getPropertyValue(PART_NAME_ATTRIBUTE); | |
} | |
return name; | |
} | |
private boolean calcHeader(final IAnnotation<ITypeParameter> wpAnnotation) | |
{ | |
if (wpAnnotation!=null && wpAnnotation.getPropertyValue(HEADER_ATTRIBUTE)!=null) { | |
return Boolean.parseBoolean(wpAnnotation.getPropertyValue(HEADER_ATTRIBUTE)); | |
} | |
return false; | |
} | |
private String calcTargetNamespace(final IAnnotation<ITypeParameter> wpAnnotation, final IWebMethod webMethod, final IWebParam webParam) | |
{ | |
if (wpAnnotation!=null && wpAnnotation.getPropertyValue(TARGET_NAMESPACE_ATTRIBUTE)!=null) { | |
return wpAnnotation.getPropertyValue(TARGET_NAMESPACE_ATTRIBUTE); | |
} | |
return defCalc().calcWebParamDefaultTargetNS(webMethod, webParam); | |
} | |
private IWebParam obtainInstance(IWebMethod wm, String impl) | |
{ | |
final IWebParam existing = findWebParamByImplName(wm, impl); | |
if (existing != null) | |
{ | |
return existing; | |
} | |
final IWebParam newParam = domFactory().createIWebParam(); | |
util().setFeatureValue(newParam, DomPackage.IWEB_PARAM__IMPLEMENTATION, impl); | |
wm.getParameters().add(newParam); | |
return newParam; | |
} | |
private IWebParam findWebParamByImplName(final IWebMethod wm, final String impl) | |
{ | |
for (IWebParam param : wm.getParameters()) | |
{ | |
if (impl.equals(param.getImplementation())) | |
{ | |
return param; | |
} | |
} | |
return null; | |
} | |
} |