| /******************************************************************************* |
| * Copyright (c) 2005 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 |
| * Matt Chapman - initial version |
| *******************************************************************************/ |
| package org.eclipse.ajdt.core; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.ajdt.core.codeconversion.AspectsConvertingParser; |
| import org.eclipse.ajdt.core.javaelements.AJCodeElement; |
| import org.eclipse.ajdt.core.javaelements.AJCompilationUnit; |
| import org.eclipse.ajdt.core.javaelements.AJCompilationUnitManager; |
| import org.eclipse.ajdt.core.javaelements.AJInjarElement; |
| import org.eclipse.ajdt.core.javaelements.AspectElement; |
| import org.eclipse.ajdt.core.javaelements.BinaryAspectElement; |
| import org.eclipse.ajdt.internal.core.AJWorkingCopyOwner; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IOpenable; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.WorkingCopyOwner; |
| import org.eclipse.jdt.internal.core.ClassFile; |
| import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; |
| import org.eclipse.jdt.internal.core.JavaElement; |
| import org.eclipse.jdt.internal.core.JavaModelManager; |
| import org.eclipse.jdt.internal.core.PackageFragment; |
| |
| public class AspectJCore { |
| |
| public static IJavaElement create(IFile file) { |
| if ("aj".equals(file.getFileExtension())) { |
| return AJCompilationUnitManager.INSTANCE.getAJCompilationUnit(file); |
| } |
| return JavaModelManager.create(file, null/*unknown java project*/); |
| } |
| |
| |
| /** |
| * Returns the Java model element corresponding to the given handle |
| * identifier generated by <code>IJavaElement.getHandleIdentifier()</code>, |
| * or <code>null</code> if unable to create the associated element. |
| * |
| * @param handleIdentifier |
| * the given handle identifier |
| * @return the Java element corresponding to the handle identifier |
| */ |
| public static IJavaElement create(String handleIdentifier) { |
| return create(handleIdentifier, AJWorkingCopyOwner.INSTANCE); |
| } |
| |
| private static int indexOfIgnoringEscapes(String str, char ch) { |
| boolean prevEscape = false; |
| for (int i = 0; i < str.length(); i++) { |
| char c = str.charAt(i); |
| if (c == JavaElement.JEM_ESCAPE) { |
| prevEscape = true; |
| } else { |
| if ((c == ch) && (!prevEscape)) { |
| return i; |
| } |
| prevEscape = false; |
| } |
| } |
| return -1; |
| } |
| |
| private static IJavaElement getCodeElement(String codeElementHandle, JavaElement parent) { |
| int li = indexOfIgnoringEscapes( |
| codeElementHandle, |
| JavaElement.JEM_COUNT); |
| if (li != -1) { |
| int occurrenceIndex = codeElementHandle.lastIndexOf(JavaElement.JEM_COUNT); |
| if (Character.isDigit(codeElementHandle.charAt(occurrenceIndex+1))) { |
| int occurrence = Integer.parseInt(codeElementHandle.substring(occurrenceIndex+1)); |
| String cname = codeElementHandle.substring(0, li); |
| return new AJCodeElement(parent, cname, occurrence); |
| } |
| codeElementHandle = codeElementHandle.substring(0, li); |
| } |
| // no occurrance count |
| return new AJCodeElement(parent, codeElementHandle); |
| } |
| |
| public static IJavaElement create(String handleIdentifier, |
| WorkingCopyOwner owner) { |
| |
| if (handleIdentifier == null) { |
| return null; |
| } |
| Map aspectsInJavaFiles = new HashMap(); |
| |
| boolean isCodeElement = false; |
| String codeElementHandle = ""; //$NON-NLS-1$ |
| |
| int codeElementDelimPos = indexOfIgnoringEscapes(handleIdentifier, |
| AspectElement.JEM_CODEELEMENT); |
| if (codeElementDelimPos != -1) { |
| isCodeElement = true; |
| codeElementHandle = handleIdentifier |
| .substring(codeElementDelimPos + 1); |
| handleIdentifier = handleIdentifier.substring(0, |
| codeElementDelimPos); |
| } |
| |
| AJMementoTokenizer memento = new AJMementoTokenizer(handleIdentifier); |
| while (memento.hasMoreTokens()) { |
| String token = memento.nextToken(); |
| if ((token.charAt(0) == AspectElement.JEM_ASPECT_CU) |
| || (token.charAt(0) == JavaElement.JEM_COMPILATIONUNIT) |
| || (token.charAt(0) == JavaElement.JEM_CLASSFILE)) { |
| |
| int index; |
| if (token.charAt(0) == AspectElement.JEM_ASPECT_CU) { |
| index = handleIdentifier.indexOf(AspectElement.JEM_ASPECT_CU); |
| } else if (token.charAt(0) == JavaElement.JEM_COMPILATIONUNIT) { |
| index = handleIdentifier.indexOf(JavaElement.JEM_COMPILATIONUNIT); |
| } else { // JEM_CLASSFILE |
| index = handleIdentifier.indexOf(JavaElement.JEM_CLASSFILE); |
| } |
| |
| if (index != -1) { |
| IJavaElement je = JavaCore.create(handleIdentifier |
| .substring(0, index)); |
| if (je instanceof PackageFragment) { |
| PackageFragment pf = (PackageFragment) je; |
| String cuName = handleIdentifier.substring(index + 1); |
| int ind1 = cuName.indexOf(JavaElement.JEM_TYPE); |
| if (ind1 != -1) { |
| cuName = cuName.substring(0, ind1); |
| } |
| int ind2 = cuName.indexOf(AspectElement.JEM_ASPECT_TYPE); |
| if (ind2 != -1) { |
| cuName = cuName.substring(0, ind2); |
| } |
| int ind3 = cuName.indexOf(AspectElement.JEM_ITD_METHOD); |
| if (ind3 != -1) { |
| cuName = cuName.substring(0, ind3); |
| } |
| ind3 = cuName.indexOf(AspectElement.JEM_ITD_FIELD); |
| if (ind3 != -1) { |
| cuName = cuName.substring(0, ind3); |
| } |
| int ind4 = cuName.indexOf(AspectElement.JEM_DECLARE); |
| if (ind4 != -1) { |
| cuName = cuName.substring(0, ind4); |
| } |
| int ind5 = cuName.indexOf(AspectElement.JEM_IMPORTDECLARATION); |
| if (ind5 != -1) { |
| cuName = cuName.substring(0, ind5); |
| } |
| int ind6 = cuName.indexOf(AspectElement.JEM_PACKAGEDECLARATION); |
| if (ind6 != -1) { |
| cuName = cuName.substring(0, ind6); |
| } |
| if (CoreUtils.ASPECTJ_SOURCE_ONLY_FILTER.accept(cuName)) { |
| // no need to use a cuprovider because we know this |
| // is an AJCompilationUnit |
| JavaElement cu = new AJCompilationUnit(pf, cuName, owner); |
| token = memento.nextToken(); |
| if (!memento.hasMoreTokens()) { |
| return cu; |
| } |
| IJavaElement restEl = cu.getHandleFromMemento( |
| memento.nextToken(), memento, owner); |
| if (restEl != null) { |
| if (isCodeElement) { |
| // there was an AJCodeElement at the end of |
| // the handle |
| IJavaElement codeEl = getCodeElement(codeElementHandle,(JavaElement) restEl); |
| if (codeEl != null) { |
| return codeEl; |
| } |
| } |
| return restEl; |
| } |
| } else { |
| // Use the default working copy owner for Java elements |
| IJavaElement restEl = pf.getHandleFromMemento( |
| token, memento, DefaultWorkingCopyOwner.PRIMARY); |
| if (restEl != null) { |
| if (isCodeElement) { |
| // there was an AJCodeElement at the end of |
| // the handle |
| IJavaElement codeEl = getCodeElement(codeElementHandle,(JavaElement) restEl); |
| if (codeEl != null) { |
| return codeEl; |
| } |
| } |
| return restEl; |
| } else if (ind2 != -1) { // An aspect in a .java file... |
| int index3 = handleIdentifier.indexOf(AspectElement.JEM_ASPECT_TYPE); |
| String aspectName = handleIdentifier.substring(index3 + 1); |
| boolean identifierIsAspect = true; |
| int ind7 = aspectName.indexOf(AspectElement.JEM_DECLARE); |
| if (ind7 != -1) { |
| aspectName = aspectName.substring(0, ind7); |
| identifierIsAspect = false; |
| } |
| int ind8 = aspectName.indexOf(AspectElement.JEM_ADVICE); |
| if (ind8 != -1) { |
| aspectName = aspectName.substring(0, ind8); |
| identifierIsAspect = false; |
| } |
| int ind9 = aspectName.indexOf(AspectElement.JEM_ITD_METHOD); |
| if (ind9 != -1) { |
| aspectName = aspectName.substring(0, ind9); |
| identifierIsAspect = false; |
| } |
| ind9 = aspectName.indexOf(AspectElement.JEM_ITD_FIELD); |
| if (ind9 != -1) { |
| aspectName = aspectName.substring(0, ind9); |
| identifierIsAspect = false; |
| } |
| int ind10 = aspectName.indexOf(AspectElement.JEM_ASPECT_TYPE); |
| if (ind10 != -1) { |
| aspectName = aspectName.substring(0, ind10); |
| identifierIsAspect = false; |
| } |
| int ind11 = aspectName.indexOf(AspectElement.JEM_TYPE); |
| if (ind11 != -1) { |
| aspectName = aspectName.substring(0, ind11); |
| identifierIsAspect = false; |
| } |
| int ind12 = aspectName.indexOf(AspectElement.JEM_FIELD); |
| if (ind12 != -1) { |
| aspectName = aspectName.substring(0, ind12); |
| identifierIsAspect = false; |
| } |
| int ind13 = aspectName.indexOf(AspectElement.JEM_METHOD); |
| if (ind13 != -1) { |
| aspectName = aspectName.substring(0, ind13); |
| identifierIsAspect = false; |
| } |
| int ind14 = aspectName.indexOf(AspectElement.JEM_POINTCUT); |
| if (ind14 != -1) { |
| aspectName = aspectName.substring(0, ind14); |
| identifierIsAspect = false; |
| } |
| IOpenable openable; |
| if (cuName.endsWith(".class")) { |
| openable = pf.getClassFile(cuName); |
| } else { |
| openable = pf.getCompilationUnit(cuName); |
| } |
| List l; |
| if(aspectsInJavaFiles.get(openable) instanceof List) { |
| l = (List)aspectsInJavaFiles.get(openable); |
| } else { |
| l = new ArrayList(); |
| aspectsInJavaFiles.put(openable, l); |
| } |
| JavaElement aspectEl = null; |
| for (Iterator iter = l.iterator(); iter.hasNext();) { |
| AspectElement element = (AspectElement) iter.next(); |
| if(element.getElementName().equals(aspectName)) { |
| aspectEl = element; |
| } |
| } |
| if(aspectEl == null) { |
| if (openable instanceof ClassFile) { |
| ClassFile cOpenable = (ClassFile) openable; |
| aspectEl = new BinaryAspectElement((JavaElement) cOpenable, aspectName); |
| } else { |
| aspectEl = new AspectElement((JavaElement) openable, aspectName); |
| } |
| l.add(aspectEl); |
| } |
| int afterAspectIndex = index3 + aspectName.length() + 1; |
| |
| |
| if (identifierIsAspect) { |
| return aspectEl; |
| } else { |
| memento.setIndexTo(afterAspectIndex); |
| return aspectEl.getHandleFromMemento(memento.nextToken(), memento, owner); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| // XXX can we get here??? |
| if (isCodeElement) { |
| // an injar aspect with no parent |
| return new AJInjarElement(codeElementHandle); |
| } |
| return JavaCore.create(handleIdentifier); |
| } |
| |
| /** |
| * Converts a handle signifying Java class to a handle signifying an |
| * aspect element. |
| * |
| * This method is necessary because JavaCore does not create |
| * AspectElements when it is building structure using the {@link AspectsConvertingParser} |
| * |
| * Note that this changes the top level class to being an aspect and keeps |
| * all others the same. This may not work in all situations (eg- an inner aspect) |
| * |
| * @param classHandle |
| * @return converts the handle to using {@link AspectElement#JEM_ASPECT_CU} and |
| * {@link AspectElement#JEM_ASPECT_TYPE} |
| */ |
| public static String convertToAspectHandle(String classHandle, IJavaElement elt) { |
| String aspectHandle = classHandle.replaceFirst("\\" + |
| Character.toString(JavaElement.JEM_TYPE), |
| Character.toString(AspectElement.JEM_ASPECT_TYPE)); |
| |
| if (CoreUtils.ASPECTJ_SOURCE_ONLY_FILTER.accept(elt.getResource().getName())) { |
| aspectHandle = aspectHandle.replace(JavaElement.JEM_COMPILATIONUNIT, |
| AspectElement.JEM_ASPECT_CU); |
| } |
| return aspectHandle; |
| } |
| |
| |
| public static String convertToJavaCUHandle(String aspectHandle, IJavaElement elt) { |
| String javaHandle = aspectHandle; |
| if (elt != null) { |
| IResource resource = elt.getResource(); |
| if (resource != null) { |
| if (CoreUtils.ASPECTJ_SOURCE_ONLY_FILTER.accept(resource.getName())) { |
| javaHandle = javaHandle.replaceFirst("\\" + AspectElement.JEM_ASPECT_CU, |
| Character.toString(JavaElement.JEM_COMPILATIONUNIT)); |
| } |
| } |
| } |
| return javaHandle; |
| } |
| |
| } |
| |