📄 obrdisplayer.java
字号:
} for(Iterator it = locationMap.keySet().iterator(); it.hasNext(); ) { String loc = (String)it.next(); node = (OBRNode)locationMap.get(loc); if(Util.bundleEqual(b, node.getBundleRecord())) { return node; } } return null; } /** * Create the sort selection button, with items * defined in SORT_ARRAY/SORT_NAMES */ JButton makeSortSelectionButton() { JButton sortButton = new JButton(sortIcon); sortButton.setToolTipText("Select sorting"); final JPopupMenu sortPopupMenu = new JPopupMenu(); ButtonGroup group = new ButtonGroup(); for(int i = 0; i < SORT_ARRAY.length; i++) { JCheckBoxMenuItem item = new JCheckBoxMenuItem(SORT_NAMES[i]); final int cat = SORT_ARRAY[i]; item.setState(cat == sortCategory); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { sortCategory = cat; refreshList(false); } }); sortPopupMenu.add(item); group.add(item); } sortButton.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { showPopup(e); } public void mouseReleased(MouseEvent e) { showPopup(e); } private void showPopup(MouseEvent e) { Component comp = e.getComponent(); sortPopupMenu.show(comp, 0, comp.getSize().height); } }); return sortButton; } boolean bBusy = false; /** * Install or install+start a bundle specified by an OBRNode * using the BundleRepositoryService. Run an a new thread to * avoid blocking the swing thread for potentially long operations. * * @param obrNode Bundle to install/start * @param bStart if <tt>true</t>, start, otherewise just install */ void installOrStart(final OBRNode obrNode, final boolean bStart) { if(bBusy) { return; } new Thread() { { start(); } public void run() { try { bBusy = obrNode.bBusy = true; setSelected(obrNode); installOrStartSync(obrNode, bStart); } catch (Exception e) { obrNode.appendLog("" + e + "\n"); } finally { bBusy = obrNode.bBusy = false; setSelected(obrNode); } } }; } void installOrStartSync(OBRNode obrNode, boolean bStart) { BundleRecord br = obrNode.getBundleRecord(); if(br == null) { return; } String updateURL = (String)br.getAttribute(BundleRecord.BUNDLE_UPDATELOCATION); // Check if bundle already is installed. If so, // ask user if it should be updated, installed again or // if the operation should be cancelled. Bundle b = getBundle(br); if(b != null) { boolean bIsRepoBundle = Util.isInRepo(b, updateURL); String[] options = bIsRepoBundle ? (new String[] { "Update", "Cancel", }) : (new String[] { "Update", "Install again", "Cancel", }); String msg = bIsRepoBundle ? "The selected bundle is already installed\n" + "from the repository.\n" + "\n" + "It can be updated from the repository." : "The selected bundle is already installed.\n" + "\n" + "It can be updated from the repository, or\n" + "a new instance can be installed from the\n" + "repository"; int n = JOptionPane .showOptionDialog(recordTree, msg, "Bundle is installed", // title JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, // icon options, options[0]); if(bIsRepoBundle) { if(n == 0) { // update obrNode.appendLog("update.\n"); } else if(n == 1) { // Cancel return; } } else { if(n == 0) { // Update InputStream in = null; try { URL url = new URL(updateURL); in = new BufferedInputStream(url.openStream()); b.update(in); obrNode.appendLog("Updated from " + url + "\n"); } catch (Exception e) { obrNode.appendLog("Update failed: " + e + "\n"); } finally { try { in.close(); } catch (Exception ignored) { } } return; } else if(n == 1) { // install new obrNode.appendLog("Install new instance.\n"); } else if(n == 2) { // cancel return; } } } // Install the budle from repo BundleRepositoryService obr = getOBR(); // deployBundle writes all info to streams, so we have to // catch that info. The text will be displayed by // the node's toHTML method ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintStream outStream = new PrintStream(bout, true); // We always resolve. boolean bResolve = true; try { boolean bOK = obr.deployBundle(outStream, // Output stream. outStream, // Error stream. updateURL, bResolve, bStart); if(bOK) { if(sortCategory == SORT_STATUS) { refreshList(false); } } } catch (Exception e) { e.printStackTrace(outStream); } finally { try { outStream.close();} catch (Exception ignored) { } String s = new String(bout.toByteArray()); obrNode.appendLog(s); } setSelected(obrNode); } /** * Refresh the OBR tree and try to reshow/reselect * any previously selected bundle node. * * @param bReload if <tt>true</tt>, reload the bundle repository * XML files, otherewise, just rebuild the tree. */ synchronized void refreshList(final boolean bReload) { Thread t = new Thread() { public void run() { locationMap.clear(); BundleRecord brOld = brSelected != null ? brSelected.getBundleRecord() : null; setRootText(STR_LOADING); rootNode = new TopNode(STR_TOPNAME); treeModel = new DefaultTreeModel(rootNode); BundleRepositoryService obr = getOBR(); if(obr != null) { if(bReload) { obrErr = ""; try { assertRepoURLs(obr.getRepositoryURLs()); obr.setRepositoryURLs(obr.getRepositoryURLs()); } catch (Exception e) { obrErr = "<b>" + e.getClass().getName() + "</b>"+ "<pre>\n" + e.getMessage() + "</pre>"; } } int count = obr.getBundleRecordCount(); // String (category) -> Set (BundleRecord) Map categories = new TreeMap(new Comparator() { public int compare(Object o1, Object o2) { return o1.toString().compareToIgnoreCase(o2.toString()); } }); // move all bundle records into a sorted // category map of sets for(int i = 0; i < count; i++) { BundleRecord br = obr.getBundleRecord(i); String loc = (String)br.getAttribute(BundleRecord.BUNDLE_UPDATELOCATION); String category = "other"; if(sortCategory == SORT_CATEGORY) { category = Util.getAttribute(br, BundleRecord.BUNDLE_CATEGORY, "[no category]"); } else if(sortCategory == SORT_VENDOR) { category = Util.getAttribute(br, BundleRecord.BUNDLE_VENDOR, "[no vendor]"); } else if(sortCategory == SORT_STATUS) { if(isInstalled(br)) { category = "Installed"; } else { category = "Not installed"; } } else if(sortCategory == SORT_NONE) { category = SORT_NAMES[SORT_NONE]; } else { int ix = loc.indexOf(":"); if(ix != -1) { category = loc.substring(0, ix); if(loc.startsWith("http://")) { ix = loc.indexOf("/", 8); if(ix != -1) { category = loc.substring(0, ix); } } else { ix = loc.indexOf("/", ix + 1); if(ix != -1) { category = loc.substring(0, ix); } else { ix = loc.indexOf("\\", ix + 1); if(ix != -1) { category = loc.substring(0, ix); } } } } } Set set = (Set)categories.get(category); if(set == null) { set = new TreeSet(new BRComparator()); categories.put(category, set); } set.add(br); } int i = 0; DefaultMutableTreeNode selNode = null; for(Iterator it = categories.keySet().iterator(); it.hasNext();) { String category = (String)it.next(); Set set = (Set)categories.get(category); final DefaultMutableTreeNode categoryNode = new CategoryNode(category); for(Iterator it2 = set.iterator(); it2.hasNext();) { BundleRecord br = (BundleRecord)it2.next(); DefaultMutableTreeNode brNode = new OBRNode(br); categoryNode.add(brNode); i++; String loc = (String)br.getAttribute(BundleRecord.BUNDLE_UPDATELOCATION); locationMap.put(loc, brNode); if(brOld != null && loc.equals(brOld.getAttribute(BundleRecord.BUNDLE_UPDATELOCATION))) { selNode = brNode; } } rootNode.add(categoryNode); } final TreePath selPath = new TreePath(selNode != null ? selNode.getPath() : rootNode.getPath()); showPath(selPath, treeModel); } } }; t.start(); } /** * Show the specified path and possible model (on the Swing thread) * * @param selPath path to show * @param model if not <tt>null</tt>, set as tree's model before setting * selected path. */ void showPath(final TreePath selPath, final TreeModel model) { SwingUtilities.invokeLater(new Runnable() { public void run() { if(model != null) { recordTree.setModel(model); } recordTree.expandPath(selPath); recordTree.setSelectionPath(selPath); recordTree.scrollPathToVisible(selPath); } }); } /** * Assert that the URLs seem to be valid ULRs. * * @throws RuntimeException if any of the strings in <tt>urls</tt> * fails to resolve to valid URL. */ void assertRepoURLs(String[] urls) { if(urls == null) { throw new RuntimeException("No URLs set"); } StringBuffer sb = new StringBuffer(); int nConnectionErrs = 0; // for each of the strings, try to create an URL and // do an initial connect() for(int i = 0; i < urls.length; i++) { URLConnection conn = null; try { URL url = new URL(urls[i]); conn = url.openConnection(); conn.connect(); } catch (Exception e) { sb.append(" " + urls[i] + ": " + e); sb.append("\n"); nConnectionErrs++; } finally { // close? } } if(nConnectionErrs > 0) { String msg = "URL connection errors:\n" + sb.toString(); throw new RuntimeException(msg); } } /** * Clear the tree and set the text of the tree's root node. */ void setRootText(final String s) { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { recordTree.setModel(new DefaultTreeModel(new TopNode(s))); } }); } catch (Exception e) { } } /** * Query the user to a list of repo URLs */ void askRepoURls() { try { StringBuffer sb = new StringBuffer(); String[] urls = getOBR().getRepositoryURLs(); for(int i = 0; i < urls.length; i++) { sb.append(urls[i]); if(i < urls.length - 1) { sb.append("\n"); } } JPanel panel = new JPanel(new BorderLayout()); JTextArea text = new JTextArea(Math.min(3, urls.length), 40); text.setText(sb.toString()); // text.setPreferredSize(new Dimension(300, 100)); JScrollPane scroll = new JScrollPane(text, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scroll.setPreferredSize(new Dimension(300, 100)); panel.add(scroll, BorderLayout.CENTER); panel.add(new JLabel("Repository URLs."), BorderLayout.NORTH); int option = JOptionPane.showConfirmDialog(this, panel, "Repository URLs", JOptionPane.YES_NO_OPTION); String r2 = text.getText(); if(option == 0 && !r2.equals(sb.toString())) { StringTokenizer st = new StringTokenizer(r2, "\n"); urls = new String[st.countTokens()]; int i = 0; while (st.hasMoreTokens()) { urls[i++] = st.nextToken(); } try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -