001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the file COPYING. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * If you do not have access to this file, you may request a copy from * 011 * help@hdfgroup.org. * 012 ****************************************************************************/ 013 014package hdf.view; 015 016import java.awt.BorderLayout; 017import java.awt.Dimension; 018import java.awt.GridLayout; 019import java.awt.Insets; 020import java.awt.Point; 021import java.awt.Toolkit; 022import java.awt.event.ActionEvent; 023import java.awt.event.ActionListener; 024import java.awt.event.ItemEvent; 025import java.awt.event.ItemListener; 026import java.awt.event.KeyEvent; 027import java.io.File; 028import java.util.Enumeration; 029import java.util.Iterator; 030import java.util.List; 031import java.util.Vector; 032 033import javax.swing.BorderFactory; 034import javax.swing.ButtonGroup; 035import javax.swing.JButton; 036import javax.swing.JCheckBox; 037import javax.swing.JComboBox; 038import javax.swing.JDialog; 039import javax.swing.JFileChooser; 040import javax.swing.JFrame; 041import javax.swing.JLabel; 042import javax.swing.JOptionPane; 043import javax.swing.JPanel; 044import javax.swing.JRadioButton; 045import javax.swing.JTextField; 046import javax.swing.border.TitledBorder; 047import javax.swing.event.DocumentEvent; 048import javax.swing.event.DocumentListener; 049import javax.swing.tree.DefaultMutableTreeNode; 050import javax.swing.tree.TreeNode; 051 052import hdf.object.DataFormat; 053import hdf.object.FileFormat; 054import hdf.object.Group; 055import hdf.object.HObject; 056 057/** 058 * NewLinkDialog shows a message dialog requesting user input for creating a 059 * new links. 060 * 061 * @author Peter X. Cao 062 * @version 2.4 9/6/2007 063 */ 064public class NewLinkDialog extends JDialog implements ActionListener,DocumentListener, ItemListener { 065 private static final long serialVersionUID = 7100424106041533918L; 066 067 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NewLinkDialog.class); 068 069 private JTextField nameField; 070 071 @SuppressWarnings("rawtypes") 072 private JComboBox parentChoice, targetObject; 073 074 private String currentDir; 075 076 private JTextField targetFile; 077 078 private JButton targetFileButton; 079 080 private JRadioButton hardLink, softLink, externalLink; 081 082 private JCheckBox checkUnsigned; 083 084 /** a list of current groups */ 085 private List<HObject> groupList; 086 087 /** a list of current objects */ 088 private List<?> objList; 089 090 private HObject newObject; 091 092 private FileFormat fileFormat; 093 094 private final Toolkit toolkit; 095 096 private ViewManager viewer; 097 098 private final List<?> fileList; 099 100 101 /** 102 * Constructs NewLinkDialog with specified list of possible parent groups. 103 * 104 * @param owner 105 * the owner of the input 106 * @param pGroup 107 * the parent group which the new group is added to. 108 * @param objs 109 * the list of all objects. 110 */ 111 @SuppressWarnings({ "rawtypes", "unchecked" }) 112 public NewLinkDialog(JFrame owner, Group pGroup, List<?> objs) { 113 super(owner, "New Link...", true); 114 115 viewer = (ViewManager)owner; 116 fileList = viewer.getTreeView().getCurrentFiles(); 117 118 newObject = null; 119 fileFormat = pGroup.getFileFormat(); 120 toolkit = Toolkit.getDefaultToolkit(); 121 objList = objs; 122 123 currentDir = ViewProperties.getWorkDir(); 124 125 parentChoice = new JComboBox(); 126 parentChoice.setName("linkparent"); 127 targetObject = new JComboBox(); 128 targetObject.setEditable(false); 129 130 groupList = new Vector<HObject>(objs.size()); 131 HObject obj = null; 132 Iterator<?> iterator = objs.iterator(); 133 String full_name = null; 134 int idx_root = -1, idx = -1; 135 while (iterator.hasNext()) { 136 obj = (HObject) iterator.next(); 137 idx++; 138 139 if (obj instanceof Group) { 140 Group g = (Group) obj; 141 groupList.add(obj); 142 if (g.isRoot()) { 143 full_name = HObject.separator; 144 idx_root = idx; 145 } 146 else { 147 full_name = g.getPath() + g.getName() + HObject.separator; 148 } 149 parentChoice.addItem(full_name); 150 } 151 else { 152 full_name = obj.getPath() + obj.getName(); 153 } 154 155 targetObject.addItem(full_name); 156 } 157 158 targetObject.removeItemAt(idx_root); 159 objList.remove(idx_root); 160 161 if (pGroup.isRoot()) { 162 parentChoice.setSelectedItem(HObject.separator); 163 } 164 else { 165 parentChoice.setSelectedItem(pGroup.getPath() + pGroup.getName() 166 + HObject.separator); 167 } 168 169 170 JPanel contentPane = (JPanel) getContentPane(); 171 contentPane.setLayout(new BorderLayout(5, 5)); 172 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 173 int w = 600 + (ViewProperties.getFontSize() - 12) * 15; 174 int h = 280 + (ViewProperties.getFontSize() - 12) * 10; 175 contentPane.setPreferredSize(new Dimension(w, h)); 176 177 JButton okButton = new JButton(" Ok "); 178 okButton.setActionCommand("Ok"); 179 okButton.setName("makelink"); 180 okButton.setMnemonic(KeyEvent.VK_O); 181 okButton.addActionListener(this); 182 183 JButton cancelButton = new JButton("Cancel"); 184 cancelButton.setMnemonic(KeyEvent.VK_C); 185 cancelButton.setActionCommand("Cancel"); 186 cancelButton.addActionListener(this); 187 188 // set OK and CANCEL buttons 189 JPanel buttonPanel = new JPanel(); 190 buttonPanel.add(okButton); 191 buttonPanel.add(cancelButton); 192 contentPane.add(buttonPanel, BorderLayout.SOUTH); 193 194 // set NAME and PARENT GROUP panel 195 JPanel namePanel = new JPanel(); 196 namePanel.setLayout(new BorderLayout(5, 5)); 197 JPanel tmpP = new JPanel(); 198 tmpP.setLayout(new GridLayout(5, 1,5, 5)); 199 tmpP.add(new JLabel("Link name: ")); 200 tmpP.add(new JLabel("Parent group: ")); 201 202 JPanel tmpLinkJPanel = new JPanel(); 203 tmpLinkJPanel.setLayout(new GridLayout(2, 1)); 204 tmpLinkJPanel.add(new JLabel("Type of Link: ")); 205 JButton helpButton = new JButton(ViewProperties.getHelpIcon()); 206 helpButton.setToolTipText("Help on Links"); 207 helpButton.setMargin(new Insets(0, 0, 0, 0)); 208 helpButton.addActionListener(this); 209 helpButton.setActionCommand("Help on Links"); 210 tmpLinkJPanel.add(helpButton); 211 tmpP.add(tmpLinkJPanel); 212 tmpP.add(new JLabel("Target File: ")); 213 tmpP.add(new JLabel("Target Object: ")); 214 namePanel.add(tmpP, BorderLayout.WEST); 215 216 tmpP = new JPanel(); 217 tmpP.setLayout(new GridLayout(5, 1,5,5)); 218 nameField = new JTextField(); 219 nameField.setName("linkname"); 220 tmpP.add(nameField); 221 tmpP.add(parentChoice); 222 223 JPanel tmpP0 = new JPanel(); 224 tmpP0.setLayout(new GridLayout(1, 3)); 225 tmpP0.add(hardLink = new JRadioButton("Hard Link ", true)); 226 tmpP0.add(softLink = new JRadioButton("Soft Link ")); 227 tmpP0.add(externalLink = new JRadioButton("External Link ")); 228 tmpP0.setBorder(new TitledBorder("")); 229 tmpP.add(tmpP0); 230 ButtonGroup bgroup = new ButtonGroup(); 231 bgroup.add(hardLink); 232 bgroup.add(softLink); 233 bgroup.add(externalLink); 234 hardLink.addItemListener(this); 235 hardLink.setName("hardlink"); 236 softLink.addItemListener(this); 237 softLink.setName("softlink"); 238 externalLink.addItemListener(this); 239 externalLink.setName("externallink"); 240 241 JPanel p0 = new JPanel(); 242 p0.setLayout(new BorderLayout()); 243 p0.add(targetFile = new JTextField(), BorderLayout.CENTER); 244 targetFile.getDocument().addDocumentListener(this); 245 targetFile.addActionListener(this); 246 targetFile.setActionCommand("Link to File"); 247 JButton b = new JButton("Browse..."); 248 targetFileButton = b; 249 b.setActionCommand("Browse File"); 250 b.setName("targetfilebutton"); 251 b.addActionListener(this); 252 p0.add(b, BorderLayout.EAST); 253 tmpP.add(p0); 254 targetFile.setEnabled(false); 255 targetFileButton.setEnabled(false); 256 257 tmpP.add(targetObject); 258 targetObject.setName("linktarget"); 259 namePanel.add(tmpP, BorderLayout.CENTER); 260 contentPane.add(namePanel, BorderLayout.CENTER); 261 262 // locate the H5Property dialog 263 Point l = owner.getLocation(); 264 l.x += 250; 265 l.y += 100; 266 setLocation(l); 267 validate(); 268 pack(); 269 } 270 271 public void actionPerformed(ActionEvent e) { 272 Object source = e.getSource(); 273 String cmd = e.getActionCommand(); 274 275 if (cmd.equals("Help on Links")) { 276 final String msg = "The Type of Link specifies which type of link the user wants to create. \n" 277 + "It could be hard, soft or external links. \n\n" 278 + "<html><b>Hard Link</b></html> \n" 279 + "Hard Link creates a hard link to a pre-existing object in an HDF5 file. \n" 280 + "The target object must already exist in the file.\n" 281 + "The HDF5 library keeps a count of all hard links pointing to an object. \n\n" 282 + "<html><b>Soft Link</b></html> \n" 283 + "Soft Link creates a new soft link to an object in an HDF5 file. \n" 284 + "Soft links are only for use only if the target object is in the current file. \n" 285 + "Unlike hard links, a soft link in an HDF5 file is allowed to dangle, \n" 286 + "meaning that the target object need not exist at the time that the link is created.\n" 287 + "The HDF5 library does not keep a count of soft links \n\n" 288 + "<html><b>External Link</b></html> \n" 289 + "External Link creates a new soft link to an external object, which is an object\n" 290 + "in a different HDF5 file from the location of the link. External links are \n" 291 + "allowed to dangle like soft links. \n\n" 292 + "Soft links and external links are also known as symbolic links as they use \n" 293 + "a name to point to an object; hard links employ an object's address in the file. \n\n\n"; 294 JOptionPane.showMessageDialog(this, msg); 295 } 296 297 if (cmd.equals("Browse File")) { 298 String filename = null; 299 filename = openTargetFile(); 300 301 if (filename == null) { 302 return; 303 } 304 targetFile.setText(filename); 305 } 306 307 if (cmd.equals("Ok")) { 308 newObject = createLink(); 309 310 if (newObject != null) { 311 dispose(); 312 } 313 } 314 if (cmd.equals("Cancel")) { 315 newObject = null; 316 dispose(); 317 ((Vector<HObject>) groupList).setSize(0); 318 } 319 } 320 321 private String openTargetFile() 322 { 323 JFileChooser fchooser = new JFileChooser(currentDir); 324 fchooser.setFileFilter(DefaultFileFilter.getFileFilter()); 325 326 int returnVal = fchooser.showOpenDialog(this); 327 if(returnVal != JFileChooser.APPROVE_OPTION) { 328 return null; 329 } 330 331 File choosedFile = fchooser.getSelectedFile(); 332 333 if (choosedFile == null) { 334 return null; 335 } 336 337 if (choosedFile.isDirectory()) { 338 currentDir = choosedFile.getPath(); 339 } 340 else { 341 currentDir = choosedFile.getParent(); 342 } 343 344 return choosedFile.getAbsolutePath(); 345 } 346 347 private final List<Object> breadthFirstUserObjects(TreeNode node) 348 { 349 if (node == null) { 350 return null; 351 } 352 353 Vector<Object> list = new Vector<Object>(); 354 DefaultMutableTreeNode theNode = null; 355 Enumeration<?> local_enum = ((DefaultMutableTreeNode)node).breadthFirstEnumeration(); 356 while(local_enum.hasMoreElements()) { 357 theNode = (DefaultMutableTreeNode)local_enum.nextElement(); 358 list.add(theNode.getUserObject()); 359 } 360 361 return list; 362 } 363 364 private HObject createLink() { 365 String name = null; 366 Group pgroup = null; 367 HObject obj = null; 368 369 name = nameField.getText().trim(); 370 if ((name == null) || (name.length() < 1)) { 371 toolkit.beep(); 372 JOptionPane.showMessageDialog(this, 373 "Link name is not specified.", getTitle(), 374 JOptionPane.ERROR_MESSAGE); 375 return null; 376 } 377 378 if (name.indexOf(HObject.separator) >= 0) { 379 toolkit.beep(); 380 JOptionPane.showMessageDialog(this, 381 "Link name cannot contain path.", getTitle(), 382 JOptionPane.ERROR_MESSAGE); 383 return null; 384 } 385 386 pgroup = (Group) groupList.get(parentChoice.getSelectedIndex()); 387 388 if (pgroup == null) { 389 toolkit.beep(); 390 JOptionPane.showMessageDialog(this, "Parent group is null.", 391 getTitle(), JOptionPane.ERROR_MESSAGE); 392 return null; 393 } 394 395 if (hardLink.isSelected()) { 396 HObject targetObj = (HObject) objList.get(targetObject 397 .getSelectedIndex()); 398 399 if (targetObj == null) { 400 toolkit.beep(); 401 JOptionPane.showMessageDialog(this, "Target object is null.", 402 getTitle(), JOptionPane.ERROR_MESSAGE); 403 return null; 404 } 405 406 if ((targetObj instanceof Group) && ((Group) targetObj).isRoot()) { 407 toolkit.beep(); 408 JOptionPane.showMessageDialog(this, 409 "Cannot make a link to the root group.", getTitle(), 410 JOptionPane.ERROR_MESSAGE); 411 return null; 412 } 413 414 try { 415 obj = fileFormat.createLink(pgroup, name, targetObj); 416 } 417 catch (Exception ex) { 418 toolkit.beep(); 419 JOptionPane.showMessageDialog(this, ex, getTitle(), 420 JOptionPane.ERROR_MESSAGE); 421 return null; 422 } 423 } 424 else if (softLink.isSelected()){ 425 String target_name = targetObject.getEditor().getItem().toString(); 426 if (target_name.length() < 1) { 427 toolkit.beep(); 428 JOptionPane.showMessageDialog(this, 429 "Target object name is not specified.", getTitle(), 430 JOptionPane.ERROR_MESSAGE); 431 return null; 432 } 433 434 HObject targetObj = null; 435 try { 436 targetObj = fileFormat.get(targetObject.getEditor().getItem().toString()); 437 } 438 catch (Exception ex) { 439 log.debug("softlink:", ex); 440 } 441 442 String tObj = null; 443 if(targetObj==null){ 444 tObj = targetObject.getEditor().getItem().toString(); 445 446 if (!tObj.startsWith(HObject.separator)) { 447 tObj = HObject.separator + tObj; 448 } 449 } 450 451 if ((targetObj instanceof Group) && ((Group) targetObj).isRoot()) { 452 toolkit.beep(); 453 JOptionPane.showMessageDialog(this, 454 "Cannot make a link to the root group.", getTitle(), 455 JOptionPane.ERROR_MESSAGE); 456 return null; 457 } 458 459 try { 460 if(targetObj !=null) 461 obj = fileFormat.createLink(pgroup, name, targetObj, Group.LINK_TYPE_SOFT); 462 else if(tObj!=null) 463 obj = fileFormat.createLink(pgroup, name, tObj, Group.LINK_TYPE_SOFT); 464 } 465 catch (Exception ex) { 466 ex.printStackTrace(); 467 toolkit.beep(); 468 JOptionPane.showMessageDialog(this, ex, getTitle(), 469 JOptionPane.ERROR_MESSAGE); 470 return null; 471 } 472 } 473 else if (externalLink.isSelected()){ 474 String TargetFileName = targetFile.getText(); 475 FileFormat TargetFileFormat = null; 476 int fileAccessID = FileFormat.FILE_CREATE_OPEN; 477 478 File TargetFile = new File(TargetFileName); 479 480 if (!TargetFile.exists()) { 481 return null; 482 } 483 FileFormat h5format = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5); 484 try { 485 //h5format.close(); 486 TargetFileFormat = h5format.createInstance(TargetFileName, fileAccessID); 487 TargetFileFormat.open(); //open the file 488 } 489 catch (Exception ex) { 490 log.debug("external link:", ex); 491 return null; 492 } 493 494 HObject targetObj = null; 495 try{ 496 targetObj = TargetFileFormat.get(targetObject.getEditor().getItem().toString()); 497 } 498 catch (Exception ex) { 499 ex.printStackTrace(); 500 } 501 502 try { 503 TargetFileFormat.close(); 504 } 505 catch (Exception ex) { 506 log.debug("external link:", ex); 507 } 508 509 String tFileObj = null; 510 if(targetObj==null){ 511 String tObj = null; 512 tObj = targetObject.getEditor().getItem().toString(); 513 if (tObj.length() < 1) { 514 toolkit.beep(); 515 JOptionPane.showMessageDialog(this, 516 "Target object name not specified.", getTitle(), 517 JOptionPane.ERROR_MESSAGE); 518 return null; 519 } 520 tFileObj = TargetFileName + FileFormat.FILE_OBJ_SEP + tObj; 521 } 522// should allow to link to the root of an external file 523// if ((targetObj instanceof Group) && ((Group) targetObj).isRoot()) { 524// toolkit.beep(); 525// JOptionPane.showMessageDialog(this, 526// "Cannot make a link to the root group.", getTitle(), 527// JOptionPane.ERROR_MESSAGE); 528// return null; 529// } 530 531 try { 532 if(targetObj !=null) 533 obj = fileFormat.createLink(pgroup, name, targetObj, Group.LINK_TYPE_EXTERNAL); 534 else if(tFileObj!=null) 535 obj = fileFormat.createLink(pgroup, name, tFileObj, Group.LINK_TYPE_EXTERNAL); 536 } 537 catch (Exception ex) { 538 ex.printStackTrace(); 539 toolkit.beep(); 540 JOptionPane.showMessageDialog(this, ex, getTitle(), 541 JOptionPane.ERROR_MESSAGE); 542 return null; 543 } 544 } 545 546 return obj; 547 } 548 549 /** 550 * Returns the new dataset created. 551 * 552 * @return The new Dataset created 553 */ 554 public DataFormat getObject() { 555 return newObject; 556 } 557 558 /** 559 * Returns the parent group of the new dataset. 560 * 561 * @return The parent group of the new Dataset 562 */ 563 public Group getParentGroup() { 564 return (Group) groupList.get(parentChoice.getSelectedIndex()); 565 } 566 567 public void changedUpdate(DocumentEvent arg0) { 568 } 569 570 public void insertUpdate(DocumentEvent e) { 571 targetObject.setEnabled(true); 572 getTargetFileObjs(); 573 } 574 575 public void removeUpdate(DocumentEvent arg0) { 576 targetObject.setEnabled(true); 577 getTargetFileObjs(); 578 } 579 580 //Retrieving objects from Target File. 581 private void getTargetFileObjs(){ 582 FileFormat fileFormatC = null; 583 int fileAccessID = FileFormat.FILE_CREATE_OPEN; 584 String filename = null; 585 filename = targetFile.getText(); 586 587 if (filename == null || filename.length()<1) { 588 return; 589 } 590 591 //Check if the target File is not the current file. 592 String CurrentFileName = fileFormat.getAbsolutePath(); 593 if(CurrentFileName.equals(filename)) 594 targetObject.setEnabled(false); 595 596 //Check if the target File is open in treeView 597 if (isFileOpen(filename)) { 598 return; 599 } 600 601 File choosedFile = new File(filename); 602 603 if (!choosedFile.exists()) { 604 targetObject.setEnabled(false); 605 return; 606 } 607 FileFormat h5format = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5); 608 try { 609 //h5format.close(); 610 fileFormatC = h5format.createInstance(filename, fileAccessID); 611 fileFormatC.open(); //open the file 612 613 } 614 catch (Exception ex) { 615 targetObject.setEnabled(false); 616 toolkit.beep(); 617 JOptionPane.showMessageDialog(this,"Invalid File Format", getTitle(), 618 JOptionPane.ERROR_MESSAGE); 619 return; 620 } 621 622 //getting the list of objects from the file:- 623 retriveObjects(fileFormatC); 624 625 try { 626 fileFormatC.close(); 627 } 628 catch (Exception ex) { 629 log.debug("FileFormat close:", ex); 630 } 631 } 632 633 //Function to check if the target File is open in treeView 634 private boolean isFileOpen(String filename) 635 { 636 boolean isOpen = false; 637 FileFormat theFile = null; 638 639 Iterator<?> iterator = fileList.iterator(); 640 while(iterator.hasNext()) { 641 theFile = (FileFormat)iterator.next(); 642 if (theFile.getFilePath().equals(filename)) { 643 isOpen = true; 644 if(!theFile.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))){ 645 targetObject.setEnabled(false); 646 } 647 retriveObjects(theFile); 648 break; 649 } 650 } // while(iterator.hasNext()) 651 652 return isOpen; 653 } 654 655 public void itemStateChanged(ItemEvent e) { 656 Object source = e.getSource(); 657 658 if (source instanceof JRadioButton) { 659 if (source.equals(hardLink) || source.equals(softLink) || source.equals(externalLink)) { 660 if (hardLink.isSelected()) { 661 targetFile.setEnabled(false); 662 targetFileButton.setEnabled(false); 663 targetObject.setEnabled(true); 664 targetObject.setEditable(false); 665 retriveObjects(fileFormat); 666 } 667 else if (softLink.isSelected()) { 668 targetFile.setEnabled(false); 669 targetFileButton.setEnabled(false); 670 targetObject.setEnabled(true); 671 targetObject.setEditable(true); 672 retriveObjects(fileFormat); 673 } 674 else if (externalLink.isSelected()) { 675 targetFile.setEnabled(true); 676 targetFileButton.setEnabled(true); 677 targetObject.setEnabled(true); 678 targetObject.setEditable(true); 679 targetObject.removeAllItems(); 680 } 681 } 682 } 683 } 684 685 //getting the list of objects from the file:- 686 private void retriveObjects(FileFormat file) { 687 List<Object> objsFile = breadthFirstUserObjects(file.getRootNode()); 688 List<HObject> groupListFile = new Vector<HObject>(objsFile.size()); 689 HObject obj = null; 690 Iterator<Object> iterator = objsFile.iterator(); 691 List<Object> objListFile = objsFile; 692 String full_name = null; 693 int idx_root = -1, idx = -1; 694 targetObject.removeAllItems(); 695 while (iterator.hasNext()) { 696 obj = (HObject) iterator.next(); 697 idx++; 698 699 if (obj instanceof Group) { 700 Group g = (Group) obj; 701 groupListFile.add(obj); 702 if (g.isRoot()) { 703 full_name = HObject.separator; 704 idx_root = idx; 705 } 706 else { 707 full_name = g.getPath() + g.getName() + HObject.separator; 708 } 709 } 710 else { 711 full_name = obj.getPath() + obj.getName(); 712 } 713 targetObject.addItem(full_name); 714 } 715 targetObject.removeItemAt(idx_root); 716 objListFile.remove(idx_root); 717 } 718 719} 720