Java tutorial
/** * Copyright (C) 2008 Atlassian * * Licensed 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 com.atlassian.theplugin.idea.config.serverconfig; import com.atlassian.theplugin.commons.ServerType; import com.atlassian.theplugin.commons.cfg.BambooServerCfg; import com.atlassian.theplugin.commons.cfg.CrucibleServerCfg; import com.atlassian.theplugin.commons.cfg.JiraServerCfg; import com.atlassian.theplugin.commons.cfg.ServerCfg; import com.atlassian.theplugin.commons.cfg.ServerIdImpl; import com.atlassian.theplugin.commons.cfg.UserCfg; import com.atlassian.theplugin.commons.cfg.xstream.BasePrivateConfigurationDao; import com.atlassian.theplugin.commons.remoteapi.ServerData; import com.atlassian.theplugin.idea.Constants; import com.atlassian.theplugin.idea.config.serverconfig.model.RootNode; import com.atlassian.theplugin.idea.config.serverconfig.model.ServerInfoNode; import com.atlassian.theplugin.idea.config.serverconfig.model.ServerNode; import com.atlassian.theplugin.idea.config.serverconfig.model.ServerNodeFactory; import com.atlassian.theplugin.idea.config.serverconfig.model.ServerTreeModel; import com.atlassian.theplugin.idea.config.serverconfig.model.ServerTypeNode; import com.atlassian.theplugin.idea.config.serverconfig.util.ServerNameUtil; import com.atlassian.theplugin.util.PluginUtil; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.io.File; import java.util.Collection; public final class ServerTreePanel extends JPanel implements TreeSelectionListener, DataProvider { private JTree serverTree; private ServerTreeModel model; private DefaultMutableTreeNode selectedNode; private boolean forceExpand = true; public static final int WIDTH = 240; public static final int HEIGHT = 250; private static final int VISIBLE_ROW_COUNT = 7; private Collection<ServerCfg> servers; private Project project; private UserCfg defaultUser; /** * serverConfigPanel needs to be initialized outside of the constructor to avoid cyclic dependency. * * @param serverConfigPanel panel to invoke storeServer() and showEmptyPanel() on. */ public void setServerConfigPanel(ServerConfigPanel serverConfigPanel) { this.serverConfigPanel = serverConfigPanel; } private ServerConfigPanel serverConfigPanel; public ServerTreePanel(Project project, UserCfg defaultUser) { this.project = project; this.defaultUser = defaultUser; initLayout(); } private void initLayout() { setLayout(new BorderLayout()); setMinimumSize(new Dimension(WIDTH, HEIGHT)); add(new JScrollPane(getServerTree()), BorderLayout.CENTER); } private void expandAllPaths() { for (int i = 0; i < serverTree.getRowCount(); ++i) { serverTree.expandRow(i); } } private JTree getServerTree() { if (serverTree == null) { serverTree = new JTree(); serverTree.setName("Server tree"); model = new ServerTreeModel(new RootNode()); serverTree.setModel(model); serverTree.setRootVisible(false); serverTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); serverTree.setVisibleRowCount(VISIBLE_ROW_COUNT); serverTree.setShowsRootHandles(true); serverTree.addTreeSelectionListener(this); final ServerTreeRenderer treeRenderer = new ServerTreeRenderer(); serverTree.setCellRenderer(treeRenderer); // final ServerTreeMouseListener serverTreeMouseListener = new ServerTreeMouseListener(serverTree); } return serverTree; } @Override public void setEnabled(boolean b) { super.setEnabled(b); getServerTree().setEnabled(b); } public String addServer(ServerType serverType) { if (serverType == null) { return null; } String name = ServerNameUtil.suggestNewName(servers); ServerCfg newServer = createNewServer(serverType, name); if (newServer == null) { return null; } ServerNode child = addNewServerCfg(serverType, newServer); TreePath path = new TreePath(child.getPath()); serverTree.scrollPathToVisible(path); serverTree.setSelectionPath(path); serverTree.expandPath(path); return newServer.getName(); } public ServerNode addNewServerCfg(ServerType serverType, ServerCfg newServer) { servers.add(newServer); ServerNode child = ServerNodeFactory.getServerNode(newServer); ServerTypeNode serverTypeNode = model.getServerTypeNode(serverType); model.insertNodeInto(child, serverTypeNode, serverTypeNode.getChildCount()); return child; } private ServerCfg createNewServer(final ServerType serverType, final String name) { ServerIdImpl id = new ServerIdImpl(); // CHECKSTYLE:OFF switch (serverType) { // CHECKSTYLE:ON case BAMBOO_SERVER: return new BambooServerCfg(false, name, id); case CRUCIBLE_SERVER: return new CrucibleServerCfg(false, name, id); case JIRA_SERVER: return new JiraServerCfg(false, name, id, true, false); case JIRA_STUDIO_SERVER: SwingUtilities.invokeLater(new Runnable() { public void run() { new JiraStudioConfigDialog(project, ServerTreePanel.this, defaultUser, servers).show(); } }); return null; } throw new RuntimeException("Unhandled server type [" + serverType + "]"); } public void copyServer() { /* ServerBean newServer = new ServerBean(); newServer.setName(suggestCopyName(ConfigurationFactory.getConfiguration() .getBambooConfiguration().transientGetServers())); ConfigurationFactory.getConfiguration().getBambooConfiguration().addServer(newServer); serverTree.updateUI(); return newServer.getName(); */ } public void removeServer() { if (selectedNode != null) { if (selectedNode instanceof ServerNode) { final ServerNode selectedServerNode = (ServerNode) this.selectedNode; int response = Messages.showYesNoDialog("Are you sure you want to delete the selected server?", "Confirm server delete", Messages.getQuestionIcon()); if (response != 0) { return; } final ServerCfg serverCfg = selectedServerNode.getServer(); if (serverCfg.isShared()) { serverCfg.setDeleted(true); serverConfigPanel.showEmptyPanel(); } else { servers.remove(serverCfg); } TreeNode parent = selectedServerNode.getParent(); selectedServerNode.removeFromParent(); model.nodeStructureChanged(parent); deleteServerFile(serverCfg); } } } // private synchronized void deleteServerFromSharedServers(ServerCfg serverCfg) { // File sharedServersFile = new File( // BasePrivateConfigurationDao.getPrivateCfgDirectoryPath() + File.separator + HomeDirSharedConfigurationImpl.GLOBAL_SERVERS_FILE_NAME); // if (!sharedServersFile.exists()) { // return; // } // Document doc; // // final SAXBuilder builder = new SAXBuilder(false); // try { // doc = builder.build(sharedServersFile.getAbsolutePath()); // doc.getRootElement().getChildren().get(0) // XPath xpath = XPathFactory.newInstance().newXPath(); // XPathExpression expression = xpath.compile("//*/server-id"); // NodeList nodes = (NodeList) expression.evaluate(doc, XPathConstants.NODESET); // for (int i = 0; i < nodes.getLength(); ++i) { // Node item = nodes.item(i); // if (item.getNodeValue().equals(serverCfg.getServerId().getId())) { // System.out.println("found " + serverCfg.getServerId().getId()); // } // } // } catch (JDOMException e) { // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. // } catch (IOException e) { // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. // } catch (XPathExpressionException e) { // e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. // } // } /** * Deletes server file with password * */ private void deleteServerFile(ServerCfg serverCfg) { String fileName = serverCfg.getServerId().getId(); File serverFile = new File( BasePrivateConfigurationDao.getPrivateCfgDirectoryPath() + File.separator + fileName); if (serverFile.exists()) { boolean success = serverFile.delete(); if (!success) { PluginUtil.getLogger().error("Cannot delete file:" + fileName + " "); } } } public void setData(Collection<ServerCfg> newServers) { servers = newServers; // jgorycki: I assume this method will only be called at the beginning of the dialog's lifecycle. // I want to expand all paths in the tree and not select any nodes - hence showing an empty panel updateTreeConfiguration(); if (forceExpand) { // do this only during first operation expandAllPaths(); // forceExpand = false; } } private ServerNode updateServerTree() { ServerNode firstServerNode = null; model = new ServerTreeModel(new RootNode()); serverTree.setModel(model); // !servers.isEmpty() because: // if server list is empty, don't create server type node, // otherwise create node - it would be required // ServerTypeNode serverTypeNode = model.getServerTypeNode(serverType, !servers.isEmpty()); // TreePath serverNodePath = new TreePath(serverTypeNode.getPath()); // boolean doExpand = serverTree.isExpanded(serverNodePath); for (ServerCfg server : servers) { if (server.isDeleted()) { continue; } ServerNode child = ServerNodeFactory.getServerNode(server); ServerTypeNode serverTypeNode = model.getServerTypeNode(server.getServerType()); model.insertNodeInto(child, serverTypeNode, serverTypeNode.getChildCount()); if (firstServerNode == null) { firstServerNode = child; } if (selectedNode != null && selectedNode instanceof ServerNode) { ServerNode serverNode = (ServerNode) selectedNode; if (child.getServer().getServerId().equals(serverNode.getServer().getServerId())) { firstServerNode = child; } } model.nodeStructureChanged(serverTypeNode); } // if (doExpand) { // serverTree.expandPath(serverNodePath); // } return firstServerNode; } private void updateTreeConfiguration() { //DefaultMutableTreeNode tmpNode = selectedNode; selectedNode = updateServerTree(); if (selectedNode != null) { TreePath path = new TreePath(selectedNode.getPath()); serverTree.scrollPathToVisible(path); serverTree.setSelectionPath(path); serverTree.expandPath(path); } else { serverConfigPanel.showEmptyPanel(); } } public void valueChanged(TreeSelectionEvent e) { TreePath oldPath = e.getOldLeadSelectionPath(); if (oldPath != null) { DefaultMutableTreeNode oldNode = (DefaultMutableTreeNode) oldPath.getLastPathComponent(); if (oldNode != null && oldNode instanceof ServerNode) { serverConfigPanel.saveData(((ServerNode) oldNode).getServerType()); } model.nodeChanged(oldNode); } TreePath path = e.getNewLeadSelectionPath(); if (path != null) { selectedNode = (DefaultMutableTreeNode) path.getLastPathComponent(); if (selectedNode instanceof ServerNode) { ServerCfg server = ((ServerNode) selectedNode).getServer(); serverConfigPanel.editServer(server); // else { // // PL-235 show blank panel if server from tree node does not exist in configuration // // it happens if you add server, click cancel and open config window again // serverConfigPanel.showEmptyPanel(); // } } else if (selectedNode instanceof ServerTypeNode) { serverConfigPanel.showEmptyPanel(); } else if (selectedNode instanceof ServerInfoNode) { serverConfigPanel.showEmptyPanel(); } } else { serverConfigPanel.showEmptyPanel(); } } public ServerCfg getSelectedServer() { if (selectedNode instanceof ServerNode) { return ((ServerNode) selectedNode).getServer(); } return null; } @Nullable public Object getData(@NonNls final String dataId) { if (dataId.equals(Constants.SERVER_CFG_KEY.getName())) { final ServerCfg selectedServer = getSelectedServer(); if (selectedServer == null) { return null; } return selectedServer; } else if (dataId.equals(Constants.SERVER_TYPE)) { if (selectedNode instanceof ServerTypeNode) { final ServerTypeNode serverTypeNode = (ServerTypeNode) selectedNode; return serverTypeNode.getServerType(); } } return null; } public void setSelectedServer(final ServerData selectedServer) { if (selectedServer != null) { for (int i = 0; i < serverTree.getRowCount(); i++) { TreePath path = serverTree.getPathForRow(i); Object object = path.getLastPathComponent(); if (object instanceof ServerNode) { ServerNode node = (ServerNode) object; if (node.getServer().getServerId().equals(selectedServer.getServerId())) { serverTree.expandPath(path); serverTree.makeVisible(path); serverTree.setSelectionPath(path); break; } } } } } public ServerType getSelectedServerType() { TreePath path = serverTree.getSelectionPath(); if (path == null) { return null; } selectedNode = (DefaultMutableTreeNode) path.getLastPathComponent(); if (selectedNode instanceof ServerTypeNode) { return ((ServerTypeNode) selectedNode).getServerType(); } return null; } public class ServerTreeMouseListener extends MouseAdapter implements MouseMotionListener { private final JTree jtree; public ServerTreeMouseListener(@NotNull JTree jtree) { this.jtree = jtree; jtree.addMouseListener(this); jtree.addMouseMotionListener(this); // jtree.addComponentListener(this); } public void mousePressed(final MouseEvent e) { if (isHLinkHit(e)) { TreePath treepath = jtree.getPathForLocation(e.getX(), e.getY()); if (treepath != null) { final Object o = treepath.getLastPathComponent(); if (o instanceof ServerInfoNode) { BrowserUtil.launchBrowser(((ServerInfoNode) o).getServerType().getInfoUrl()); } } } } public void mouseMoved(final MouseEvent e) { jtree.setCursor( isHLinkHit(e) ? Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) : Cursor.getDefaultCursor()); } public void mouseDragged(final MouseEvent e) { } private boolean isHLinkHit(MouseEvent mouseevent) { TreePath treepath = jtree.getPathForLocation(mouseevent.getX(), mouseevent.getY()); if (treepath != null) { final Object o = treepath.getLastPathComponent(); if (o instanceof ServerInfoNode) { return true; } } return false; } } }