|
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.awt.event.ActionEvent;
import java.lang.IllegalArgumentException;
import java.net.MalformedURLException;
import org.openide.src.JavaDoc;
import org.openide.src.ClassElement;
import org.openide.util.RequestProcessor;
import org.openide.src.Identifier;
import org.openide.src.FieldElement;
import org.openide.src.Type;
import org.openide.src.MethodElement;
import org.openide.src.ConstructorElement;
import org.openide.src.JavaDocTag;
import org.netbeans.editor.ext.CompletionJavaDoc;
import org.netbeans.editor.ext.ExtEditorUI;
import org.netbeans.editor.ext.java.JCField;
import org.netbeans.editor.ext.java.JCMethod;
import org.netbeans.editor.ext.java.JCClass;
import org.netbeans.editor.ext.java.JCParameter;
import org.netbeans.editor.ext.java.JCConstructor;
import java.net.URL;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.swing.text.Document;
import org.netbeans.editor.ext.java.JCFinder;
import org.netbeans.editor.BaseDocument;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.editor.Utilities;
import org.netbeans.editor.SyntaxSupport;
import org.netbeans.editor.ext.JavaDocPane;
import org.netbeans.editor.ext.java.JCPackage;
import org.netbeans.editor.ext.java.JavaCompletionJavaDoc;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
import org.openide.loaders.DataObject;
import org.openide.util.NbBundle;
/**
*
* @author Martin Roskanin
* @since 03/2002
*/
public class NbCompletionJavaDoc extends JavaCompletionJavaDoc{
ParsingThread task = null;
public static final String CONTENT_NOT_FOUND = NbBundle.getMessage(NbCompletionJavaDoc.class, "javadoc_content_not_found"); //NOI18N
private static boolean javaSourcesMounted = true;
private static boolean inited = false;
private String lastBase="";
private boolean goToSourceEnabled = false;
/** Creates a new instance of NbCompletionJavaDoc */
public NbCompletionJavaDoc(ExtEditorUI extEditorUI) {
super(extEditorUI);
}
protected JCFinder getFinder() {
Document doc = Utilities.getDocument(extEditorUI.getComponent());
assert doc != null;
DataObject dobj = NbEditorUtilities.getDataObject(doc);
assert dobj != null;
FileObject fo = dobj.getPrimaryFile();
return JCFinderFactory.getDefault().getFinder(fo);
}
protected CompletionJavaDoc.JavaDocTagItem[] getJavaDocTags(JavaDocTag jdt[]){
CompletionJavaDoc.JavaDocTagItem ret [] = new CompletionJavaDoc.JavaDocTagItem[jdt.length];
for (int i=0; i 0) {
org.openide.awt.HtmlBrowser.URLDisplayer.getDefault().showURL(urls[0]); // show first URL
}
}
protected String findProperClass(String name, String pkgName){
if (name==null) return null;
String ret = null;
if (pkgName!=null && pkgName.length()>0){
if (getClassElement(pkgName+"."+name) != null){ //NOI18N
return pkgName+"."+name; //NOI18N
}
}else{
if (getClassElement(name) != null){
return name;
}
}
List classes = getFinder().findClasses(null, name, true);
if (classes.size()>0){
ret = ((JCClass)classes.get(0)).getFullName();
// found in Code Completion DB, but it is not mounted
if (getClassElement(ret) == null) ret = null;
}
return ret;
}
protected boolean isNotFullyQualifiedInnerClass (String inner, String pkgName){
if (inner.indexOf(".") != inner.lastIndexOf(".")){ //NOI18N
// fully qualified
return false;
}
return (getClassElement((pkgName.length()>0) ? (pkgName+"."+inner) : inner) != null); //NOI18N
}
protected List parseMethodTypes(String parameters){
ArrayList ret = new ArrayList();
if (parameters == null) return ret;
StringTokenizer st = new StringTokenizer(parameters,","); //NOI18N
while (st.hasMoreTokens()) {
String param = st.nextToken();
param.trim();
if (param.indexOf(".") < 0){ // NOI18N
//it could be i.e String without java.lang package
String testParam = "java.lang."+param; //NOI18N
if (testParam.indexOf("[")>0){ //NOI18N
// if param is an array
testParam = testParam.substring(0,testParam.indexOf("[")); // NOI18N
}
ClassElement ce = getClassElement(testParam); //NOI18N
if (ce!=null){
param = "java.lang."+param; //NOI18N
}
}
ret.add(param);
}
return ret;
}
/** Returns true if javadoc is mounted in FS */
public boolean isExternalJavaDocMounted(){
SyntaxSupport sup = Utilities.getSyntaxSupport(extEditorUI.getComponent());
NbJavaSyntaxSupport nbJavaSup = (NbJavaSyntaxSupport)sup.get(NbJavaSyntaxSupport.class);
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[] = nbJavaSup.getJavaDocURLs(currentContent);
return (urls == null || urls.length < 1) ? false : true;
}
/** Parses given link such as java.awt.Component#addHierarchyListener
* and returns parsed Object
* @return Object of JCClass, JCMethod, JCConstructor or JCField
*/
public Object parseLink(String link, String clsFQN, String pkgName){
if (pkgName == null) pkgName = "";//NOI18N
link = link.trim();
ClassElement linkClsElem;
Object linkMember;
JCClass linkClass;
JCFinder finder = getFinder();
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,...)
*/
linkClsElem = getClassElement(clsFQN);
if (linkClsElem == null) return null;
linkClass = finder.getExactClass(clsFQN);
if (linkClass == null) return null;
}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
// it can be class in current package
String curPkgCls = (pkgName.length()>0) ? pkgName+"."+refCls : refCls; //NOI18N
if (getClassElement(curPkgCls) == null){
// try to find a class via finder
List outCls = finder.findClasses(null, refCls, true);
if (outCls.size() > 0){
refCls = ((JCClass) outCls.get(0)).getFullName();
}
}else{
refCls = curPkgCls;
}
}
linkClsElem = getClassElement(refCls);
if (linkClsElem == null) return null;
linkClass = finder.getExactClass(linkClsElem.getName().getFullName());
if (linkClass == null) return null;
}
if (link.indexOf("(")>0){ //NOI18N
//method or constructor
String memberLink = link.substring(link.indexOf("#")+1) ; //NOI18N
String memberFullName = (memberLink.indexOf(" ")>0) ? memberLink.substring(0,memberLink.indexOf(" ")) : memberLink; //NOI18N
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);
Type types[] = new Type[params.size()];
try{
for (int i=0; i0) ? 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 ()
FieldElement fieldElement = linkClsElem.getField(Identifier.create(memberName));
if (fieldElement !=null){
JCField flds[] = linkClass.getFields();
for (int i = 0; i0) ? link.substring(0, link.indexOf(" ")) : link; //NOI18N
if (refCls.indexOf(".") > 0){ //NOI18N
// fully qualified name or inner class
linkClsElem = getClassElement(refCls);
if (linkClsElem == null) {
refCls = findProperClass(refCls, pkgName);
}
}else{
// class in current package
refCls = findProperClass(refCls, pkgName);
}
linkClsElem = getClassElement(refCls);
if (linkClsElem == null) return null;
linkClass = finder.getExactClass(linkClsElem.getName().getFullName());
return linkClass;
}
}
protected URL mergeRelLink(String base, String rel){
try{
return new URL(new URL(base),rel);
}catch(MalformedURLException mue){
mue.printStackTrace();
}
return null;
}
class ParsingThread implements Runnable{
Object content;
boolean running = true;
public ParsingThread(Object content){
this.content = content;
}
void stopTask(){
running = false;
}
protected String getBoldName(String description, String name){
if (description.indexOf(name) > -1){
StringBuffer sb = new StringBuffer();
sb.append(description.substring(0, description.indexOf(name)));
sb.append(""+name+""); //NOI18N
sb.append(description.substring(description.indexOf(name)+name.length()));
return sb.toString().replace('$', '.'); //NOI18N
}
return description;
}
/** Wraps the given JCClass to anchor tag with appropriate href */
private String wrapClass(JCClass clazz){
if (clazz==null || clazz.toString().length()==0) return "";
String ret = clazz.toString();
SyntaxSupport sup = Utilities.getSyntaxSupport(extEditorUI.getComponent());
NbJavaSyntaxSupport nbJavaSup = (NbJavaSyntaxSupport)sup.get(NbJavaSyntaxSupport.class);
if (nbJavaSup==null) return ret;
URL[] urls = nbJavaSup.getJavaDocURLs(clazz);
if (urls.length > 0 && urls[0]!=null){
ret = ""+clazz.toString()+""; //NOI18N
}
return ret;
}
/** Retireves class from javadoc URL and wraps it to the anchor tag format */
private String wrapClass(String url){
if (url==null) return ""; //NOI18N
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 ret;
}
}
}
return "";
}
private boolean tryMountedJavaDoc(URL url){
if (url!=null && !"nbfs".equals(url.getProtocol())){ //NOI18N
// ignore non-NBFS protocol URLs
return false;
}
String clazzInfo = "";
if (content instanceof JCMethod){
JCClass clazz = ((JCMethod)content).getClazz();
if (clazz!=null) clazzInfo = wrapClass(clazz);
} else if (content instanceof JCField){
JCClass clazz = ((JCField)content).getClazz();
if (clazz!=null) clazzInfo = wrapClass(clazz);
} else if (content instanceof JCConstructor){
JCClass clazz = ((JCConstructor)content).getClazz();
if (clazz!=null) clazzInfo = wrapClass(clazz);
}
SyntaxSupport sup = Utilities.getSyntaxSupport(extEditorUI.getComponent());
NbJavaSyntaxSupport nbJavaSup = (NbJavaSyntaxSupport)sup.get(NbJavaSyntaxSupport.class);
if (url==null){
URL[] urls = nbJavaSup.getJavaDocURLs(content);
if (urls.length > 0 && urls[0]!=null){
url = urls[0];
}else{
return false;
}
}
String urlStr = url.toString();
if (clazzInfo.length() == 0){
clazzInfo = wrapClass(urlStr);
}
String textFromURL = HTMLJavadocParser.getJavadocText(url, content instanceof JCPackage);
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;
}
protected String getLastBase(String urlStr){
if (urlStr==null) return null;
return urlStr.substring(0,urlStr.lastIndexOf('/')+1);
}
protected void javaDocNotFound(){
if (alwaysDisplayPopup()) showJavaDoc(CONTENT_NOT_FOUND);
}
protected void showJavaDoc(final String preparedText){
if (running){
Runnable r = new Runnable() {
public void run() {
getJavaDocView().setContent(preparedText);
setGoToSourceEnabled(isGoToSourceEnabled());
if (running){
setJavaDocVisible(true);
}
}
};
Utilities.runInEventDispatchThread(r);
}
}
private void setMethod(MethodElement me, JCMethod jcMethod){
if (me == null || jcMethod == null){
if (tryMountedJavaDoc(null)) return;
goToSourceEnabled = false;
javaDocNotFound();
return;
}
JavaDoc.Method jdMethod = me.getJavaDoc();
boolean notFound = jdMethod == null || (jdMethod.getText().length() == 0 && jdMethod.getTags().length == 0);
String preparedText = prepareJavaDocContent(jcMethod.getClazz(),
getBoldName(jcMethod.toString(), jcMethod.getName()),
(notFound) ? CONTENT_NOT_FOUND : jdMethod.getText(),
(jdMethod == null) ? null : getJavaDocTags(jdMethod.getTags()));
if (notFound){
if (tryMountedJavaDoc(null)) return;
javaDocNotFound();
return;
}
showJavaDoc(preparedText);
}
private void setClass(ClassElement ce, JCClass cls){
if (ce == null) {
if (tryMountedJavaDoc(null)) return;
goToSourceEnabled = false;
javaDocNotFound();
return;
}
JavaDoc.Class jdClass = ce.getJavaDoc();
boolean notFound = jdClass == null || (jdClass.getText().length() == 0 && jdClass.getTags().length == 0);
String preparedText = prepareJavaDocContent(cls,"", //NOI18N
notFound ? CONTENT_NOT_FOUND : jdClass.getText(),
(jdClass == null) ? null : getJavaDocTags(jdClass.getTags()));
if (notFound){
if (tryMountedJavaDoc(null)) return;
javaDocNotFound();
return;
}
showJavaDoc(preparedText);
}
private void setField(FieldElement fe, JCField jcField){
if (fe == null || jcField == null) {
if (tryMountedJavaDoc(null)) return;
goToSourceEnabled = false;
javaDocNotFound();
return;
}
JavaDoc.Field jdField = fe.getJavaDoc();
boolean notFound = jdField == null || (jdField.getText().length() == 0 && jdField.getTags().length == 0);
String preparedText = prepareJavaDocContent(jcField.getClazz(),
getBoldName(jcField.toString(), jcField.getName()),
notFound ? CONTENT_NOT_FOUND : jdField.getText(),
(jdField == null) ? null : getJavaDocTags(jdField.getTags()));
if (notFound){
if (tryMountedJavaDoc(null)) return;
javaDocNotFound();
return;
}
showJavaDoc(preparedText);
}
private void setConstructor(ConstructorElement conElem, JCConstructor jcConstuctor){
if (conElem == null || jcConstuctor == null) {
if (tryMountedJavaDoc(null)) return;
goToSourceEnabled = false;
javaDocNotFound();
return;
}
JavaDoc.Method jdMethod = conElem.getJavaDoc();
boolean notFound = jdMethod == null || ( jdMethod.getText().length() == 0 && jdMethod.getTags().length == 0 );
String preparedText = prepareJavaDocContent(jcConstuctor.getClazz(),
getBoldName(jcConstuctor.toString(), jcConstuctor.getClazz().getName()),
notFound ? CONTENT_NOT_FOUND : jdMethod.getText(),
(jdMethod == null) ? null : getJavaDocTags(jdMethod.getTags()));
if (notFound){
if (tryMountedJavaDoc(null)) return;
javaDocNotFound();
return;
}
showJavaDoc(preparedText);
}
public void run(){
goToSourceEnabled = true;
if (content instanceof JCClass){
setClass(getClassElement(((JCClass)content).getFullName()), ((JCClass)content));
}else if(content instanceof JCField){
JCField fld = (JCField)content;
ClassElement ce = getClassElement(fld.getClazz().getFullName());
if (ce == null){
goToSourceEnabled = false;
if (!tryMountedJavaDoc(null)) javaDocNotFound();
return;
}
setField(ce.getField(Identifier.create(((JCField)content).getName())), fld);
}else if(content instanceof JCMethod){
JCMethod mtd = (JCMethod)content;
ClassElement ce = getClassElement(mtd.getClazz().getFullName());
if (ce == null) {
goToSourceEnabled = false;
if (!tryMountedJavaDoc(null)) javaDocNotFound();
return;
}
JCParameter jcp [] = mtd.getParameters();
try{
Type types[] = new Type[jcp.length];
for (int i=0; i
|