org.netbeans.modules.java.classfile.AttachSourcePanel Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.java.classfile;
import com.sun.source.util.TreePath;
import java.net.URL;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import javax.lang.model.element.Element;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import org.netbeans.api.actions.Openable;
import org.netbeans.api.annotations.common.CheckForNull;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.api.editor.document.EditorDocumentUtils;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.queries.SourceForBinaryQuery;
import org.netbeans.api.java.queries.SourceJavadocAttacher;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.api.java.source.ElementHandle;
import org.netbeans.api.java.source.JavaSource.Phase;
import org.netbeans.api.java.source.UiUtils;
import org.netbeans.api.progress.BaseProgressUtils;
import org.netbeans.modules.parsing.api.ParserManager;
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.parsing.api.Source;
import org.netbeans.modules.parsing.api.UserTask;
import org.netbeans.modules.parsing.spi.ParseException;
import org.netbeans.modules.parsing.spi.Parser;
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
import org.openide.cookies.EditorCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
public class AttachSourcePanel extends javax.swing.JPanel {
private static final RequestProcessor RP = new RequestProcessor(AttachSourcePanel.class);
private final URL root;
private final URL file;
private final String binaryName;
private final String sourceFile;
public AttachSourcePanel(
@NonNull final URL root,
@NonNull final URL file,
@NonNull final String binaryName,
@NonNull final String sourceFile
) {
assert root != null;
assert file != null;
assert binaryName != null;
this.root = root;
this.file = file;
this.binaryName = binaryName;
this.sourceFile = sourceFile;
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// //GEN-BEGIN:initComponents
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
jLabel1.setText(org.openide.util.NbBundle.getMessage(AttachSourcePanel.class, "AttachSourcePanel.jLabel1.text", sourceFile));
jButton1.setText(org.openide.util.NbBundle.getMessage(AttachSourcePanel.class, "AttachSourcePanel.jButton1.text")); // NOI18N
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
attachSources(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 608, Short.MAX_VALUE)
.addGap(22, 22, 22)
.addComponent(jButton1)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
);
}// //GEN-END:initComponents
private void attachSources(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_attachSources
jButton1.setEnabled(false);
RP.execute(new Runnable() {
@Override
public void run() {
SourceJavadocAttacher.attachSources(
root,
new SourceJavadocAttacher.AttachmentListener() {
@Override
public void attachmentSucceeded() {
boolean success = false;
final FileObject rootFo = URLMapper.findFileObject(root);
final FileObject fileFo = URLMapper.findFileObject(file);
if (rootFo != null && fileFo != null) {
final FileObject[] fos = SourceForBinaryQuery.findSourceRoots(root).getRoots();
if (fos.length > 0) {
final ClassPath cp = ClassPathSupport.createClassPath(fos);
final FileObject newFileFo = cp.findResource(binaryName + ".java"); //NOI18N
if (newFileFo != null) {
try {
final EditorCookie ec = DataObject.find(fileFo).getLookup().lookup(EditorCookie.class);
final Openable open = DataObject.find(newFileFo).getLookup().lookup(Openable.class);
if (ec != null && open != null) {
final ElementHandle activeElement = findElement(fileFo);
ec.close();
if (activeElement == null || !UiUtils.open(newFileFo, activeElement)) {
open.open();
}
success = true;
}
} catch (DataObjectNotFoundException ex) {
Exceptions.printStackTrace(ex);
}
}
}
}
if (!success) {
enableAttach();
}
}
@Override
public void attachmentFailed() {
enableAttach();
}
private void enableAttach() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jButton1.setEnabled(true);
}
});
}
});
}
});
}//GEN-LAST:event_attachSources
@CheckForNull
private ElementHandle> findElement(@NonNull final FileObject expectedFile) {
final AtomicReference> res = new AtomicReference<>();
JTextComponent editor = EditorRegistry.lastFocusedComponent();
final int pos = editor.getCaret().getDot() + 1;
final FileObject activeFile = EditorDocumentUtils.getFileObject(editor.getDocument());
if (expectedFile.equals(activeFile)) {
final Source src = Source.create(expectedFile);
if (src != null) {
final AtomicBoolean cancel = new AtomicBoolean();
BaseProgressUtils.runOffEventDispatchThread(
new Runnable() {
@Override
public void run() {
try {
ParserManager.parse(
Collections.singleton(src),
new UserTask() {
@Override
public void run(ResultIterator resultIterator) throws Exception {
if (cancel.get()) {
return;
}
Parser.Result result = resultIterator.getParserResult();
final CompilationController cc = result == null ? null : CompilationController.get(result);
if (cc != null) {
cc.toPhase(Phase.ELEMENTS_RESOLVED);
if (cancel.get()) {
return;
}
TreePath path = cc.getTreeUtilities().pathFor(pos);
Element e;
for (e = element(path, cc); e == null; e = element(path, cc)) {
path = path.getParentPath();
if (path == null) {
break;
}
if (cancel.get()) {
return;
}
}
if (e != null) {
res.set(ElementHandle.create(e));
}
}
}
});
} catch (ParseException e) {
//pass
}
}
},
NbBundle.getMessage(AttachSourcePanel.class, "TXT_OpenAttachedSource"),
cancel,
false);
}
}
return res.get();
}
@CheckForNull
private static Element element(
@NonNull final TreePath path,
@NonNull final CompilationInfo ci) {
Element e = ci.getTrees().getElement(path);
if (e == null) {
return e;
}
switch (e.getKind()) {
case PACKAGE:
case CLASS:
case INTERFACE:
case ENUM:
case ANNOTATION_TYPE:
case METHOD:
case CONSTRUCTOR:
case INSTANCE_INIT:
case STATIC_INIT:
case FIELD:
case ENUM_CONSTANT:
case TYPE_PARAMETER:
return e;
default:
return null;
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
// End of variables declaration//GEN-END:variables
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy