/******************************************************************************* * Copyright (c) 2000, 2008 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 net.sourceforge.phpdt.core.dom; import java.util.Iterator; import java.util.List; import net.sourceforge.phpdt.core.ICompilationUnit; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IPackageFragment; import net.sourceforge.phpdt.core.IPackageFragmentRoot; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.internal.compiler.env.IBinaryAnnotation; import net.sourceforge.phpdt.internal.compiler.env.IBinaryType; import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment; import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer; import net.sourceforge.phpdt.internal.compiler.lookup.BinaryTypeBinding; import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; import net.sourceforge.phpdt.internal.compiler.util.Util; import net.sourceforge.phpdt.internal.core.NameLookup; import net.sourceforge.phpdt.internal.core.SearchableEnvironment; /** * Internal implementation of package bindings. */ class PackageBinding implements IPackageBinding { private static final String[] NO_NAME_COMPONENTS = CharOperation.NO_STRINGS; private static final String UNNAMED = Util.EMPTY_STRING; private static final char PACKAGE_NAME_SEPARATOR = '.'; private net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding binding; private String name; private BindingResolver resolver; private String[] components; PackageBinding(net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding binding, BindingResolver resolver) { this.binding = binding; this.resolver = resolver; } public IAnnotationBinding[] getAnnotations() { try { INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment; if (!(nameEnvironment instanceof SearchableEnvironment)) return AnnotationBinding.NoAnnotations; NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup; if (nameLookup == null) return AnnotationBinding.NoAnnotations; final String pkgName = getName(); IPackageFragment[] pkgs = nameLookup.findPackageFragments(pkgName, false/*exact match*/); if (pkgs == null) return AnnotationBinding.NoAnnotations; for (int i = 0, len = pkgs.length; i < len; i++) { int fragType = pkgs[i].getKind(); switch(fragType) { case IPackageFragmentRoot.K_SOURCE: String unitName = "package-info.java"; //$NON-NLS-1$ ICompilationUnit unit = pkgs[i].getCompilationUnit(unitName); if (unit != null && unit.exists()) { ASTParser p = ASTParser.newParser(AST.JLS3); p.setSource(unit); p.setResolveBindings(true); p.setUnitName(unitName); p.setFocalPosition(0); p.setKind(ASTParser.K_COMPILATION_UNIT); CompilationUnit domUnit = (CompilationUnit) p.createAST(null); PackageDeclaration pkgDecl = domUnit.getPackage(); if (pkgDecl != null) { List annos = pkgDecl.annotations(); if (annos == null || annos.isEmpty()) return AnnotationBinding.NoAnnotations; IAnnotationBinding[] result = new IAnnotationBinding[annos.size()]; int index=0; for (Iterator it = annos.iterator(); it.hasNext(); index++) { result[index] = ((Annotation) it.next()).resolveAnnotationBinding(); // not resolving bindings if (result[index] == null) return AnnotationBinding.NoAnnotations; } return result; } } break; case IPackageFragmentRoot.K_BINARY: NameEnvironmentAnswer answer = nameEnvironment.findType(TypeConstants.PACKAGE_INFO_NAME, this.binding.compoundName); if (answer != null && answer.isBinaryType()) { IBinaryType type = answer.getBinaryType(); char[][][] missingTypeNames = type.getMissingTypeNames(); IBinaryAnnotation[] binaryAnnotations = type.getAnnotations(); net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding[] binaryInstances = BinaryTypeBinding.createAnnotations(binaryAnnotations, this.binding.environment, missingTypeNames); net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding[] allInstances = net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding.addStandardAnnotations(binaryInstances, type.getTagBits(), this.binding.environment); int total = allInstances.length; IAnnotationBinding[] domInstances = new AnnotationBinding[total]; for (int a = 0; a < total; a++) { final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(allInstances[a]); if (annotationInstance == null) {// not resolving binding return AnnotationBinding.NoAnnotations; } domInstances[a] = annotationInstance; } return domInstances; } } } } catch(JavaModelException e) { return AnnotationBinding.NoAnnotations; } return AnnotationBinding.NoAnnotations; } /* * @see IBinding#getName() */ public String getName() { if (name == null) { computeNameAndComponents(); } return name; } /* * @see IPackageBinding#isUnnamed() */ public boolean isUnnamed() { return getName().equals(UNNAMED); } /* * @see IPackageBinding#getNameComponents() */ public String[] getNameComponents() { if (components == null) { computeNameAndComponents(); } return components; } /* * @see IBinding#getKind() */ public int getKind() { return IBinding.PACKAGE; } /* * @see IBinding#getModifiers() */ public int getModifiers() { return Modifier.NONE; } /* * @see IBinding#isDeprecated() */ public boolean isDeprecated() { return false; } /** * @see IBinding#isRecovered() */ public boolean isRecovered() { return false; } /** * @see IBinding#isSynthetic() */ public boolean isSynthetic() { return false; } /* * @see IBinding#getJavaElement() */ public IJavaElement getJavaElement() { INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment; // a package binding always has a LooupEnvironment set if (!(nameEnvironment instanceof SearchableEnvironment)) return null; NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup; if (nameLookup == null) return null; IJavaElement[] pkgs = nameLookup.findPackageFragments(getName(), false/*exact match*/); if (pkgs == null) return null; return pkgs[0]; } /* * @see IBinding#getKey() */ public String getKey() { return new String(this.binding.computeUniqueKey()); } /* * @see IBinding#isEqualTo(Binding) * @since 3.1 */ public boolean isEqualTo(IBinding other) { if (other == this) { // identical binding - equal (key or no key) return true; } if (other == null) { // other binding missing return false; } if (!(other instanceof PackageBinding)) { return false; } net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding packageBinding2 = ((PackageBinding) other).binding; return CharOperation.equals(this.binding.compoundName, packageBinding2.compoundName); } private void computeNameAndComponents() { char[][] compoundName = this.binding.compoundName; if (compoundName == CharOperation.NO_CHAR_CHAR || compoundName == null) { name = UNNAMED; components = NO_NAME_COMPONENTS; } else { int length = compoundName.length; components = new String[length]; StringBuffer buffer = new StringBuffer(); for (int i = 0; i < length - 1; i++) { components[i] = new String(compoundName[i]); buffer.append(compoundName[i]).append(PACKAGE_NAME_SEPARATOR); } components[length - 1] = new String(compoundName[length - 1]); buffer.append(compoundName[length - 1]); name = buffer.toString(); } } /* * For debugging purpose only. * @see java.lang.Object#toString() */ public String toString() { return this.binding.toString(); } }