blob: 66dc2472473659c9b98af8b10f3366842cb11c55 [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.internal.validation.provider;
import java.util.ArrayList;
import java.util.List;
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.jst.ws.jaxws.dom.runtime.GeneralTypesNames;
import org.eclipse.jst.ws.jaxws.dom.runtime.TypeResolver;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.TypeNotFoundException;
import org.eclipse.jst.ws.jaxws.utils.ContractChecker;
/**
* TypeProxy represents a type in a way convienient for type checking.
*
* @author Georgi Vachkov
*/
public class TypeAdapter
{
private final IType type;
private String superClassName;
/**
* Constructor.
*
* @param type
* @throws NullPointerException -
* in case <code>type</code> is null.
*/
public TypeAdapter(IType type)
{
ContractChecker.nullCheckParam(type, "type");
this.type = type;
}
/**
* Checks for default constructor in analysed class.
*
* @return true if public constructor without paramethers exists or class does not have any constructor.
* @throws JavaModelException
*/
public boolean hasDefaultConstructor() throws JavaModelException
{
boolean hasConstructor = false;
boolean isPublic = false;
for (IMethod method : type.getMethods())
{
isPublic = Flags.isPublic(method.getFlags());
if (method.isConstructor())
{
hasConstructor = true;
}
if (method.isConstructor() && isPublic && method.getParameterNames().length == 0)
{
return true;
}
}
return !hasConstructor;
}
/**
* Retrieves the direct super interfaces fully qualified names.
*
* @return list of interface names - in case no interfaces are implemented an empty array is returned
* @throws JavaModelException
*/
public final List<String> getInterfaceNames() throws JavaModelException
{
String[] iNames = type.getSuperInterfaceNames();
List<String> interfaceNames = new ArrayList<String>(iNames.length);
for (String name : iNames)
{
String resolvedName = TypeResolver.resolveType(name, type);
interfaceNames.add(resolvedName);
}
return interfaceNames;
}
/**
* Checks if the class contains non static and non public inner classes.
*
* @return true if contains such
* @throws JavaModelException
*/
public boolean hasNonStaticOrNonPublicInnerTypes() throws JavaModelException
{
for (IType t : type.getTypes())
{
int typeFlags = t.getFlags();
if (!Flags.isStatic(typeFlags) || !Flags.isPublic(typeFlags))
{
return true;
}
}
return false;
}
/**
* Retrieves the name of it's superclass
*
* @return returnes resolved super class name or null if not present
* @throws JavaModelException
*/
public final String getSuperClassName() throws JavaModelException
{
if (type.getSuperclassName() != null && superClassName == null)
{
superClassName = TypeResolver.resolveType(type.getSuperclassName(), type);
}
return superClassName;
}
/**
* Resolves and creates an instance of TypeProxy for super class.
*
* @return returns instance of {@link TypeAdapter} for super class or null if not present
* @throws JavaModelException
* @throws TypeNotFoundException
*/
public final TypeAdapter getSuperClassType() throws TypeNotFoundException, JavaModelException
{
if (getSuperClassName() == null)
return null;
return new TypeAdapter(TypeFactory.create(getSuperClassName(), getType()));
}
/**
* Defines if this class extends <tt>baseClassType</tt>
*
* @param baseClassType
* @return check if this class type extends <tt>baseClassType</tt>
* @throws TypeNotFoundException
* @throws JavaModelException
*/
public boolean isExtending(String baseClassType) throws TypeNotFoundException, JavaModelException
{
String typeName = this.getQualifiedName();
// if we have arrived at object in the hierarchy, the type cannot be an exception
if (typeName.equals(GeneralTypesNames.JAVA_LANG_OBJECT))
{
return false;
}
// All exceptions inherit from Throwable
if (typeName.equals(baseClassType))
{
return true;
}
TypeAdapter parentType = getSuperClassType();
if (parentType != null)
{
return parentType.isExtending(baseClassType);
}
return false;
}
/**
* Checks if <code>type</code> implements interface <code>checkedInterfaceName</code>. Recursive check over the implemented interfaces is
* done which defines if some of the implemented in <code>type</code> interface is extending the specified interface.
*
* @param interfaceName
* @return true is this class type implements <tt>interfaceName</tt>
* @throws TypeNotFoundException
* @throws JavaModelException
*/
public boolean isImplementing(final String interfaceName) throws TypeNotFoundException, JavaModelException
{
return isImplementing(this, interfaceName);
}
private boolean isImplementing(final TypeAdapter checkedType, final String checkedInterfaceName) throws TypeNotFoundException, JavaModelException
{
if (checkedType.getQualifiedName().equals(checkedInterfaceName))
return true;
for (String interfaceName : checkedType.getInterfaceNames())
{
TypeAdapter ta = new TypeAdapter(TypeFactory.create(interfaceName, checkedType.getType()));
if (isImplementing(ta, checkedInterfaceName))
{
return true;
}
}
// here use ep checker as seriablizable is not required in supertype
if (checkedType.getSuperClassName() != null)
{
TypeAdapter superClass = new TypeAdapter(TypeFactory.create(checkedType.getSuperClassName(), checkedType.getType()));
return isImplementing(superClass, checkedInterfaceName);
}
return false;
}
/**
* Returns the type fully qualified name
*
* @return not <tt>null</tt> string
*/
public final String getQualifiedName()
{
return type.getFullyQualifiedName();
}
/**
* Returns the project name in which the type resides.
*
* @return not <tt>null</tt> string
*/
public final String getProjectName()
{
return type.getJavaProject().getProject().getName();
}
/**
* Returns wrapped IType.
*
* @return IType instance
*/
public final IType getType()
{
return type;
}
@Override
public int hashCode()
{
return type.getFullyQualifiedName().hashCode();
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (obj.getClass() == TypeAdapter.class)
{
return (getQualifiedName().equals(((TypeAdapter) obj).getQualifiedName()));
}
return false;
}
/**
* Checks if the type is public.
*
* @return <tt>true</tt> if the class is public
* @throws JavaModelException
*/
public boolean isPublic() throws JavaModelException
{
return Flags.isPublic(type.getFlags());
}
/**
* Checks if the type is final.
*
* @return <tt>true</tt> if the class is final
* @throws JavaModelException
*/
public boolean isFinal() throws JavaModelException
{
return Flags.isFinal(type.getFlags());
}
/**
* Checks if the type is abstract.
*
* @return <tt>true</tt> if the class is abstract
* @throws JavaModelException
*/
public boolean isAbstract() throws JavaModelException
{
return Flags.isAbstract(type.getFlags());
}
/**
* Checks if the type is an interface.
*
* @return <tt>true</tt> if the class is interface
* @throws JavaModelException
*/
public boolean isInterface() throws JavaModelException
{
return type.isInterface();
}
}