blob: 82418e6002de86f6c53ce148e9e0842a4217bd28 [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;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
/**
* Utility class containing logic for resolving type names from IType object.
*
* @author Georgi Vachkov
*/
public class TypeResolver
{
private static final String DOT = "."; //$NON-NLS-1$
private static final String QUOTE = "?"; //$NON-NLS-1$
/**
* Resolves <tt>typeName</tt> using <tt>type</tt>. In case when <tt>typeName</tt> contains generics declaration all types used in
* declaraion are returned.
*
* @param typeName
* @param type
* @return list of resolved types
* @throws JavaModelException
*/
public static List<String> resolveTypes(String typeName, IType type) throws JavaModelException
{
List<String> names = new ArrayList<String>(1);
String realTypeName = Signature.toString(typeName);
if (hasGenerics(realTypeName))
{
names = getTypesFromGenerics(realTypeName, type);
} else
{
names.add(realTypeName);
}
List<String> resolvedNames = new ArrayList<String>(names.size());
for (String name : names)
{
String resolvedName = resolveType(name, type);
if (!resolvedName.equals(QUOTE))
{
resolvedNames.add(resolvedName);
}
}
return resolvedNames;
}
/**
* Retrieves real type in case type is present by generics.
*
* @param typeName
* @param declaringType
* @return the real type of the expression if <tt>typeName</tt> is an expression otherwise <tt>typeName</tt>
* @throws JavaModelException
*/
private static String getType(String typeName, IType declaringType) throws JavaModelException
{
if (typeName.indexOf('?') > -1)
{
int pos = typeName.trim().lastIndexOf(' ');
if (pos > -1)
{
return TypeResolver.resolveType(typeName.substring(pos + 1), declaringType);
}
}
return typeName;
}
/**
* Gets the types used in generics declaration.
* @param typeName
* @param type the type containing resolved type
* @return list of type names.
* @throws JavaModelException
*/
public static final List<String> getTypesFromGenerics(String typeName, IType type) throws JavaModelException
{
String name = typeName;
List<String> names= new ArrayList<String>();
int ltPos = -1;
int gtPos = -1;
while ((ltPos = name.indexOf('<')) > -1)
{
if ((gtPos = name.lastIndexOf('>')) == -1)
{
gtPos = name.length()-2;
}
String firstName = name.substring(0, ltPos) + name.substring(gtPos+1);
name = name.substring(ltPos+1, gtPos);
addName(firstName, names, type);
if (name.indexOf('<') == -1)
{
addName(name, names, type);
}
}
return names;
}
private static final void addName(final String name, final List<String> names, final IType type) throws JavaModelException
{
int comaPos = name.indexOf(',');
if( comaPos > -1)
{
names.add(name.substring(0, comaPos));
names.add(name.substring(comaPos+1));
}
else {
names.add(getType(name, type));
}
}
/**
* Resolves type.
*
* @param typeName
* @param type
* @return the resolved type name.
* @throws JavaModelException
*/
public static String resolveType(final String typeName, final IType type) throws JavaModelException
{
String realTypeName = typeName;
if (PrimitiveTypeHandler.isArrayType(typeName))
{
return resolveType(PrimitiveTypeHandler.getTypeFromArrayType(typeName), type);
}
if (PrimitiveTypeHandler.isJavaPrimitiveType(realTypeName) || PrimitiveTypeHandler.isVoidType(realTypeName))
{
return realTypeName;
}
if (realTypeName.indexOf(DOT) > -1)
{
return realTypeName;
}
String[][] st = type.resolveType(realTypeName);
if (st != null)
{
if (st[0][0].length() == 0)
{
return st[0][1];
}
return st[0][0] + DOT + st[0][1];
}
if (realTypeName.startsWith(new String(new char[] { Signature.C_UNRESOLVED })))
{
return resolveType(realTypeName.substring(1, realTypeName.length()), type);
}
return realTypeName;
}
/**
* Checks whether <code>typeName</code> uses generics declaration. Example: for 'java.util.List<Strng>' the method will return true.
*
* @param typeName
* @return true is <tt>typeName</tt> contains generics declaration.
*/
private static boolean hasGenerics(String typeName)
{
return (typeName.indexOf('<') > -1);
}
}