blob: 5fb4993eef8ad41f449d368ad8d28ab97e653977 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* 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
* $Id: CalloutToFieldMapping.java 23416 2010-02-03 19:59:31Z stephan $
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.internal.core;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.ILocalVariable;
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.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.eclipse.objectteams.otdt.core.ICalloutToFieldMapping;
import org.eclipse.objectteams.otdt.core.IFieldAccessSpec;
import org.eclipse.objectteams.otdt.core.IRoleType;
import org.eclipse.objectteams.otdt.core.TypeHelper;
import org.eclipse.objectteams.otdt.internal.core.util.FieldData;
import org.eclipse.objectteams.otdt.internal.core.util.MethodData;
/**
* Callout to field mapping implementation.
*
* @author brcan
*/
public class CalloutToFieldMapping extends AbstractCalloutMapping implements ICalloutToFieldMapping
{
private boolean isOverride;
private IField baseField;
private IFieldAccessSpec baseFieldHandle;
public CalloutToFieldMapping(
int declarationSourceStart,
int sourceStart,
int sourceEnd,
int declarationSourceEnd,
IRoleType role,
IMethod correspondingJavaElem,
MethodData roleMethodHandle,
IFieldAccessSpec baseFieldHandle,
boolean hasSignature,
boolean isOverride)
{
this(declarationSourceStart, sourceStart, sourceEnd, declarationSourceEnd, CALLOUT_TO_FIELD_MAPPING, role, correspondingJavaElem, roleMethodHandle, baseFieldHandle, hasSignature, isOverride, true);
}
protected CalloutToFieldMapping(
int declarationSourceStart,
int sourceStart,
int sourceEnd,
int declarationSourceEnd,
int elementType,
IType parentRole,
IMethod correspondingJavaElem,
MethodData roleMethodHandle,
IFieldAccessSpec baseFieldHandle,
boolean hasSignature,
boolean isOverride,
boolean addAsChild)
{
super(declarationSourceStart,
sourceStart,
sourceEnd,
declarationSourceEnd,
elementType,
correspondingJavaElem,
parentRole,
roleMethodHandle,
hasSignature,
addAsChild);
this.isOverride = isOverride;
this.baseFieldHandle = baseFieldHandle;
}
public boolean isOverride() {
return this.isOverride;
}
@SuppressWarnings("nls")
public String getElementName()
{
StringBuffer name = new StringBuffer(super.getElementName());
name.append(" -> ");
if (hasSignature())
{
name.append(this.baseFieldHandle.toString());
}
else
{
name.append(this.baseFieldHandle.getSelector());
}
return name.toString();
}
public int getMappingKind()
{
return CALLOUT_TO_FIELD_MAPPING;
}
public IField getBoundBaseField() throws JavaModelException
{
if (this.baseField == null)
{
this.baseField = findBaseField();
}
return this.baseField;
}
//added for the SourceTypeConverter
public IFieldAccessSpec getBaseFieldHandle()
{
return this.baseFieldHandle;
}
public boolean equals(Object obj)
{
if(!(obj instanceof CalloutToFieldMapping))
{
return false;
}
return super.equals(obj);
}
@SuppressWarnings("nls")
public String toString()
{
return "callout to field" + super.toString();
}
/**
* Performs resolving of bound base field
*/
private IField findBaseField() throws JavaModelException
{
IType baseClass = ((IRoleType)getParent()).getBaseClass();
IType[] typeParents = TypeHelper.getSuperTypes(baseClass);
return findField(typeParents, this.baseFieldHandle);
}
/**
* Tries to find an IField matching the given field handle in a set
* of types.
*
* @return the first matching IField in the set of types or null if
* nothing found
*/
private IField findField(IType[] types, IFieldAccessSpec fieldHandle)
throws JavaModelException
{
// cycle through types...
for (int idx = 0; idx < types.length; idx++)
{
IField[] fields = types[idx].getFields();
// ... and compare with each field defined in current type
for (int idy = 0; idy < fields.length; idy++)
{
IField tmpField = fields[idy];
// check for equal field name
if (tmpField.getElementName().equals(fieldHandle.getSelector()))
{
// return immmediately on first match
return tmpField;
}
}
}
return null;
}
// ==== memento generation: ====
@Override
protected char getMappingKindChar() {
if (this.baseFieldHandle.isSetter()) {
if (this.isOverride)
return 'S';
return 's';
} else {
if (this.isOverride)
return 'G';
return 'g';
}
}
@Override
protected void getBaseMethodsForHandle(StringBuffer buff) {
escapeMementoName(buff, this.baseFieldHandle.getSelector());
buff.append(JavaElement.JEM_METHOD);
escapeMementoName(buff, this.baseFieldHandle.getFieldType());
}
// ==== retreive from memento:
public static IFieldAccessSpec createFieldData(MementoTokenizer memento, boolean isSetter) {
String selector = memento.nextToken();
String cur = memento.nextToken();
if (cur.charAt(0) == JavaElement.JEM_METHOD)
cur = memento.nextToken(); // skip initial separator
StringBuffer buffer = new StringBuffer();
while (cur.length() == 1 && Signature.C_ARRAY == cur.charAt(0)) { // backward compatible with 3.0 mementos
buffer.append(Signature.C_ARRAY);
if (!memento.hasMoreTokens())
break;
cur = memento.nextToken();
}
buffer.append(cur);
String fieldType = buffer.toString();
memento.nextToken(); // skip separator
return new FieldData(selector, fieldType, isSetter);
}
// ====
// implementation and alternate API of resolved(Binding)
public OTJavaElement resolved(char[] uniqueKey) {
ResolvedCalloutToFieldMapping resolvedHandle =
new ResolvedCalloutToFieldMapping(
getDeclarationSourceStart(),
getSourceStart(),
getSourceEnd(),
getDeclarationSourceEnd(),
getElementType(),
(IType) getParent(),
getIMethod(),
getRoleMethodHandle(),
this.baseFieldHandle,
hasSignature(),
isOverride(),
new String(uniqueKey));
return resolvedHandle;
}
// disable method that does not apply to c-t-f:
@Override
public String[] getExceptionTypes() throws JavaModelException {
return new String[0];
}
public ILocalVariable[] getParameters() throws JavaModelException {
// TODO Auto-generated method stub
// see Bug 338593 - [otmodel] Add new API to ease the retrieval of the parameter annotations for an IMethodMapping
return null;
}
}