blob: ec9d4068bf9e793ab129808620278436527d65ac [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.validation.provider;
import java.util.Collection;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.ws.jaxws.dom.runtime.PrimitiveTypeHandler;
import org.eclipse.jst.ws.jaxws.dom.runtime.TypeResolver;
import org.eclipse.jst.ws.jaxws.dom.runtime.internal.plugin.JaxWsDomRuntimePlugin;
import org.eclipse.jst.ws.jaxws.dom.runtime.internal.validation.provider.TypeFactory;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.ConstructorNotExposableException;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.InadmissableTypeException;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.MethodNotPublicException;
/**
* Performes method validation by validating types used. Types are cached between different invocations of check(IMethod method) for better
* performance.
*
* @author Georgi Vachkov
*/
public class MethodValidator
{
private final static String EMPTY = ""; //$NON-NLS-1$
private final RuntimeTypeValidator validator;
/**
* Constructor.
*/
public MethodValidator()
{
validator = new RuntimeTypeValidator();
}
/**
* Performs check on types used in method. Checks return types, paramether types and exception types. Stops validation on the first error. An
* IStatus object containing information on the result of the check is returned.
*
* @param method
* @return IStatus with severity IStatus.OK if the method can be exposed, or IStatus.ERROR including error message decribing the problem.
* @throws NullPointerException -
* in case <code>method</code> is null
* @throws JavaModelException
*/
public IStatus check(IMethod method) throws JavaModelException
{
if (method.isConstructor()) {
return prepareStatus(new ConstructorNotExposableException(method.getElementName()));
}
final IType declaringType = method.getDeclaringType();
if (!Flags.isPublic(method.getFlags()) && !declaringType.isInterface()) {
return prepareStatus(new MethodNotPublicException(method.getElementName()));
}
try
{
// Handle return type
validateRuntimeClass(method.getReturnType(), declaringType);
// Handle input parameters and there types
for (String paramTypeName : method.getParameterTypes())
{
validateRuntimeClass(paramTypeName, declaringType);
}
// handle exception types
for (String exceptionTypeName : method.getExceptionTypes())
{
validateException(exceptionTypeName, declaringType);
}
return prepareStatus(null);
} catch (InadmissableTypeException e)
{
return prepareStatus(e);
}
}
/**
* Validates <code>typeName</code>. On first steps type is resolved and all resolved types are validated one by one. The resolved types can be
* more than one in case the type declaration uses generics. Validation propagates the exceptions thrown by RuntimeTypeValidator.
*
* @param typeName
* @param declaringType
* @throws JavaModelException
* @throws InadmissableTypeException
*/
private void validateRuntimeClass(String typeName, IType declaringType) throws JavaModelException, InadmissableTypeException
{
Collection<String> names = TypeResolver.resolveTypes(typeName, declaringType);
for (String name : names)
{
if (PrimitiveTypeHandler.isVoidType(name))
{
continue;
}
validator.validate(TypeFactory.create(name, declaringType));
}
}
/**
* Validates if <tt>exceptionType</tt> is a valid exception type for WS operation
*
* @param exceptionType -
* exception type name
* @param declaringType -
* type in which it is used
* @throws JavaModelException
* @throws InadmissableTypeException
* @throws JavaModelException
*/
private void validateException(final String exceptionType, final IType declaringType) throws InadmissableTypeException, JavaModelException
{
String exFQName = TypeResolver.resolveType(Signature.toString(exceptionType), declaringType);
validator.validate(TypeFactory.create(exFQName, declaringType));
}
/**
* Prepares IMethodAudit instance for <code>method</code>. If <code>throwable</code> is <code>null</code> IStatus.OK is set to the IStatus
* object contained in returned IMethodAudit instance else IStatus.ERROR is set.
*
* @param throwable
* @return always returns an valid IMethodAudit instance.
*/
private IStatus prepareStatus(Throwable throwable)
{
IStatus status = new Status((throwable == null) ? IStatus.OK : IStatus.ERROR, JaxWsDomRuntimePlugin.PLUGIN_ID, IStatus.OK,
(throwable == null) ? EMPTY : throwable.getLocalizedMessage(), throwable);
return status;
}
}