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-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.editor.java;

import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.awt.Toolkit;

import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.ext.java.JavaSyntaxSupport;
import org.netbeans.editor.ext.java.JCExpression;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;

import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.text.PositionBounds;


/**
* Support methods for syntax analyzes working with java JMI interfaces.
*
* @author Dusan Balek, Martin Roskanin
* @version 1.00
*/

public class NbJavaJMISyntaxSupport extends NbJavaSyntaxSupport {

    private JMIUtils jmiUtils;

    public JMIUtils getJMIUtils() {
        return jmiUtils;
    }

    public NbJavaJMISyntaxSupport(BaseDocument doc) {
        super(doc);
        setJava15(true);
        jmiUtils = JMIUtils.get(doc);
    }

    public JavaClass getJavaClass(int pos) {
        Feature f = getFeatureAtPos(pos);
        return f == null ? null : f instanceof JavaClass ? (JavaClass)f : (JavaClass)f.getDeclaringClass();
    }

    public boolean isStaticBlock(int pos) {
        Feature f = getFeatureAtPos(pos);
        return f != null ? (f.getModifiers() & Modifier.STATIC) != 0 : false;
    }

    protected int getMethodStartPosition(int pos) {
        Feature f = getFeatureAtPos(pos);
        return f != null ? JavaMetamodel.getManager().getElementPosition(f).getBegin().getOffset() : 0;
    }

    private Feature getFeatureAtPos(int pos) {
        Element element = getResource();
        boolean cont = (element != null);
        while (cont) {
            cont = false;
            for (Iterator it = element.getChildren().iterator(); it.hasNext();) {
                Element el = (Element) it.next();
                PositionBounds bounds = JavaMetamodel.getManager().getElementPosition(el);
                if (bounds.getBegin().getOffset() <= pos && bounds.getEnd().getOffset() >= pos) {
                    if (el instanceof JavaClass) {
                        element = el;
                        cont = true;
                    } else if (el instanceof Feature) {
                        return (Feature)el;
                    }
                    break;
                }
            }
        }
        return element instanceof Feature ? (Feature)element : null;
    }

    public Object findType(String varName, int varPos) {
        Object obj = super.findType(varName, varPos);
        if (!(obj instanceof JavaSyntaxSupport.JavaVariable))
            return obj;
        JCExpression typeExp = ((JavaSyntaxSupport.JavaVariable)obj).getTypeExpression();
        JCExpression varExp = ((JavaSyntaxSupport.JavaVariable)obj).getVariableExpression();
        Type type = getType(typeExp);
        if (type != null)
            type = processArrayDepth(type, getArrayDepth(varExp));
        return type;
    }

    public int findLocalDeclarationPosition(String varName, int varPos) {
        Object obj = super.findType(varName, varPos);
        if (!(obj instanceof JavaSyntaxSupport.JavaVariable))
            return super.findLocalDeclarationPosition(varName, varPos);
        else
            return getExpressionPos(((JavaSyntaxSupport.JavaVariable)obj).getTypeExpression());
    }

    public Collection getLocalVariableNames(String namePrefix, int pos, boolean exactMatch) {
        Map varMap = getLocalVariableMap(pos);
        if (varMap != null) {
            if (namePrefix != null && namePrefix.length() > 0) {
                return jmiUtils.filterNames(varMap.keySet(), namePrefix, exactMatch);
            } else if (!exactMatch) {
                return varMap.keySet();
            }
        }
        return Collections.EMPTY_LIST;
    }

    private int getExpressionPos(JCExpression exp) {
        return Math.min(exp.getTokenCount() > 0 ? exp.getTokenOffset(0) : Integer.MAX_VALUE, exp.getParameterCount() > 0 ? getExpressionPos(exp.getParameter(0)) : Integer.MAX_VALUE);
    }

    private int getArrayDepth(JCExpression exp) {
        return exp.getExpID() == JCExpression.ARRAY ? exp.getTokenCount() / 2 : 0;
    }

    private String getTypeName(JCExpression exp) {
        switch (exp.getExpID()) {
            case JCExpression.VARIABLE:
            case JCExpression.TYPE:
                return exp.getTokenText(0);

            case JCExpression.DOT:
                StringBuffer sb = new StringBuffer();
                for(int i = 0; i < exp.getParameterCount(); i++) {
                    sb.append(getTypeName(exp.getParameter(i)));
                    if (i < exp.getParameterCount() - 1)
                        sb.append('.'); // NOI18N
                }
                return sb.toString();

            case JCExpression.GENERIC_TYPE:
                return getTypeName(exp.getParameter(0));

            default:
                throw new IllegalStateException();
        }
    }

    private Type getType(JCExpression typeExp) {
        Type type = null;
        switch (typeExp.getExpID()) {
            case JCExpression.ARRAY:
                type = processArrayDepth(getType(typeExp.getParameter(0)), getArrayDepth(typeExp));
                break;

            case JCExpression.GENERIC_TYPE:
                type = getType(typeExp.getParameter(0));
                if (type instanceof JavaClass && ((JavaClass)type).getTypeParameters().size() > 0) {
                    List params = new ArrayList(typeExp.getParameterCount() - 1);
                    for (int i = 1; i < typeExp.getParameterCount(); i++)
                        params.add(getType(typeExp.getParameter(i)));
                    type = jmiUtils.resolveParameterizedType((JavaClass)type, params);
                }
                break;

            case JCExpression.DOT:
                type = getType(typeExp.getParameter(0));
                if (type != null && !(type instanceof UnresolvedClass)) {
                    int i = 1;
                    while(type instanceof ClassDefinition && i < typeExp.getParameterCount()) {
                        type = ((ClassDefinition)type).getInnerClass(getTypeName(typeExp.getParameter(i++)), true);
                        if (type instanceof JavaClass && ((JavaClass)type).getTypeParameters().size() > 0)
                            type = jmiUtils.resolveParameterizedType((JavaClass)type, null);
                    }
                    break;
                }
                type = jmiUtils.resolveType(getTypeName(typeExp)); // try FQN

            default:
                String typeName = getTypeName(typeExp);
                // Maybe it's an inner class or a type parameter. Stick an outerClass before it ...
                JavaClass outerCls = getJavaClass(typeExp.getTokenOffset(0));
                if (outerCls != null){
                    JavaClass innerClass = outerCls.getInnerClass(typeName, true); //NOI18N
                    if (innerClass != null){
                        type = innerClass;
                    } else {
                        for (Iterator it = outerCls.getTypeParameters().iterator(); it.hasNext();) {
                            TypeParameter tp = (TypeParameter) it.next();
                            if (tp.getName().equals(typeName)) {
                                type = tp;
                                break;
                            }
                        }
                    }
                }
                if (type == null) {
                    Feature f = getFeatureAtPos(typeExp.getTokenOffset(0));
                    if (f instanceof CallableFeature) {
                        for (Iterator it = ((CallableFeature)f).getTypeParameters().iterator(); it.hasNext();) {
                            TypeParameter tp = (TypeParameter) it.next();
                            if (tp.getName().equals(typeName)) {
                                type = tp;
                                break;
                            }
                        }
                    }
                }
                if (type == null){
                    type = getTypeFromName(typeName, true, outerCls);
                }
                if (type instanceof JavaClass && ((JavaClass)type).getTypeParameters().size() > 0)
                    type = jmiUtils.resolveParameterizedType((JavaClass)type, null);
                if (type == null)
                    type = jmiUtils.resolveType(typeName);
        }
        return type;
    }

    private Type processArrayDepth(Type typ, int arrayDepth) {
        while (arrayDepth > 0) {
            typ = jmiUtils.resolveArray(typ);
            arrayDepth--;
        }
        return typ;
    }


    public Type getTypeFromName(String name, boolean searchByName, JavaClass context) {

        // try to resolve as a primitive type or a FQN class
        Type ret = jmiUtils.resolveType(name);
        if (ret != null && !(ret instanceof UnresolvedClass))
            return ret;

        // try to resolve as an inner class
        JavaClass topClass = getTopJavaClass();
        if (topClass!=null){
            ret = topClass.getInnerClass(name, true);
            if (ret != null)
                return ret;
        }

        // check imports and package content
        JavaClass importedClass = jmiUtils.getImportedClass(name, topClass, context);
        if (importedClass != null) return importedClass;

        if (searchByName) {
            List clsList = jmiUtils.findClasses(null, name, true, context, false);
            if (clsList != null && clsList.size() > 0) {
                if (clsList.size() > 0) { // more matching classes
                    return (JavaClass)clsList.get(0); // return the first one
                }
            }
        }

        return null;
    }

    public Resource getResource() {
        DataObject dob = NbEditorUtilities.getDataObject(getDocument());
        return dob != null ? JavaMetamodel.getManager().getResource(dob.getPrimaryFile()) : null;
    }

    public JavaClass getTopJavaClass(Resource res) {
        if (res != null) {
            Iterator cls = res.getClassifiers().iterator();
            if (cls.hasNext())
                return (JavaClass)cls.next();
        }
        return null;
    }

    public JavaClass getTopJavaClass() {
        return getTopJavaClass(getResource());
    }

    protected Map buildGlobalVariableMap(int pos) {
        refreshClassInfo();
        JavaClass cls = getJavaClass(pos);
        if (cls != null) {
            HashMap varMap = new HashMap();
            List fldList = jmiUtils.findFields(cls, "", false, true, null, false, false, false, false); // NOI18N
            for (int i = fldList.size() - 1; i >= 0; i--) {
                Field fld = (Field)fldList.get(i);
                varMap.put(fld.getName(), fld.getType());
            }
            return varMap;
        }
        return null;
    }

    public Type getCommonType(Type typ1, Type typ2) {
        if (jmiUtils.isAssignable(typ1, typ2)) {
            return typ1;
        } else if (jmiUtils.isAssignable(typ2, typ1)) {
            return typ2;
        } else {
            return null;
        }
    }

    public List filterMethods(List methodList, List parmTypeList,
                              boolean acceptMoreParameters) {
        if (parmTypeList == null) {
            return methodList;
        }

        List ret = new ArrayList();
        int parmTypeCnt = parmTypeList.size();
        for (Iterator it = methodList.iterator(); it.hasNext();) {
            CallableFeature m = (CallableFeature) it.next();
            List methodParms = m.getParameters();
            int methodParmsCnt = methodParms.size();
            boolean isVarArg = methodParmsCnt > 0 ? ((Parameter)methodParms.get(methodParmsCnt - 1)).isVarArg() : false;
            if ((methodParmsCnt == parmTypeCnt && (!acceptMoreParameters || methodParmsCnt == 0))
            || (acceptMoreParameters && methodParmsCnt > parmTypeCnt)
            || (isVarArg && methodParmsCnt <= parmTypeCnt)
            ) {
                boolean accept = true;
                boolean bestMatch = !acceptMoreParameters;
                for (int i = 0; accept && i < parmTypeCnt; i++) {
                    Type mpt = ((Parameter)methodParms.get(i < methodParmsCnt ? i : methodParmsCnt - 1)).getType();
                    Type t = (Type)parmTypeList.get(i);
                    if (t != null) {
                        if (!jmiUtils.isEqualType(t, mpt)) {
                            bestMatch = false;
                            if (!jmiUtils.isAssignable(t, mpt)) {
                                if (acceptMoreParameters || !isVarArg || i != methodParmsCnt - 1 || methodParmsCnt != parmTypeCnt
                                || !(t instanceof Array) || !jmiUtils.isAssignable(((Array)t).getType(), mpt)) {
                                    accept = false;
                                    break;
                                }
                            }
                        }
                    } else { // type in list is null
                        bestMatch = false;
                    }
                }

                if (accept) {
                    if (bestMatch) {
                        ret.clear();
                    }
                    ret.add(m);
                    if (bestMatch) {
                        break;
                    }
                }

            }
        }
        return ret;
    }

    /** Returns true if the given class is in the import statement directly or
     *  indirectly (package.name.*) */
    public boolean isImported(JavaClass cls){
        JavaClass importedClass = jmiUtils.getImportedClass(cls.getSimpleName(), getTopJavaClass(), null);
        return (importedClass != null && importedClass.equals(cls));
    }

    /**
     * @return non-null [startOffset, endOffset] pair defining bounds
     *  of the import section.
     *  
* If there are no imports the bounds are * [Integer.MAX_VALUE, Integer.MIN_VALUE]. */ public int[] getImportSectionBounds() { Resource resource = getResource(); int startOffset = Integer.MAX_VALUE; int endOffset = Integer.MIN_VALUE; if (resource != null){ for (Iterator it = resource.getImports().iterator(); it.hasNext();) { Import imp = (Import)it.next(); startOffset = Math.min(startOffset, imp.getStartOffset()); endOffset = Math.max(endOffset, imp.getEndOffset()); } } return new int[] { startOffset, endOffset }; } public URL[] getJavaDocURLs(Object obj) { ArrayList urlList = new ArrayList(); if (obj instanceof NbJMIResultItem){ obj = ((NbJMIResultItem)obj).getAssociatedObject(); } if (obj instanceof JavaPackage) { JavaPackage pkg = (JavaPackage)obj; URL u = getDocFileObjects(pkg.getName(), PACKAGE_SUMMARY); if (u != null) { urlList.add(u); } } else if (obj instanceof JavaClass) { JavaClass cls = (JavaClass)obj; URL u = getDocFileObjects(cls.getName(), null); if (u != null) { urlList.add(u); } } else if (obj instanceof CallableFeature) { // covers JCMethod too CallableFeature ctr = (CallableFeature)obj; ClassDefinition cls = ctr.getDeclaringClass(); URL url = getDocFileObjects(cls.getName(), null); if (url != null) { StringBuffer sb = new StringBuffer("#"); // NOI18N sb.append(ctr.getName()); sb.append('('); List parms = ctr.getParameters(); int cntM1 = parms.size() - 1; for (int j = 0; j <= cntM1; j++) { String name = ((Parameter)parms.get(j)).getType().getName(); int idx = name.indexOf('<'); if (idx > -1) name = name.substring(0, idx); sb.append(name); if (j < cntM1) { sb.append(", "); // NOI18N } } sb.append(')'); try { urlList.add(new URL(url.toExternalForm() + sb)); } catch (MalformedURLException e) { ErrorManager.getDefault().log(ErrorManager.ERROR, e.toString()); } } } else if (obj instanceof Field) { Field fld = (Field)obj; ClassDefinition cls = fld.getDeclaringClass(); if (cls != null) { URL u = getDocFileObjects(cls.getName(), null); if (u != null) { try { urlList.add(new URL(u.toExternalForm() + '#' + fld.getName())); } catch (MalformedURLException e) { ErrorManager.getDefault().log(ErrorManager.ERROR, e.toString()); } } } } URL[] ret = new URL[urlList.size()]; urlList.toArray(ret); return ret; } private String getSourceName(JavaClass cls, boolean shortName) { return shortName ? cls.getSimpleName() : cls.getName(); } public String openSource(Object item, boolean findDeclaration, boolean simulate) { Element elem = null; Type typ = null; if (item instanceof JavaPackage) { if (!findDeclaration) { String pkgName = ((JavaPackage)item).getName(); if ( (pkgName==null) || (pkgName.length() <= 0) ) return null; if (!simulate) { FileObject fo = findResource(pkgName.replace('.', '/')); if (fo != null) { DataObject dob = getDataObject(fo); if (dob != null) { Node node = dob.getNodeDelegate(); if (node != null) { org.openide.nodes.NodeOperation.getDefault().explore(node); // explore the package return null; } } } } return pkgName; } } else if (item instanceof JavaClass) { elem = typ = (JavaClass)item; } else if (item instanceof Field) { if (findDeclaration) { elem = (Field)item; typ = ((Field)elem).getDeclaringClass(); } else { typ = ((Field)item).getType(); if (typ instanceof JavaClass) elem = JMIUtils.getSourceElementIfExists((JavaClass)typ); } } else if (item instanceof CallableFeature) { elem = (CallableFeature)item; typ = ((CallableFeature)item).getDeclaringClass(); } if (!simulate && elem != null) { if (JMIUtils.openElement(elem)) return null; } if (!simulate && elem == null && !(typ instanceof JavaClass)) Toolkit.getDefaultToolkit().beep(); return typ instanceof JavaClass ? getSourceName((JavaClass)typ, simulate) : null; } }
... 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.