blob: ab6cf39876e3e91caed19149263a819b6a0ae036 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.jdt.internal.ui.commands;
import org.eclipse.core.commands.AbstractParameterValueConverter;
import org.eclipse.core.commands.ParameterValueConversionException;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
/**
* A command parameter value converter to convert between Java elements and
* String references that identify them.
* <p>
* References can be made to Java types, methods and fields. The reference
* identifies the project to use as a search scope as well as the java element
* information. Note that non-source elements may be referenced (such as
* java.lang.Object), but they must be resolved within the scope of some
* project.
* </p>
* <p>
* References take the form:
*
* <pre>
* elementRef := typeRef | fieldRef | methodRef
* typeRef := projectName '/' fullyQualifiedTypeName
* fieldRef := typeRef '#' fieldName
* methodRef := typeRef '#' methodName '(' parameterSignatures ')'
* </pre>
*
* where <code>parameterSignatures</code> uses the signature format documented
* in the {@link org.eclipse.jdt.core.Signature Signature} class.
* </p>
*
* @since 3.2
*/
public class JavaElementReferenceConverter extends AbstractParameterValueConverter {
private static final char PROJECT_END_CHAR= '/';
private static final char TYPE_END_CHAR= '#';
private static final char PARAM_START_CHAR= Signature.C_PARAM_START;
private static final char PARAM_END_CHAR= Signature.C_PARAM_END;
public Object convertToObject(String parameterValue) throws ParameterValueConversionException {
assertWellFormed(parameterValue != null);
final int projectEndPosition= parameterValue.indexOf(PROJECT_END_CHAR);
assertWellFormed(projectEndPosition != -1);
String projectName= parameterValue.substring(0, projectEndPosition);
String javaElementRef= parameterValue.substring(projectEndPosition + 1);
IJavaModel javaModel= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
assertExists(javaModel);
IJavaProject javaProject= javaModel.getJavaProject(projectName);
assertExists(javaProject);
final int typeEndPosition= javaElementRef.indexOf(TYPE_END_CHAR);
String typeName;
if (typeEndPosition == -1) {
typeName= javaElementRef;
} else {
typeName= javaElementRef.substring(0, typeEndPosition);
}
IType type= null;
try {
type= javaProject.findType(typeName);
} catch (JavaModelException ex) {
// type == null
}
assertExists(type);
if (typeEndPosition == -1) {
return type;
}
String memberRef= javaElementRef.substring(typeEndPosition + 1);
final int paramStartPosition= memberRef.indexOf(PARAM_START_CHAR);
if (paramStartPosition == -1) {
IField field= type.getField(memberRef);
assertExists(field);
return field;
}
String methodName= memberRef.substring(0, paramStartPosition);
String signature= memberRef.substring(paramStartPosition);
String[] parameterTypes= null;
try {
parameterTypes= Signature.getParameterTypes(signature);
} catch (IllegalArgumentException ex) {
// parameterTypes == null
}
assertWellFormed(parameterTypes != null);
IMethod method= type.getMethod(methodName, parameterTypes);
assertExists(method);
return method;
}
/**
* Throws a <code>ParameterValueConversionException</code> if the java
* element reference string does not meet some well-formedness condition.
*
* @param assertion
* a boolean check for well-formedness
* @throws ParameterValueConversionException
*/
private void assertWellFormed(boolean assertion) throws ParameterValueConversionException {
if (!assertion) {
throw new ParameterValueConversionException("Malformed parameterValue"); //$NON-NLS-1$
}
}
/**
* Throws a <code>ParameterValueConversionException</code> if the java
* element reference string identifies an element that does not exist.
*
* @param javaElement
* an element to check for existence
* @throws ParameterValueConversionException
*/
private void assertExists(IJavaElement javaElement) throws ParameterValueConversionException {
if ((javaElement == null) || (!javaElement.exists())) {
throw new ParameterValueConversionException("parameterValue must reference an existing IJavaElement"); //$NON-NLS-1$
}
}
public String convertToString(Object parameterValue) throws ParameterValueConversionException {
if (!(parameterValue instanceof IJavaElement)) {
throw new ParameterValueConversionException("parameterValue must be an IJavaElement"); //$NON-NLS-1$
}
IJavaElement javaElement= (IJavaElement) parameterValue;
IJavaProject javaProject= javaElement.getJavaProject();
if (javaProject == null) {
throw new ParameterValueConversionException("Could not get IJavaProject for element"); //$NON-NLS-1$
}
StringBuffer buffer;
if (javaElement instanceof IType) {
IType type= (IType) javaElement;
buffer= composeTypeReference(type);
} else
if (javaElement instanceof IMethod) {
IMethod method= (IMethod) javaElement;
buffer= composeTypeReference(method.getDeclaringType());
buffer.append(TYPE_END_CHAR);
buffer.append(method.getElementName());
String[] parameterTypes= method.getParameterTypes();
buffer.append(PARAM_START_CHAR);
for (int i= 0; i < parameterTypes.length; i++) {
buffer.append(parameterTypes[i]);
}
buffer.append(PARAM_END_CHAR);
} else
if (javaElement instanceof IField) {
IField field= (IField) javaElement;
buffer= composeTypeReference(field.getDeclaringType());
buffer.append(TYPE_END_CHAR);
buffer.append(field.getElementName());
} else {
throw new ParameterValueConversionException("Unsupported IJavaElement type"); //$NON-NLS-1$
}
return buffer.toString();
}
private StringBuffer composeTypeReference(IType type) {
StringBuffer buffer= new StringBuffer();
buffer.append(type.getJavaProject().getElementName());
buffer.append(PROJECT_END_CHAR);
buffer.append(type.getFullyQualifiedName());
return buffer;
}
}