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 org.netbeans.editor.SyntaxSupport;
import org.netbeans.editor.Utilities;
import org.netbeans.editor.ext.Completion;
import org.netbeans.editor.ext.CompletionJavaDoc;
import org.netbeans.editor.ext.ExtEditorUI;
import org.netbeans.editor.ext.JavaDocPane;
import org.netbeans.jmi.javamodel.*;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;

/**
 *  Support for javadoc in code completion working with java JMI interfaces
 *
 *  @author Martin Roskanin, Dusan Balek
 *  @since 04/2004
 */
class NbJMICompletionJavaDoc extends NbCompletionJavaDoc {

    private boolean goToSourceEnabled = false;    
    private String lastBase="";    
    private JavaDocPane pane;
    private JMIUtils jmiUtils;
    private NbJavaJMISyntaxSupport jmiSup;
    private Comparator contentComparator;
    private static String ARRAY_LENGTH_FIELD_JAVADOC =
        NbBundle.getBundle(NbJMICompletionJavaDoc.class).getString("array_length_field_javadoc"); //NOI18N

    private static String CLASS_CONSTANT_JAVADOC = 
        NbBundle.getBundle(NbJMICompletionJavaDoc.class).getString("class_constant_javadoc"); //NOI18N


    NbJMICompletionJavaDoc(ExtEditorUI extEditorUI) {
        super(extEditorUI);
    }

    private JMIUtils getJMIUtils() {
        if (jmiUtils == null)
            jmiUtils = JMIUtils.get(extEditorUI.getDocument());
        return jmiUtils;
    }

    private NbJavaJMISyntaxSupport getJMISyntaxSupport() {
        if (jmiSup == null) {
            SyntaxSupport sup = Utilities.getSyntaxSupport(extEditorUI.getComponent());
            jmiSup = (NbJavaJMISyntaxSupport)sup.get(NbJavaJMISyntaxSupport.class);
        }
        return jmiSup;
    }

    protected Object getCurrentContent() {
        return convert(super.getCurrentContent());
    }

    protected Comparator getContentComparator() {
        if (contentComparator == null)
            contentComparator = new ContentComparator();
        return contentComparator;
    }

    protected String findProperClass(String name, String pkgName) {
        JavaClass jc = getJMIUtils().getExactClass(name, pkgName);
        return jc != null ? jc.getName() : null;
    }

    protected ParsingThread setInRequestProcessorThread(final Object content){
        JMIParsingThread pt = new JMIParsingThread(content);
        RequestProcessor.getDefault().post(pt);
        return pt;
    }

    /** Returns true if javadoc is mounted in FS */
    public boolean isExternalJavaDocMounted(){
        Object currentContent = getCurrentContent();
        if (currentContent instanceof URL || currentContent instanceof String){
            try{
                FileObject fo = URLMapper.findFileObject(new URL(lastBase));
                if (fo != null) return true;
            }catch(MalformedURLException mue){
                mue.printStackTrace();
                return false;
            }
        }
        URL urls[] = getJMISyntaxSupport().getJavaDocURLs(currentContent);
        return (urls == null || urls.length < 1) ? false : true;
    }
    
    /** Opens source of current javadoc in editor */
    public void goToSource(){
        Object currentContent = getCurrentContent();
        if (getJMISyntaxSupport().openSource(currentContent, true, false) == null){
            extEditorUI.getCompletion().setPaneVisible(false);
        }
    }

    /** Returns JavaDoc popup pane */
    public JavaDocPane getJavaDocPane(){
        Completion completion = extEditorUI.getCompletion();
        if (completion != null){
            JavaDocPane jdp = completion.getJDCPopupPanel().getJavaDocPane();
            if (jdp instanceof NbJMIScrollJavaDocPane)return jdp;
        }
        
        if (pane == null){
            pane = new NbJMIScrollJavaDocPane(extEditorUI);
        }
        return pane;
     }

    private CompletionJavaDoc.JavaDocTagItem[] getJavaDocTags(List jdt){
        CompletionJavaDoc.JavaDocTagItem ret [] = new CompletionJavaDoc.JavaDocTagItem[jdt.size()];
        int i = 0;
        for (Iterator it = jdt.iterator(); it.hasNext(); i++) {
            TagValue tv = (TagValue) it.next();
            ret[i] = new JavaDocTagItemImpl(tv.getDefinition().getName(), tv.getValue());
        }
        return ret;
    }

    protected boolean isGoToSourceEnabled(){
        return goToSourceEnabled;
    }
    
    /** Opens javadoc in external browser */
    public void openInExternalBrowser(){
        Object currentContent = getCurrentContent();

        if (currentContent instanceof URL){
            org.openide.awt.HtmlBrowser.URLDisplayer.getDefault().showURL((URL)currentContent);
        }else if (currentContent instanceof String){
            URL url = mergeRelLink(lastBase,(String)currentContent);
            org.openide.awt.HtmlBrowser.URLDisplayer.getDefault().showURL(url);
        }
        
        URL[] urls = getJMISyntaxSupport().getJavaDocURLs(currentContent);

        if (urls != null && urls.length > 0) {
            org.openide.awt.HtmlBrowser.URLDisplayer.getDefault().showURL(urls[0]); // show first URL
        }
    }
    
    private List parseMethodTypes(String parameters, JavaClass cls){
        ArrayList ret = new ArrayList();
        if (parameters == null) return ret;
        StringTokenizer st = new StringTokenizer(parameters, ","); //NOI18N
        while (st.hasMoreTokens()) {
            String param = st.nextToken();
            param.trim();
            param = (param.indexOf(" ") > 0) ? param.substring(0, param.indexOf(" ")) : param; //NOI18N
            int arrDepth = 0;
            Type typ = null;
            if (param.indexOf("[") > 0) { // NOI18N
                int idx = param.indexOf("["); // NOI18N
                param = param.substring(0, idx); //NOI18N
                while (idx >= 0) {
                    arrDepth++;
                    idx = param.indexOf("[", idx); // NOI18N
                }
            }
            if (param.indexOf(".") < 0) { // NOI18N
                typ = getJMISyntaxSupport().getTypeFromName(param, true, cls);
            } else {
                typ = getJMIUtils().getExactClass(param);
                if (typ == null)
                    typ = getJMIUtils().getExactClass(param, getJMIUtils().getPackageName(cls));
            }
            if (typ != null) {
                while (arrDepth > 0) {
                    typ = getJMIUtils().resolveArray(typ);
                    arrDepth--;
                }
            }
            ret.add(typ);
        }

        return ret;
    }

    public Object parseLink(String link, String clsFQN, String pkgName) {
        return parseLink(link, getJMIUtils().getExactClass(clsFQN));
    }

    public Object parseLink(String link, JavaClass cls) {
        link = link.trim();
        JavaClass linkClass = null;

        getJMIUtils().beginTrans(false);
        try {
            if (link.indexOf("#") > -1 ) { //NOI18N
                if (link.startsWith("#")) { //NOI18N
                    /* Referencing a member of the current class i.e:
                     * @see  #field
                     * @see  #method(Type, Type,...)
                     * @see  #method(Type argname, Type argname,...)
                     */
                    if (cls == null)
                        return null;
                    linkClass = cls;
                } else {
                    /* Referencing another class in the current or imported packages
                     * @see  Class#field
                     * @see  Class#method(Type, Type,...)
                     * @see  Class#method(Type argname, Type argname,...)
                     * @see  package.Class#field
                     * @see  package.Class#method(Type, Type,...)
                     * @see  package.Class#method(Type argname, Type argname,...)
                     */
                    String refCls = link.substring(0, link.indexOf("#")); //NOI18N
                    if (refCls.indexOf(".") < 0){ // NOI18N
                        Type typ = getJMISyntaxSupport().getTypeFromName(refCls, true, cls);
                        if (typ instanceof JavaClass)
                            linkClass = (JavaClass)typ;
                    } else {
                        linkClass = getJMIUtils().getExactClass(refCls);
                        if (linkClass == null)
                            linkClass = getJMIUtils().getExactClass(refCls, getJMIUtils().getPackageName(cls));
                    }
                    if (linkClass == null)
                        return null;
                }

                String memberLink = link.substring(link.indexOf("#")+1) ;  //NOI18N
                if (link.indexOf("(")>0){ //NOI18N
                //method or constructor
                    String memberName = memberLink.substring(0,memberLink.indexOf("(")); //NOI18N
                    String memberParams = null;
                    if (link.indexOf(")")>0){ //NOI18N
                        memberParams = link.substring(link.indexOf("(")+1,link.indexOf(")"));  //NOI18N
                    }
                    List params = parseMethodTypes(memberParams, cls);
                    if (memberName.equals(linkClass.getSimpleName()))
                        return linkClass.getConstructor(params, true);
                    else
                        return linkClass.getMethod(memberName, params, true);
                } else {
                //field or method or constructor
                    String memberName = (memberLink.indexOf(" ")>0) ? memberLink.substring(0,memberLink.indexOf(" ")) : memberLink; //NOI18N

                    // look for fields first. If it will be the method with the same name it should be named with ()
                    Field fld = linkClass.getField(memberName, true);
                    if (fld != null)
                        return fld;

                    // Now try to find a method or constructor
                    Feature feature;
                    if (memberName.equals(linkClass.getSimpleName()))
                        feature = linkClass.getConstructor(Collections.EMPTY_LIST, true);
                    else
                        feature = linkClass.getMethod(memberName, Collections.EMPTY_LIST, true);
                    if (feature == null){
                        // it could be method with some parameter
                        Iterator it = getJMIUtils().findFeatures(linkClass, memberName, true, false, cls, false, false, null, false, false).iterator();
                        if (it.hasNext())
                            feature = (Feature)it.next();
                    }
                    return feature;
                }
            } else {
                /* no member available, it can be package or class i.e:
                 * @see  Class
                 * @see  package.Class
                 * @see  package
                 */
                String refCls = (link.indexOf(" ")>0) ? link.substring(0, link.indexOf(" ")) : link; //NOI18N
                if (refCls.indexOf(".") < 0){ // NOI18N
                    Type typ = getJMISyntaxSupport().getTypeFromName(refCls, true, cls);
                    if (typ instanceof JavaClass)
                        linkClass = (JavaClass)typ;
                } else {
                    linkClass = getJMIUtils().getExactClass(refCls);
                    if (linkClass == null)
                        linkClass = getJMIUtils().getExactClass(refCls, getJMIUtils().getPackageName(cls));
                }
                return linkClass;
            }
        } finally {
            getJMIUtils().endTrans(false);
        }
    }
    
     /** Prepares raw javadoc content with given javadoc parameters
     *  @param cls root class
     *  @param member String representation of field or method
     *  @param content raw javadoc content text
     *  @param tags javadoc tag items array
     */
    public String prepareJavaDocContent(ClassDefinition cls, String member, String content, CompletionJavaDoc.JavaDocTagItem tags[]){
        JMIUtils jmiUtils = getJMIUtils();
        String pkgName = jmiUtils.getPackageName(cls);
        return prepareJavaDocContent(cls.getName(), pkgName, member, content, tags);
    }

    private Object convert(Object content) {
        if ((content instanceof NbJMIResultItem)){
            Object obj = ((NbJMIResultItem)content).getAssociatedObject();
            if (obj!=null){
                content = obj;
            }
        }
        getJMIUtils().beginTrans(false);
        try {
            if (content instanceof Feature)
                content = JMIUtils.getDefintion((Feature)content);
            if (content instanceof ClassDefinition)
                content = JMIUtils.getSourceElementIfExists((ClassDefinition)content);
            return content;
        } finally {
            getJMIUtils().endTrans(false);
        }
    }

    private class ContentComparator implements Comparator {
        public int compare(Object o1, Object o2) {
            Object obj1 = convert(o1);
            Object obj2 = convert(o2);
            return obj1 != null && obj1.equals(obj2) ? 0 : 1;
        }
    }


    class JMIParsingThread extends ParsingThread {
        
        Object content;
        boolean running = true;
        
        public JMIParsingThread(Object content){
            super(content);
            this.content = content;
        }
        
        private String wrapClass(JavaClass clazz) {
            if (clazz==null || clazz.getName().length()==0) return "";
            URL[] urls = getJMISyntaxSupport().getJavaDocURLs(clazz);
            if (urls.length > 0 && urls[0]!=null){
                return ""+clazz.getName()+""; // NOI18N
            }
            return "";
        }
        
        /** Retireves class from javadoc URL and wraps it to the anchor tag format */
        private  String wrapClass(String url){
            if (url==null) return "";
            String parent = url;
            int hashIndex = parent.lastIndexOf("#"); //NOI18N
            if (hashIndex>0){
                parent = parent.substring(0, hashIndex);
            }
            
            StringBuffer sb  = new StringBuffer(url);
            int htmlIndex = sb.indexOf(".html"); //NOI18N
            if (htmlIndex>0){
                sb.delete(htmlIndex, sb.length());
            }
            
            for (int i=0; i"+subStr+""; //NOI18N
                    }
                }
            }
            return "";
        }
        
        private boolean tryMountedJavaDoc(URL url){
            if (url==null){
                URL[] urls = getJMISyntaxSupport().getJavaDocURLs(content);
                if (urls.length > 0 && urls[0]!=null){
                    url = urls[0];
                }else{
                    return false;
                }
            }
            String urlStr = url.toString();

            ClassDefinition clazz = null;
            if (content instanceof JavaClass) {
                clazz = (JavaClass)content;
            } else if (content instanceof CallableFeature || content instanceof Field){
                clazz = ((Feature)content).getDeclaringClass();
            }
            String clazzInfo = clazz instanceof JavaClass ? wrapClass((JavaClass)clazz) : wrapClass(urlStr);

            String textFromURL = HTMLJavadocParser.getJavadocText(url, content instanceof JavaPackage);

            if (textFromURL!=null && textFromURL.length()>0){
                if (!textFromURL.toUpperCase().startsWith("
") && //NOI18N (!textFromURL.toUpperCase().startsWith("
"))) //NOI18N
                    clazzInfo += "
"; //NOI18N String retrievedText = clazzInfo + textFromURL; lastBase = getLastBase(urlStr); goToSourceEnabled = false; showJavaDoc(retrievedText); return true; } return false; } private void setClass(JavaClass cls){ if (cls == null) { if (tryMountedJavaDoc(null)) return; goToSourceEnabled = false; javaDocNotFound(); return; } JavaDoc jd = cls.getJavadoc(); boolean notFound = jd == null || (jd.getText().length() == 0 && jd.getTags().size() == 0); String preparedText = prepareJavaDocContent(cls,"", //NOI18N notFound ? CONTENT_NOT_FOUND : jd.getText(), notFound ? null : getJavaDocTags(jd.getTags())); if (notFound){ if (tryMountedJavaDoc(null)) return; javaDocNotFound(); return; } showJavaDoc(preparedText); } private void setFeature(Feature feature, String displayText){ if (feature == null) { if (tryMountedJavaDoc(null)) return; goToSourceEnabled = false; javaDocNotFound(); return; } if (feature instanceof org.netbeans.modules.javacore.jmiimpl.javamodel.ArrayLengthField){ showJavaDoc(ARRAY_LENGTH_FIELD_JAVADOC); return; } JavaDoc jd = feature.getJavadoc(); boolean notFound = jd == null || (jd.getText().length() == 0 && jd.getTags().size() == 0); String preparedText = prepareJavaDocContent(feature.getDeclaringClass(), getBoldName(displayText, feature instanceof Constructor ? getTypeName(((Constructor)feature).getType()) : feature.getName()), (notFound) ? CONTENT_NOT_FOUND : jd.getText(), (notFound) ? null : getJavaDocTags(jd.getTags())); if (notFound){ if (tryMountedJavaDoc(null)) return; javaDocNotFound(); return; } showJavaDoc(preparedText); } private String getTypeName(Type typ) { String typeName = NbJMIResultItem.getTypeName(typ); typeName = typeName.replaceAll("<", "<"); // NOI18N return typeName.replaceAll(">", ">"); // NOI18N } private String getFieldHeader(Field f){ StringBuffer sb = new StringBuffer(); sb.append(Modifier.toString(f.getModifiers())); sb.append(" "); // NOI18N sb.append(getTypeName(f.getType())); sb.append(" "); //NOI18N sb.append(f.getName()); sb.append(""); //NOI18N return sb.toString(); } private String getCallableFeatureHeader(CallableFeature cf){ StringBuffer sb = new StringBuffer(); sb.append(Modifier.toString(cf.getModifiers())); sb.append(" "); // NOI18N if (cf instanceof Constructor){ sb.append(""); //NOI18N sb.append(getTypeName(cf.getType())); } else { sb.append(getTypeName(cf.getType())); sb.append(" "); //NOI18N sb.append(cf.getName()); } sb.append("("); //NOI18N List params = cf.getParameters(); for (Iterator it = params.iterator(); it.hasNext();) { Parameter param = (Parameter) it.next(); sb.append(getTypeName(param.getType())); if (param.isVarArg()) sb.append("..."); // NOI18N String paramName = param.getName(); if (paramName != null && paramName.length() > 0) sb.append(" "); // NOI18N sb.append(paramName); if (it.hasNext()) sb.append(", "); //NOI18N } sb.append(")"); //NOI18N List excs = cf.getExceptions(); Iterator it = excs.iterator(); if (it.hasNext()) sb.append(" throws ");//NOI18N while (it.hasNext()) { JavaClass exc = (JavaClass) it.next(); sb.append(getTypeName(exc)); if (it.hasNext()) sb.append(", "); //NOI18N } return sb.toString(); } public void run() { getJMIUtils().beginTrans(false); try { goToSourceEnabled = true; if(content instanceof JavaClass) { setClass((JavaClass)content); } else if(content instanceof Field) { setFeature((Field)content, getFieldHeader((Field)content)); } else if(content instanceof CallableFeature){ setFeature((CallableFeature)content, getCallableFeatureHeader((CallableFeature)content)); } else if (content instanceof URL){ if (!tryMountedJavaDoc((URL)content)){ goToSourceEnabled = false; javaDocNotFound(); } if (addToHistory) addToHistory(content); } else if (content instanceof String){ goToSourceEnabled = false; String strCon = (String) content; URL url = mergeRelLink(lastBase, strCon); if (url == null) return; if (addToHistory) addToHistory(url); if (!tryMountedJavaDoc(url)) javaDocNotFound(); } else if (content instanceof NbJMIResultItem.VarResultItem){ NbJMIResultItem.VarResultItem varItem = (NbJMIResultItem.VarResultItem)content; String itemText = varItem.getItemText(); Type varType = varItem.getType(); if ("class".equals(itemText) && varType!=null && "java.lang.Class".equals(varType.getName())){ //NOI18N showJavaDoc(CLASS_CONSTANT_JAVADOC); return; } } else{ goToSourceEnabled = false; if (!tryMountedJavaDoc(null)) javaDocNotFound(); } } finally { getJMIUtils().endTrans(false); } } } }
... 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.