blob: 655903ddd1bf60de6b3c4492d9ac64e26ae2896d [file] [log] [blame]
/*******************************************************************************
* 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;
}
}