alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.modules.javacore;

import java.io.*;
import java.util.*;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.queries.SourceLevelQuery;
import org.netbeans.api.mdr.MDRepository;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.lib.java.parser.Factory;
import org.netbeans.lib.java.parser.JScanner;
import org.netbeans.lib.java.parser.ParserTokens;
import org.netbeans.mdr.NBMDRepositoryImpl;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.netbeans.modules.javacore.jmiimpl.javamodel.JavaClassImpl;
import org.netbeans.mdr.util.IOUtils;
import org.netbeans.mdr.persistence.MOFID;
import org.netbeans.mdr.handlers.BaseObjectHandler;
import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileStateInvalidException;
import org.openide.filesystems.JarFileSystem;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;

/**
 *
 * @author  Tomas Hurka, Martin Matula
 */
public class ClassIndex implements Serializable {
    private static final int VERSION = 2;

    static Map codebaseIndexes=Collections.synchronizedMap(new HashMap());
    private static final String INDEX_SUFFIX=".cdx"; // NOI18N
    private SortedMap fqnMap;
    private SortedMap simpleMap;
    private Map identifiersMap;
    private String storageId;
    private long lastSaved;
    private transient NBMDRepositoryImpl rep;
    private transient String filename;
    private transient boolean isDirty;
    private transient HashMap changeLogSN;
    private transient HashMap changeLogFQN;
    private transient HashMap changeLogI;
    
    private static boolean shutdownListenerRegistered = false;
    private static final ShutdownL shutdownListener = new ShutdownL();
    
    private static final long serialVersionUID = -2611840548775984571L;
    private static final boolean DEBUG = false;

    /** Creates a new instance of ClassIndex */
    private ClassIndex(String file, String storageId) {
        this.storageId = storageId;
        rep = (NBMDRepositoryImpl) JavaMetamodel.getDefaultRepository();
        filename = file;
        cleanIndex();
        // register shutdown listener
        if (!shutdownListenerRegistered) {
            synchronized (shutdownListener) {
                if (!shutdownListenerRegistered) {
                    ((NBMDRepositoryImpl) JavaMetamodel.getDefaultRepository()).addShutdownListener(shutdownListener);
                    shutdownListenerRegistered = true;
                }
            }
        }
    }
    
    void cleanIndex() {
        fqnMap = new TreeMap();
        simpleMap = new TreeMap();
        identifiersMap = new HashMap();
        isDirty = true;
    }
    
    static void commit() {
        for (Iterator it = codebaseIndexes.values().iterator(); it.hasNext();) {
            ((ClassIndex) it.next()).commitChanges();
        }
    }
    
    static void rollback() {
        for (Iterator it = codebaseIndexes.values().iterator(); it.hasNext();) {
            ((ClassIndex) it.next()).rollbackChanges();
        }
    }
    
    private void commitChanges() {
        changeLogSN = null;
        changeLogFQN = null;
        changeLogI = null;
    }
    
    private void rollbackChanges() {
        if (changeLogSN != null) {
            for (Iterator it = changeLogSN.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                it.remove();
                long mofId = ((Long) entry.getKey()).longValue();
                if (entry.getValue() == null) {
                    JavaClass cls = (JavaClass) rep.getByMofId(makeMofId(mofId));
                    if (cls != null) {
                        addClass(cls, cls.getName(), cls.getSimpleName());
                    }
                } else {
                    removeFromMap(simpleMap, entry.getValue(), mofId);
                    // list of fqn changes is superset of this list so I don't have to add the class
                    // to index here - it will be done when iterating through changeLogFQN below
                }
            }
        }
        
        if (changeLogFQN != null) {
            for (Iterator it = changeLogFQN.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                it.remove();
                long mofId = ((Long) entry.getKey()).longValue();
                JavaClass cls = (JavaClass) rep.getByMofId(makeMofId(mofId));
                if (entry.getValue() != null) {
                    removeFromMap(fqnMap, entry.getValue(), mofId);
                }
                if (cls != null) {
                    addClass(cls, cls.getName(), cls.getSimpleName());
                }
            }
        }
        
        if (changeLogI != null) {
            for (Iterator it = changeLogI.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                it.remove();
                identifiersMap.put(entry.getKey(), entry.getValue());
            }
        }
    }
    
    private void removeFromMap(Map map, Object key, long value) {
        if (map == simpleMap) {
            key = ((String) key).toUpperCase();
        }
        Object temp = map.get(key);
        if (temp != null) {
            long[] oldValue = (long[]) temp;
            int len = oldValue.length;
            long[] newValue = new long[len - 1];
            int i = 0, j = 0;
            for (; i < len && j < len - 1; i++) {
                if (oldValue[i] != value) {
                    newValue[j++] = oldValue[i];
                }
            }
            
            if (i < len && oldValue[i] != value) {
                if (j < len - 1) {
                    newValue[j] = oldValue[i];
                } else {
                    newValue = oldValue;
                }
            }
            
            if (oldValue != newValue) {
                if (newValue.length == 0) {
                    map.remove(key);
                } else {
                    map.put(key, newValue);
                }
            }
        }
    }
    
    public static ClassIndex getIndex(JavaModelPackage mofPackage) {
        return (ClassIndex)codebaseIndexes.get(mofPackage);
    }
    
    private static void saveAllIndexes() {
        MDRepository rep=JavaMetamodel.getDefaultRepository();
        
        rep.beginTrans(false);
        try {
            synchronized(codebaseIndexes) {
                Iterator indexIt=codebaseIndexes.values().iterator();

                while(indexIt.hasNext()) {
                    ClassIndex index=(ClassIndex)indexIt.next();

                    index.saveIndex();
                }
            }
        } finally {
            rep.endTrans();
        }
    }
    
    static void removeIndex(JavaModelPackage mofPackage) {
        ClassIndex index=(ClassIndex)codebaseIndexes.remove(mofPackage);
        index.saveIndex();
    }
    
    static void saveIndex(JavaModelPackage mofPackage) {
        ClassIndex index=(ClassIndex)codebaseIndexes.get(mofPackage);
        index.saveIndex();
    }
    
    static void cleanIndex(JavaModelPackage mofPackage) {
        ClassIndex index=(ClassIndex)codebaseIndexes.get(mofPackage);
        index.cleanIndex();
    }
    
    static void addIndex(JavaModelPackage mofPackage,String filename) {
        codebaseIndexes.put(mofPackage, new ClassIndex(filename, ((BaseObjectHandler) mofPackage)._getDelegate().getMofId().getStorageID()));
    }
    
    static boolean loadIndexFrom(String filename,JavaModelPackage mofPackage) {
        long t = 0;
        try {
            if (JMManager.PERF_DEBUG) {
                t = System.currentTimeMillis();
            }
            File indexFile=new File(filename.concat(INDEX_SUFFIX));
            InputStream indexStream=new BufferedInputStream(new FileInputStream(indexFile), 65536);
            ClassIndex index;
            try {
                index = new ClassIndex(filename, ((BaseObjectHandler) mofPackage)._getDelegate().getMofId().getStorageID()).read(indexStream);
            } finally {
                indexStream.close();
            }
            if (index == null) {
                addIndex(mofPackage, filename);
            } else {
                codebaseIndexes.put(mofPackage,index);
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            addIndex(mofPackage,filename);
            return false;
        } finally {
            if (JMManager.PERF_DEBUG) {
                System.err.println("loading index " + filename + " took: " + (System.currentTimeMillis() - t) + "ms");
            }
        }
    }

    private ClassIndex read(InputStream indexStream) throws IOException {
        if (VERSION != IOUtils.readInt(indexStream)) return null;
        if (!storageId.equals(IOUtils.readString(indexStream))) return null;
        readMap(indexStream, fqnMap);
        readMap(indexStream, simpleMap);

        int count = IOUtils.readInt(indexStream);
        for (int i = 0; i < count; i++) {
            Long key = new Long(IOUtils.readLong(indexStream));
            int count2 = IOUtils.readInt(indexStream);
            int[] value = new int[count2];
            for (int j = 0; j < count2; j++) {
                value[j] = IOUtils.readInt(indexStream);
            }
            identifiersMap.put(key, value);
        }
        lastSaved = IOUtils.readLong(indexStream);
        return this;
    }

    private void write(OutputStream indexStream) throws IOException {
        if (JMManager.PERF_DEBUG) System.err.println("fqnMap: " + fqnMap.size() + " records; identifiersMap: " + identifiersMap.size() + "records");
        IOUtils.writeInt(indexStream, VERSION);
        IOUtils.writeString(indexStream, storageId);
        writeMap(indexStream, fqnMap);
        writeMap(indexStream, simpleMap);

        IOUtils.writeInt(indexStream, identifiersMap.size());
        for (Iterator it = identifiersMap.entrySet().iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            IOUtils.writeLong(indexStream, ((Long) entry.getKey()).longValue());

            int[] array = (int[]) entry.getValue();
            IOUtils.writeInt(indexStream, array.length);
            for (int i = 0; i < array.length; i++) {
                IOUtils.writeInt(indexStream, array[i]);
            }
        }

        IOUtils.writeLong(indexStream, System.currentTimeMillis());
    }

    private void readMap(InputStream indexStream, Map map) throws IOException {
        int count = IOUtils.readInt(indexStream);
        for (int i = 0; i < count; i++) {
            String key = IOUtils.readString(indexStream);
            int count2 = IOUtils.readInt(indexStream);
            long[] value = new long[count2];
            for (int j = 0; j < count2; j++) {
                value[j] = IOUtils.readLong(indexStream);
            }
            map.put(key, value);
        }
    }

    private void writeMap(OutputStream indexStream, Map map) throws IOException {
        IOUtils.writeInt(indexStream, map.size());
        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            IOUtils.writeString(indexStream, (String) entry.getKey());

            long[] array = (long[]) entry.getValue();
            IOUtils.writeInt(indexStream, array.length);
            for (int i = 0; i < array.length; i++) {
                IOUtils.writeLong(indexStream, array[i]);
            }
        }
    }

    void saveIndex() {
        if (!isDirty)
            return;
        if (JMManager.PERF_DEBUG) {
            System.err.println("saving index " + filename);
        }
        rep.beginTrans(false);
        try {
            FileOutputStream fos=new FileOutputStream(filename.concat(INDEX_SUFFIX));
            BufferedOutputStream indexStream=new BufferedOutputStream(fos, 65536);
            try {
                write(indexStream);
            } finally {
                indexStream.close();
            }
            isDirty=false;
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            rep.endTrans();
        }
    }
    
    public void renameClass(JavaClass jcls, String newName) {
        long mofId = getMofId(jcls);
        String name = jcls.getName();
        String simpleName = jcls.getSimpleName();
        String newSimpleName = JavaClassImpl.getSimpleName(newName);

        if (JMManager.INCONSISTENCY_DEBUG) System.err.println("ClassIndex: Renaming class: " + name + " to: " + newName + " MOFID: " + jcls.refMofId());
        //Thread.dumpStack();
        
        isDirty=true;
        removeFromMap(fqnMap, name, mofId);
        
        Long objMofId = new Long(mofId);
        logFQNChange(objMofId, newName);
        if (!simpleName.equals(newSimpleName)) {
            removeFromMap(simpleMap, simpleName, mofId);
            logSNChange(objMofId, newSimpleName);
        }
        addClass(jcls, newName, newSimpleName);
    }
    
    private static HashMap logChange(HashMap map, Long mofId, Object value) {
        if (map == null) {
            map = new HashMap();
        }
        map.put(mofId, value);
        return map;
    }
    
    private void logFQNChange(Long mofId, String name) {
        changeLogFQN = logChange(changeLogFQN, mofId, name);
    }
    
    private void logSNChange(Long mofId, String name) {
        changeLogSN = logChange(changeLogSN, mofId, name);
    }
    
    public void addClass(JavaClass jcls,String fqn,String simpleName) {
        if (JMManager.INCONSISTENCY_DEBUG) System.err.println("ClassIndex: Adding class " + fqn + " MOFID: " + jcls.refMofId());
        long mofId = getMofId(jcls);

        isDirty=true;
        addToMap(fqnMap, fqn, mofId);
        addToMap(simpleMap, simpleName, mofId);
    }
    
    private void addToMap(Map map, Object key, long value) {
        if (map == simpleMap) {
            key = ((String) key).toUpperCase();
        }
        long[] temp = (long[]) map.get(key);
        long[] newValue;
        int len;
        if (temp == null) {
            len = 0;
            newValue = new long[len + 1];
        } else {
            long[] oldValue = temp;
            len = oldValue.length;
            newValue = new long[len + 1];
            for (int i = 0; i < len; i++) {
                if (oldValue[i] == value) {
                    newValue = oldValue;
                    break;
                }
                newValue[i] = oldValue[i];
            }
        }
        if (newValue != temp) {
            newValue[len] = value;
            map.put(key, newValue);
        }
    }
    
    public long getTimestamp() {
        return lastSaved;
    }

    public Set getClassesByFqn(String fqn) {
        Set result = new HashSet();
        long[] classes = (long[]) fqnMap.get(fqn);
        if (classes != null) {
            JavaClass cls = null;
            int j = 0;
            for (int i = 0; i < classes.length; i++) {
                JavaClass temp = (JavaClass) rep.getByMofId(makeMofId(classes[i]));
                if (temp == null) {
                    logFQNChange(new Long(classes[i]), null);
                } else {
                    classes[j] = classes[i];
                    j++;
                    result.add(temp);
                }
            }
            if (j == 0) {
                fqnMap.remove(fqn);
            } else if (j < classes.length) {
                long[] newValue = new long[j];
                System.arraycopy(classes, 0, newValue, 0, j);
                fqnMap.put(fqn, newValue);
            }
        }
        return result;
    }

    public JavaClass getClassByFqn(String fqn) {
        long[] classes = (long[]) fqnMap.get(fqn);
        if (classes != null) {
            JavaClass result = null;
            JavaClass sureResult = null;
            int j = 0;
            for (int i = 0; i < classes.length; i++) {
                JavaClass temp = (JavaClass) rep.getByMofId(makeMofId(classes[i]));
                if (temp == null) {
                    logFQNChange(new Long(classes[i]), null);
                } else {
                    classes[j] = classes[i];
                    j++;
                    result = temp;
                    // [TODO] the following code can be incommented if necessary
                    // (it tries to prefer classes that are in the correct folder)
                    // now it is commented out for performance reasons
//                    Resource res = (Resource) result.refImmediateComposite();
//                    if (res != null) {
//                        if (res.getName().replace('/', '.').startsWith(res.getPackageName())) {
//                            sureResult = result;
//                        }
//                    }
                }
            }
            if (j == 0) {
                fqnMap.remove(fqn);
            } else if (j < classes.length) {
                long[] newValue = new long[j];
                System.arraycopy(classes, 0, newValue, 0, j);
                fqnMap.put(fqn, newValue);
            }
            return sureResult == null ? result : sureResult;
        }
        return null;
    }
    
    public List getClassesByFQNPrefix(String fqnPrefix) {
        SortedMap map;
        if (fqnPrefix == null || fqnPrefix.length() == 0) {
            map = fqnMap;
        } else {
            map = fqnMap.subMap(fqnPrefix, fqnPrefix + '\uffff');
        }
        ArrayList result = new ArrayList(map.size());
        int length = fqnPrefix.length();
        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            if (((String) entry.getKey()).lastIndexOf('.') < length) {
                long[] value = (long[]) entry.getValue();
                int j = 0;
                for (int i = 0; i < value.length; i++) {
                    Object cls = (JavaClass) rep.getByMofId(makeMofId(value[i]));
                    if (cls == null) {
                        logFQNChange(new Long(value[i]), null);
                    } else {
                        value[j] = value[i];
                        j++;
                        result.add(cls);
                    }
                }
                if (j == 0) {
                    it.remove();
                } else if (j < value.length) {
                    long[] newValue = new long[j];
                    System.arraycopy(value, 0, newValue, 0, j);
                    entry.setValue(newValue);
                }
            }
        }
        return result;
    }
    
    /**
     * Looks for the classes in class index by prefix. Finding mechanism is case
     * sensitive.
     *
     * @param  snPrefix  simple name leading characters of class which will 
     *                   be looked for
     * @return   list of matching JavaClasses instances ordered by their names
     */
    public LazyImmutableList getClassesBySNPrefix(String snPrefix) {
        return getClassesBySNPrefix(snPrefix, true);
    }
    
    /**
     * Looks for the classes in class index by prefix. Finding can be either 
     * case-sensitive or case-insensitive.
     *
     * @param  snPrefix  simple name leading characters of class which
     *                     will be looked for
     * @return   list of matching JavaClasses instances ordered by names
     */
    public LazyImmutableList getClassesBySNPrefix(String snPrefix, boolean caseSensitive) {
        SortedMap map;
        if (snPrefix == null || snPrefix.length() == 0) {
            map = simpleMap;
        } else {
            String snPrefixUp = snPrefix.toUpperCase();
            map = simpleMap.subMap(snPrefixUp, snPrefixUp + '\uffff');
        }
        return new LazyImmutableList(new ClassesBySNPrefixIterator(map,snPrefix,caseSensitive));
    }
    
    public boolean doesnotExist(String fqn) {
        return fqnMap.get(fqn)==null;
    }
    
    public boolean hasClass(String fqn) {
        return getClassByFqn(fqn) != null;
    }
    
    /**
     * Looks for the classes in class index. Finding mechanism is case
     * sensitive.
     *
     * @param  simpleName  simple (short) name of class which will be looked for
     * @return   collection of matching JavaClasses instances
     */
    public Collection getClassesBySimpleName(String simpleName) {
        return getClassesBySimpleName(simpleName, true);
    }
    
    /**
     * Looks for the classes in class index. Finding can be either 
     * case-sensitive or case-insensitive.
     *
     * @param  simpleName  simple (short) name of class which will be looked for
     * @param  caseSensitive  use false when you want to ignore case
     * @return   collection of matching JavaClasses instances
     */
    public Collection getClassesBySimpleName(String simpleName, boolean caseSensitive) {
        String simpleUpper = simpleName.toUpperCase();
        long[] value = (long[]) simpleMap.get(simpleUpper);
        List res=new ArrayList();
        
        if (value!=null) {
            int j = 0;
            for (int i = 0; i < value.length; i++) {
                JavaClass cls = (JavaClass) rep.getByMofId(makeMofId(value[i]));
                if (cls == null) {
                    logSNChange(new Long(value[i]), null);
                } else {
                    value[j] = value[i];
                    j++;
                    if (!caseSensitive || simpleName.equals(cls.getSimpleName())) {
                        res.add(cls);
                    }
                }
            }
            if (j == 0) {
                simpleMap.remove(simpleUpper);
            } else if (j < value.length) {
                long[] newValue = new long[j];
                System.arraycopy(value, 0, newValue, 0, j);
                simpleMap.put(simpleUpper, newValue);
            }
        }
        return res;
    }
    
    public static boolean hasClass(String fqn,ClassPath classPath) {
        FileObject[] roots = classPath.getRoots();
        // iteruj pres rooty a hledej classu podle FQN
        for (int i = 0; i < roots.length; i++) {
            JavaModelPackage mofPackage = JavaMetamodel.getManager().getJavaExtent(roots[i]);
            // test for mofPackage != null is needed when any other thread 
            // mounts the new filesystem and we do not know about it yet.
            // It is in list of all filesystem roots, but we do not have created
            // package for it yet. In such a case, the index does not contain
            // class and we will return false.
            if (mofPackage!=null && ClassIndex.getIndex(mofPackage).hasClass(fqn))
                return true;
        }
        return false;
    }

    public static JavaClass getClassByFqn(String fqn, ClassPath classPath) {
        FileObject[] roots = classPath.getRoots();
        for (int i = 0; i < roots.length; i++) {
            JavaModelPackage mofPackage = org.netbeans.modules.javacore.internalapi.JavaMetamodel.getManager().getJavaExtent(roots[i]);
            if (mofPackage != null) {
                ClassIndex index = ClassIndex.getIndex(mofPackage);
                if (index != null) {
                    JavaClass cls = index.getClassByFqn(fqn);
                    if (cls != null) {
                        return cls;
                    }
                }
            }
        }
        return null;
    }

    public void setIdentifiers(Resource rsc,int identifiers[]) {
        isDirty=true;
        Arrays.sort(identifiers);        
        identifiersMap.put(new Long(getMofId(rsc)), identifiers);
    }
    
    private long getMofId(Object obj) {
        return ((BaseObjectHandler) obj)._getMofId().getSerialNumber();
    }
    
    private MOFID makeMofId(long mofId) {
        return new MOFID(mofId, storageId);
    }
    
    public void removeResource(Resource rsc) {
        isDirty = true;
        Long mofId = new Long(getMofId(rsc));
        Object o = identifiersMap.remove(mofId);
        changeLogI = logChange(changeLogI, mofId, o);
    }

    void updateIdentifiersInResource(Resource rsc,String sourceText) {
        FileObject file=JavaMetamodel.getManager().getFileObject(rsc);
        String sourceLevel=SourceLevelQuery.getSourceLevel(file);
        JScanner scanner=Factory.getDefault().getScanner(new StringReader(sourceText),sourceLevel);
        int token;
        int identifiers[]=(int[])identifiersMap.get(new Long(getMofId(rsc)));
        List newIds=new ArrayList(10);
        int newIdSize;
        
        try {
            while((token=scanner.yylex())!=0) {
                if (token==ParserTokens.IDENTIFIER) {
                    String text=scanner.yytext();
                    int hash=text.hashCode();

                    if (Arrays.binarySearch(identifiers,hash)<0) {
                        newIds.add(text);
                    }
                }
            }
        }
        catch (IOException ex) {
            ErrorManager.getDefault().notify(ex);
        }
        newIdSize=newIds.size();
        if (newIdSize>0) {
            int ids[]=new int[identifiers.length+newIdSize];
            String newIdArr[]=(String[])newIds.toArray(new String[newIdSize]);
            int i;
            
            for (i=0;i=0) {
                Object obj = rep.getByMofId(makeMofId(((Long) en.getKey()).longValue()));
                if (obj == null) {
                    it.remove();
                } else {
                    res.add(obj);
                }
            }
        }
        return res;
    }

    private class ClassesBySNPrefixIterator extends LazyImmutableList.LazyIterator {
        private final String snPrefix;
        private final boolean caseSensitive;
        private final Iterator classMapIt;
        private final int estimatedSize;
        
        private Object next = null;
        private boolean hasNext = true;
        private Iterator inner = Collections.EMPTY_LIST.iterator();

        ClassesBySNPrefixIterator(Map classMap,String prefix, boolean cases) {
            int size = 0;
            for (Iterator it = classMap.values().iterator(); it.hasNext();) {
                size += ((long[]) it.next()).length;
            }
            estimatedSize = size;
            classMapIt = classMap.entrySet().iterator();
            snPrefix = prefix;
            caseSensitive = cases;
        }
        
        public Object next() {
            if (next==null) {
                findNext();
            }
            Object result = next;
            next = null;
            return result;
        }

        public boolean hasNext() {
            findNext();
            return hasNext;
        }
        
        protected int maxEstimatedSize() {
            return estimatedSize;
        }

        private void findNext() {
            if (!hasNext) {
                throw new NoSuchElementException();
            }
            while (next==null && hasNext == true) {
                if (inner.hasNext()) {
                    next=inner.next();
                }
                else if (classMapIt.hasNext()) {
                    inner=getClassesBySNPrefix().iterator();
                } else {
                    hasNext=false;
                }
            }
        }

        private Collection getClassesBySNPrefix() {
            Collection result=new ArrayList();
            Map.Entry entry = (Map.Entry) classMapIt.next();
            long[] value = (long[]) entry.getValue();
            int j = 0;
            for (int i = 0; i < value.length; i++) {
                JavaClass cls = (JavaClass) rep.getByMofId(makeMofId(value[i]));
                if (cls == null) {
                    logSNChange(new Long(value[i]), null);
                } else {
                    value[j] = value[i];
                    j++;
                    if (!caseSensitive || cls.getSimpleName().startsWith(snPrefix)) {
                        result.add(cls);
                    }
                }
            }
            if (j == 0) {
                classMapIt.remove();
            } else if (j < value.length) {
                long[] newValue = new long[j];
                System.arraycopy(value, 0, newValue, 0, j);
                entry.setValue(newValue);
            }                    
            return result;
        }
    }
    
    public static Resource[] findResourcesForIdentifier(String identifier,boolean includeLibraries) {
        FileObject[] roots = org.netbeans.modules.javacore.internalapi.JavaMetamodel.getManager().getClassPath().getRoots();
        // iterate through roots and find class by its FQN
        Collection resources=new ArrayList();
        org.netbeans.modules.javacore.internalapi.JavaMetamodel manager=org.netbeans.modules.javacore.internalapi.JavaMetamodel.getManager();
        boolean isJavaDocTag = identifier.startsWith("@"); // NOI18N
        
        for (int i = 0; i < roots.length; i++) {
            try {
                if (includeLibraries || !(roots[i].getFileSystem() instanceof JarFileSystem)) {
                    JavaModelPackage mofPackage = manager.getJavaExtent(roots[i]);
                    // [TODO]: temporary solution to enable IsValueFor association implementation

                    if (mofPackage != null) {
                        if (isJavaDocTag) {
                            ResourceClass resourceClass = mofPackage.getResource();
                            resources.addAll(resourceClass.refAllOfClass());
                        }
                        else {
                            resources.addAll(ClassIndex.getIndex(mofPackage).findResourcesForIdent(identifier));
                        }
                    }
                }
            } catch (FileStateInvalidException ex) {
                ErrorManager.getDefault().notify(ex);
            }
        }
        return (Resource[])resources.toArray(new Resource[resources.size()]);
    }

    public static Resource[] findResourcesForIdentifier(String identifier) {
        return findResourcesForIdentifier(identifier,false);
    }

    public static void updateIdentifiers(Resource rsc,String sourceText) {
        JavaModelPackage mofPackage=(JavaModelPackage)rsc.refOutermostPackage();
        ClassIndex.getIndex(mofPackage).updateIdentifiersInResource(rsc, sourceText);
    }
    
    public static boolean containsIdentifier(Resource rsc, int identifier) {
        JavaModelPackage mofPackage=(JavaModelPackage)rsc.refOutermostPackage();
        ClassIndex index = ClassIndex.getIndex(mofPackage);
        int[] idents = (int[]) index.identifiersMap.get(new Long(index.getMofId(rsc)));
        return Arrays.binarySearch(idents, identifier) >= 0;
    }
    
    // Shutdown listener ........................................................
    
    private static class ShutdownL implements NBMDRepositoryImpl.ShutdownListener {
        
        public void shutdown() {
            // RequestProcessor.getDefault().post(this);
            saveAllIndexes();
        }
        
        public void stepFinished() {
        }
        
    }
    
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.