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.scanning;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.lang.reflect.Modifier;
import java.util.*;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.jmi.javamodel.JavaEnum;
import org.netbeans.lib.java.parser.ParserTokens;
import org.netbeans.modules.javacore.ClassIndex;
import org.netbeans.modules.javacore.JMManager;
import org.netbeans.modules.javacore.jmiimpl.javamodel.*;
import org.netbeans.modules.javacore.parser.TokenIterator;
import org.netbeans.modules.javacore.parser.MDRParser;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.openide.ErrorManager;

/**
 *
 * @author Tomas Hurka
 */
public class JavaUpdater {
    private final JavaClassClassImpl jclsClass;
    private final JavaEnumClassImpl enumClass;
    private final AnnotationTypeClassImpl annTypeClass;
    private final ResourceClassImpl resourceClass;
    private final ClassIndex classIndex;
    private final String sourceLevel;
    private final FileScanner fileScanner;
    
    /** Creates a new instance of JavaUpdater */
    public JavaUpdater(JavaModelPackage mofModel,String srcLevel, FileScanner fileScanner) {
        jclsClass = (JavaClassClassImpl) mofModel.getJavaClass();
        enumClass = (JavaEnumClassImpl) mofModel.getJavaEnum();
        resourceClass = (ResourceClassImpl) mofModel.getResource();
        annTypeClass = (AnnotationTypeClassImpl) mofModel.getAnnotationType();
        sourceLevel = srcLevel;
        classIndex=ClassIndex.getIndex(mofModel);
        this.fileScanner = fileScanner;
    }

    public int[] computeIndex(ResourceImpl resource,TokenIterator tokens) {
        JavaMetamodel.getDefaultRepository().beginTrans(false);
        try {
            return makeIndex(resource,tokens,false);
        } finally {
            JavaMetamodel.getDefaultRepository().endTrans();
        }
    }

    private int[] makeIndex(ResourceImpl resource,TokenIterator tokens, boolean removeFeatures) {
        int idIndexes[]=null;
        boolean resInited=resource.isInitialized();
        HashSet reinitToDo = new HashSet();
        List javaClasses;
        Set remainingClasses;
        Set usedClasses = new HashSet();
        
        javaClasses=resource.getPersistentClassifiers();

        remainingClasses=getAllClassesFromResource(resource,javaClasses);
        if (!resInited) {
            javaClasses.clear();
        }
        try {
            final int S_NORMAL=0;
            final int S_PACKAGE=1;
            final int S_CLASS=2;

            String id;
            IntSet ids=new IntSet();
            Iterator idIt;
            int i=0;
            int token;
            int last_token=0;
            int state=S_NORMAL;
            int modifiers=0;
            String pack="";
            Stack classes=new Stack();
            int br_level=0;
            boolean packageSet = false;

            while((token=tokens.getNextTokenType())!=0) {
                String text=null;

                if (token==ParserTokens.IDENTIFIER) {
                    int hash=tokens.getIdentifierHash();
                    ids.add(hash);
                }
		if (tokens.isDeprecated())
		    modifiers|=FeatureImpl.DEPRECATED;
                switch (token) {
                    case ParserTokens.PUBLIC:
                        modifiers|=Modifier.PUBLIC;
                        break;
                    case ParserTokens.PROTECTED:
                        modifiers|=Modifier.PROTECTED;
                        break;
                    case ParserTokens.PRIVATE:
                        modifiers|=Modifier.PRIVATE;
                        break;
                    case ParserTokens.ABSTRACT:
                        modifiers|=Modifier.ABSTRACT;
                        break;
                    case ParserTokens.STATIC:
                        modifiers|=Modifier.STATIC;
                        break;
                    case ParserTokens.FINAL:
                        modifiers|=Modifier.FINAL;
                        break;
                    case ParserTokens.SYNCHRONIZED:
                        modifiers|=Modifier.SYNCHRONIZED;
                        break;
                    case ParserTokens.NATIVE:
                        modifiers|=Modifier.NATIVE;
                        break;
                    case ParserTokens.STRICTFP:
                        modifiers|=Modifier.STRICT;
                        break;
                    case ParserTokens.TRANSIENT:
                        modifiers|=Modifier.TRANSIENT;
                        break;
                    case ParserTokens.VOLATILE:
                        modifiers|=Modifier.VOLATILE;
                        break;
                    case ParserTokens.SEMICOLON:
                        modifiers=tokens.isDeprecated() ?
			    FeatureImpl.DEPRECATED : 0;
                        break;
                    case ParserTokens.L_CURLY:
                        br_level++;
                        modifiers=tokens.isDeprecated() ?
			    FeatureImpl.DEPRECATED : 0;
                        break;
                    case ParserTokens.R_CURLY:
                        if (br_level==classes.size() && !classes.isEmpty())
                            classes.pop();
                        br_level--;
                        break;
                }
		if (last_token==ParserTokens.MONKEYS_AT && 
		    token==ParserTokens.IDENTIFIER) {
                    String s=tokens.getIdentifierText();
		    if (s.equals("Deprecated") ||
			s.equals("java.lang.Deprecated"))
			// @Deprecated annotation found
			modifiers|=FeatureImpl.DEPRECATED; 
		}
                switch (state) {
                    case S_NORMAL:
                        if (token==ParserTokens.PACKAGE)
                            state=S_PACKAGE;
                        else if ((token==ParserTokens.CLASS || token==ParserTokens.INTERFACE || token==ParserTokens.ENUM) && last_token!=ParserTokens.DOT) {
                            if (!packageSet) {
                                if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaUpdater: Setting package name of resource " + resource.getName() + " to " + pack);
                                resource._setPackageName(pack);
                                packageSet = true;
                            }
                            if (last_token==ParserTokens.MONKEYS_AT && token==ParserTokens.INTERFACE) {
                                modifiers|=MDRParser.M_ANNOTATION; // we have found an annotation
                                ids.add("Annotation".hashCode()); // NOI18N
                            }
                            state=S_CLASS;
                        }
                        break;
                    case S_PACKAGE:
			if (token==ParserTokens.IDENTIFIER)
			    text=tokens.getIdentifierText();
                        if (text!=null) {
                            if (pack.length()==0)
                                pack=text;
                            else
                                pack=pack + '.' + text; // NOI18N
                        }
                        if (token==ParserTokens.SEMICOLON) {
                            state=S_NORMAL;
                        }
                        break;
                    case S_CLASS:
			if (token==ParserTokens.IDENTIFIER)
			    text=tokens.getIdentifierText();
                        if (br_level==classes.size() && text!=null) {
                            String fqn;
                            JavaClassImpl jcls;
                            JavaClassImpl enclosingClass=null;

                            if (!classes.empty())
                                enclosingClass=(JavaClassImpl)classes.peek();
                            fqn=constructFqn(pack,classes,text);
                            if (last_token==ParserTokens.INTERFACE) {
                                modifiers|=Modifier.INTERFACE;
                            } else if (last_token == ParserTokens.ENUM) {
                                modifiers |= MDRParser.M_ENUM;
                                ids.add("Enum".hashCode()); // NOI18N
                            }
                            jcls=createJavaClass(fqn,modifiers,removeFeatures,text,remainingClasses,usedClasses,enclosingClass);
                            usedClasses.add(jcls);
                            classes.push(jcls);
                            remainingClasses.remove(jcls);
                            if (jcls.refImmediateComposite() == null) {
                                if (enclosingClass!=null) {
                                    boolean contentsInited = enclosingClass.contentsInited();
                                    boolean contentsEmpty = enclosingClass.getPersistentContents().isEmpty();
                                    if (contentsInited || !contentsEmpty) {
                                        enclosingClass.getPersistentContents().add(jcls);
                                        if (contentsInited) {
                                            reinitToDo.add(enclosingClass);
                                        }
                                    } else {
                                        jcls.setParentClass(enclosingClass);
                                    }
                                } else {
                                    javaClasses.add(jcls);
                                }
                            }
                        }
                        state=S_NORMAL;
                }
                last_token=token;
            }
            idIndexes=ids.toArray();
            // the removal has to be done always, to avoid duplicate classes in index
//            if (!resInited) {
                for (Iterator it = remainingClasses.iterator(); it.hasNext();) {
                    JavaClass cls = (JavaClass) it.next();
                    cls.refDelete();
                }
//            }
            if (resource.classifiersInited())
                resource.reinitClassifiers();
            for (Iterator it = reinitToDo.iterator(); it.hasNext();) {
                ((JavaClassImpl) it.next()).reinitContents();
            }
        } catch (Exception ex) {
            ErrorManager.getDefault().notify(ex);
            return new int[0];
        }
        return idIndexes;
    }

    private JavaClassImpl createJavaClass(String fqn, int modifiers,boolean removeFeatures, String simpleName,Set remainingClasses,Set usedClasses,JavaClass enclosingClass) {
        Collection classes = classIndex.getClassesByFqn(fqn);
        JavaClass jcls = null;

        if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaUpdater: Looking for class: " + fqn);
        for (Iterator it = classes.iterator(); it.hasNext();) {
            JavaClass temp = (JavaClass) it.next();
            if ((!removeFeatures && enclosingClass != null && enclosingClass.equals(temp.refImmediateComposite()) && !usedClasses.contains(temp)) || remainingClasses.contains(temp)) {
                if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaUpdater: Existing class found in index.");
                jcls = temp;
                break;
            }
        }
        if (jcls != null) {
            // if the jcls exists test for the change of declaration type. E.g.
            // Used when user changes enum declaration to class and vice versa.
            int declType = jcls instanceof JavaEnum ? 1 : (jcls instanceof AnnotationType ? 2 : 0);
            if ((declType == 1 && !isEnum(modifiers)) || (declType != 1 && isEnum(modifiers)) ||
                (declType == 2 && !isAnnotation(modifiers)) || (declType != 2 && isAnnotation(modifiers)))
            {
                if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaUpdater: The found class is of wrong type: " + jcls.getClass().getName() + " -> deleting...");
                remainingClasses.remove(jcls);
                jcls.refDelete();
                jcls = null;
            }
        }

        if (jcls==null) {
            if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaUpdater: No suitable class found -> creating...");
            if (isEnum(modifiers)) {
                jcls = enumClass.create(fqn, modifiers, false);
            } else if (isAnnotation(modifiers)) {
                jcls = annTypeClass.create(fqn, modifiers, false);
            } else {
                jcls = jclsClass.create(fqn, modifiers, null, null, false);
            }
            // should not add the class to the index - it is already done in the create method
            //classIndex.addClass(jcls, fqn, simpleName);
        } else {
            if (removeFeatures) {
                boolean changes = ((JavaClassImpl) jcls).disableChanges;
                ((JavaClassImpl) jcls).disableChanges = true;
                try {
                    Collection fs = ((JavaClassImpl)jcls).getPersistentContents();
                    int size=fs.size();
                    ClassMember features[]=(ClassMember[])fs.toArray(new ClassMember[size]);

                    for (int i=0;i0) {
                name=pack+'.';
            } else {
                name="";
            }
        } else {
            name=((JavaClass)names.peek()).getName()+'.';
        }
        return name.concat(simpleName);
    }

    public Collection updateResources(Map javaFiles) 
    {
        JavaMetamodel.getDefaultRepository().beginTrans(false);
        try {
            Iterator resIt=javaFiles.values().iterator();
            List resList=new ArrayList();
            long indexTimestamp;

            indexTimestamp=classIndex.getTimestamp();
            while(resIt.hasNext()) {
                FileInfo file=(FileInfo)resIt.next();
                try {
                    String name=file.getPath();
                    long timestamp=file.lastModified();
                    ResourceImpl resource=(ResourceImpl) resourceClass.resolveResource(name,true,false);

                    resList.add(resource);
                    if (resource.getTimestamp()!=timestamp || indexTimestamp
... 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.