/******************************************************************************* * Copyright (c) 2010, 2015 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.cdi.internal.core.scanner; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IPackageDeclaration; import org.eclipse.jdt.core.IType; import org.jboss.tools.cdi.core.CDICorePlugin; import org.jboss.tools.cdi.core.ICDIBuilderDelegate; import org.jboss.tools.cdi.internal.core.scanner.lib.BeanArchiveDetector; import org.jboss.tools.common.model.XModelObject; /** * * @author Viacheslav Kabanovich * */ public class FileSet implements ICDIBuilderDelegate.IFileSet { private Set<IPath> allpaths = new HashSet<IPath>(); private Set<IPath> nonmodel = new HashSet<IPath>(); private Map<IPath, List<IType>> annotations = new HashMap<IPath, List<IType>>(); private Map<IPath, List<IType>> interfaces = new HashMap<IPath, List<IType>>(); private Map<IPath, List<IType>> classes = new HashMap<IPath, List<IType>>(); private Map<IPath, IPackageDeclaration> packages = new HashMap<IPath, IPackageDeclaration>(); private Map<IPath, XModelObject> beanXMLs = new HashMap<IPath, XModelObject>(); private boolean checkVetoed = false; public FileSet() {} public void setCheckVetoed(boolean b) { checkVetoed = b; } public void add(IPath path, IType[] types) throws CoreException { allpaths.add(path); if(types.length == 0) { nonmodel.add(path); } else { for (IType type: types) { add(path, type); } } } public void add(IPath path, IType type) throws CoreException { allpaths.add(path); if(!checkType(type, path)) { //do nothing, bug JDT } else if(type.isAnonymous()) { //is not bean } else if(type.getDeclaringType() != null && !Flags.isStatic(type.getFlags())) { //is not bean } else if(type.getFullyQualifiedName().indexOf('$') > 0 && !Flags.isStatic(type.getFlags())) { //is not bean } else if(type.isAnnotation()) { add(annotations, path, type); } else if(type.isInterface()) { add(interfaces, path, type); } else { add(classes, path, type); IType[] ts = type.getTypes(); for (IType t: ts) { if(checkType(t, path) && Flags.isStatic(t.getFlags())) { add(path, t); } } } } private static Set<IPath> failedPaths = new HashSet<IPath>(); /** * Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=342757 * This method and field failedPaths should be removed as soon as the * issue is fixed. * @param type * @param path * @return * @throws CoreException */ private boolean checkType(IType type, IPath path) throws CoreException { try { type.isAnnotation(); } catch (ArrayIndexOutOfBoundsException e) { if(failedPaths.contains(path)) return false; // Do not let's be too noisy. failedPaths.add(path); CDICorePlugin.getDefault().logError("JDT failed to load " + type.getFullyQualifiedName() + " from " + path + "\nSee https://bugs.eclipse.org/bugs/show_bug.cgi?id=342757"); return false; } return true; } private void add(Map<IPath, List<IType>> target, IPath path, IType type) throws CoreException { if(checkVetoed && BeanArchiveDetector.isVetoed(type)) { return; } List<IType> ts = target.get(path); if(ts == null) { ts = new ArrayList<IType>(); target.put(path, ts); } ts.add(type); } public void add(IPath path, IPackageDeclaration pkg) throws CoreException { allpaths.add(path); packages.put(path, pkg); } @Override public Set<IPath> getAllPaths() { return allpaths; } public Set<IPath> getNonModelFiles() { return nonmodel; } @Override public Map<IPath, List<IType>> getAnnotations() { return annotations; } @Override public Map<IPath, List<IType>> getInterfaces() { return interfaces; } @Override public Map<IPath, List<IType>> getClasses() { return classes; } @Override public Map<IPath, IPackageDeclaration> getPackages() { return packages; } @Override public XModelObject getBeanXML(IPath f) { return beanXMLs.get(f); } public void setBeanXML(IPath f, XModelObject o) { beanXMLs.put(f, o); allpaths.add(f); } }