/**
* SlingBeans - NetBeans Sling plugin https://github.com/jkan997/SlingBeans
* Licensed under Apache 2.0 license http://www.apache.org/licenses/LICENSE-2.0
*/
package org.jkan997.slingbeans.nbtree;
import java.beans.PropertyVetoException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jkan997.slingbeans.dialogs.NewVersionDialog;
import org.jkan997.slingbeans.helper.LogHelper;
import org.jkan997.slingbeans.nbservices.SlingFsConnector;
import org.jkan997.slingbeans.helper.StringHelper;
import org.jkan997.slingbeans.helper.SwingHelper;
import org.jkan997.slingbeans.nbservices.SlingFsFactory;
import org.jkan997.slingbeans.slingfs.FileObject;
import org.jkan997.slingbeans.slingfs.FileSystem;
import org.jkan997.slingbeans.version.Version;
import org.jkan997.slingbeans.version.VersionManager;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.lookup.InstanceContent;
import org.openide.util.lookup.Lookups;
import org.openide.windows.TopComponent;
import org.netbeans.api.progress.ProgressUtils;
/**
* Top component which displays something.
*/
@ConvertAsProperties(
dtd = "-//org.jkan997.slingbeans.nbtree//SlingTree//EN",
autostore = false)
@TopComponent.Description(
preferredID = "SlingTreeTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "explorer", openAtStartup = true)
@ActionID(category = "Window", id = "org.jkan997.slingbeans.nbtree.SlingTreeTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(
displayName = "Sling Explorer",
preferredID = "SlingTreeTopComponent")
/*@Messages({
"CTL_CrxTreeAction=CrxTree",
"CTL_CrxTreeTopComponent=CrxTree Window",
"HINT_CrxTreeTopComponent=This is a CrxTree window"
})*/
public final class SlingTreeTopComponent extends TopComponent implements ExplorerManager.Provider {
protected FileObject rootFo = null;
private final ExplorerManager mgr = new ExplorerManager();
private final InstanceContent content = new InstanceContent();
private final SlingRootNode rootNode;
public SlingTreeTopComponent() {
initComponents();
associateLookup(ExplorerUtils.createLookup(mgr, getActionMap()));
setDisplayName("Sling Explorer");
pathPanel.setOpaque(false);
pathText.setEnabled(false);
//pathText.setEditable(false);
pathText.setText("/");
rootNode = new SlingRootNode(Children.LEAF);
BeanTreeView btv = (BeanTreeView) crxScrollPane;
rootNode.setHidden(true);
rootNode.setBeanTreeView(btv);
mgr.setRootContext(rootNode);
Lookups.singleton(this);
}
private void initSlingFs(final FileObject rootFo) {
try {
final SlingNodeChildren rootChildren = new SlingNodeChildren(rootFo);
SlingRootNode slingRootNode = new SlingRootNode(rootChildren);
String rootNodeName = "Not connected";
if (rootFo != null) {
StringBuilder sb = new StringBuilder();
FileSystem fs = rootFo.getFileSystem();
boolean isAEM = fs.isCQ5();
if (isAEM) {
sb.append("AEM");
} else {
sb.append("Sling");
}
sb.append(" (");
sb.append(fs.getServerPrefix());
sb.append("/)");
rootNodeName = sb.toString();
}
slingRootNode.setDisplayName(rootNodeName);
slingRootNode.setRootFileObject(rootFo);
mgr.setRootContext(slingRootNode);
pathText.setEnabled(true);
crxScrollPane.invalidate();
} catch (Exception ex) {
LogHelper.logError(ex);
}
}
protected SlingNode selectedSlingNode = null;
private String selectedPath = null;
private BeanTreeView getBeanTreeView() {
BeanTreeView res = new BeanTreeView() {
@Override
public void selectionChanged(Node[] nodes, ExplorerManager em) throws PropertyVetoException {
super.selectionChanged(nodes, em);
if ((nodes != null) && (nodes.length > 0) && (nodes[0] instanceof SlingNode)) {
SlingNode slingNode = (SlingNode) (nodes[0]);
selectedSlingNode = slingNode;
if (slingNode != null) {
selectedPath = "/" + slingNode.getPath();
pathText.setText(selectedPath);
}
}
}
};
return res;
}
public ExplorerManager getExplorerManager() {
return mgr;
}
/**
* 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
pathPanel = new javax.swing.JPanel();
gotoBtn = new javax.swing.JButton();
pathText = new javax.swing.JTextField();
connectBtn = new javax.swing.JButton();
crxScrollPane = getBeanTreeView();
pathPanel.setBackground(new java.awt.Color(255, 255, 255));
gotoBtn.setFont(new java.awt.Font("Lucida Grande", 0, 10)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(gotoBtn, org.openide.util.NbBundle.getMessage(SlingTreeTopComponent.class, "SlingTreeTopComponent.gotoBtn.text")); // NOI18N
gotoBtn.setToolTipText(org.openide.util.NbBundle.getMessage(SlingTreeTopComponent.class, "SlingTreeTopComponent.gotoBtn.toolTipText")); // NOI18N
gotoBtn.setMargin(new java.awt.Insets(0, 0, 0, 0));
gotoBtn.setMaximumSize(new java.awt.Dimension(75, 20));
gotoBtn.setMinimumSize(new java.awt.Dimension(75, 20));
gotoBtn.setPreferredSize(new java.awt.Dimension(75, 23));
gotoBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
gotoBtnActionPerformed(evt);
}
});
pathText.setFont(new java.awt.Font("Lucida Grande", 0, 10)); // NOI18N
pathText.setText(org.openide.util.NbBundle.getMessage(SlingTreeTopComponent.class, "SlingTreeTopComponent.pathText.text")); // NOI18N
pathText.setPreferredSize(new java.awt.Dimension(84, 30));
pathText.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pathTextActionPerformed(evt);
}
});
pathText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
pathTextKeyPressed(evt);
}
});
connectBtn.setFont(new java.awt.Font("Lucida Grande", 0, 10)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(connectBtn, org.openide.util.NbBundle.getMessage(SlingTreeTopComponent.class, "SlingTreeTopComponent.connectBtn.text")); // NOI18N
connectBtn.setMargin(new java.awt.Insets(0, 0, 0, 0));
connectBtn.setMaximumSize(new java.awt.Dimension(75, 20));
connectBtn.setMinimumSize(new java.awt.Dimension(75, 20));
connectBtn.setPreferredSize(new java.awt.Dimension(5, 30));
connectBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectBtnActionPerformed(evt);
}
});
javax.swing.GroupLayout pathPanelLayout = new javax.swing.GroupLayout(pathPanel);
pathPanel.setLayout(pathPanelLayout);
pathPanelLayout.setHorizontalGroup(
pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pathPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(pathText, javax.swing.GroupLayout.DEFAULT_SIZE, 230, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(gotoBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(connectBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pathPanelLayout.setVerticalGroup(
pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pathPanelLayout.createSequentialGroup()
.addGroup(pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(pathText, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(gotoBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(connectBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pathPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {connectBtn, gotoBtn});
crxScrollPane.setBorder(null);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(crxScrollPane)
.addContainerGap())
.addComponent(pathPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(pathPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(crxScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void connectBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectBtnActionPerformed
if (connectBtn.getText().equals("Disconnect")) {
SlingFsFactory slingFsFactory = SlingFsFactory.lookup();
slingFsFactory.unregisterAll();
rootFo = null;
this.initSlingFs(rootFo);
this.pathText.setText("Not connected");
this.pathText.setEditable(false);
rootNode.setName("Not connected");
connectBtn.setText("Connect");
} else if (connectBtn.getText().equals("Connect")) {
checkNewestVersion();
SlingFsConnector sfh = new SlingFsConnector() {
@Override
protected void rootNodeHandler(FileObject fo) {
rootFo = fo;
try {
FileSystem fs = fo.getFileSystem();
rootNode.setName(fs.getDisplayName());
pathText.setEditable(true);
connectBtn.setText("Disconnect");
} catch (Exception ex) {
LogHelper.logError(ex);
}
}
};
sfh.connectToFileSystem(null);
this.initSlingFs(rootFo);
rootFo = null;
}
}//GEN-LAST:event_connectBtnActionPerformed
private void pathTextKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_pathTextKeyPressed
if (evt.getKeyCode() == 10) {
gotoBtnActionPerformed(null);
}
}//GEN-LAST:event_pathTextKeyPressed
private void pathTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pathTextActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_pathTextActionPerformed
private void gotoBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoBtnActionPerformed
String path = pathText.getText();
gotoPath(path);
//btv.expandNode(selectedSlingNode);
//selectedSlingNode.refresh();
}//GEN-LAST:event_gotoBtnActionPerformed
public void refreshPath(String path) {
path = StringHelper.normalizePath(path);
String[] pathArr = path.split("/");
Node node = mgr.getRootContext();
boolean childFound = false;
StringBuilder pathSb = new StringBuilder();
for (String part : pathArr) {
childFound = false;
for (Node child : node.getChildren().getNodes()) {
String nodeName = child.getDisplayName();
if (nodeName.equals(part)) {
childFound = true;
node = child;
pathSb.append("/" + node.getName());
break;
}
}
if (!childFound) {
break;
}
}
if (node instanceof SlingNode) {
LogHelper.logInfo(this, "Refreshing path %s", pathSb);
((SlingNode) node).refresh();
}
}
public String getPath(){
return this.selectedPath;
}
public void gotoPath(String path) {
BeanTreeView btv = (BeanTreeView) crxScrollPane;
path = StringHelper.normalizePath(path);
String[] pathArr = path.split("/");
Node node = mgr.getRootContext();
boolean childFound = false;
LogHelper.logInfo(this, "Trying to expand path %s", path);
for (String part : pathArr) {
childFound = false;
for (Node child : node.getChildren().getNodes()) {
String nodeName = child.getDisplayName();
LogHelper.logInfo(this, "Checking node %s", nodeName);
if (nodeName.equals(part)) {
childFound = true;
btv.expandNode(child);
node = child;
LogHelper.logInfo(this, "Expanding %s", part);
break;
}
}
if (!childFound) {
LogHelper.logInfo(this, "Cannot expand %s", part);
break;
}
}
if (node != null) {
try {
mgr.setSelectedNodes(new Node[]{node});
} catch (PropertyVetoException ex) {
LogHelper.logError(ex);
}
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton connectBtn;
private javax.swing.JScrollPane crxScrollPane;
private javax.swing.JButton gotoBtn;
private javax.swing.JPanel pathPanel;
private javax.swing.JTextField pathText;
// End of variables declaration//GEN-END:variables
@Override
public void componentOpened() {
// TODO add custom code on component opening
}
@Override
public void componentClosed() {
// TODO add custom code on component closing
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
// TODO store your settings
}
void readProperties(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
}
private void checkNewestVersion() {
final Runnable checkVersionTask = new Runnable() {
@Override
public void run() {
final Version version = VersionManager.getNewestVersion();
if (version != null) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
NewVersionDialog newVersionDialog = new NewVersionDialog(null, false);
newVersionDialog.setVersion(version);
SwingHelper.showDialog(newVersionDialog);
}
});
}
}
};
Thread t = new Thread(checkVersionTask);
t.start();
}
}