Changeset 3899
- Timestamp:
- Oct 20, 2010, 1:10:39 PM (13 years ago)
- Location:
- trunk/client/servlet/src/org/proteios/action
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/servlet/src/org/proteios/action/directory/ViewActiveDirectory.java
r3888 r3899 1 1 /* 2 $Id$3 4 Copyright (C) 2006 Gregory Vincic5 Copyright (C) 2007 Gregory Vincic, Olle Mansson6 7 Files are copyright by their respective authors. The contributions to8 files where copyright is not explicitly stated can be traced with the9 source code revision system.10 11 This file is part of Proteios.12 Available at http://www.proteios.org/13 14 Proteios-2.x is free software; you can redistribute it and/or15 modify it under the terms of the GNU General Public License16 as published by the Free Software Foundation; either version 217 of the License, or (at your option) any later version.18 19 Proteios is distributed in the hope that it will be useful,20 but WITHOUT ANY WARRANTY; without even the implied warranty of21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the22 GNU General Public License for more details.23 24 You should have received a copy of the GNU General Public License25 along with this program; if not, write to the Free Software26 Foundation, Inc., 59 Temple Place - Suite 330,27 Boston, MA 02111-1307, USA.28 2 $Id$ 3 4 Copyright (C) 2006 Gregory Vincic 5 Copyright (C) 2007 Gregory Vincic, Olle Mansson 6 7 Files are copyright by their respective authors. The contributions to 8 files where copyright is not explicitly stated can be traced with the 9 source code revision system. 10 11 This file is part of Proteios. 12 Available at http://www.proteios.org/ 13 14 Proteios-2.x is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License 16 as published by the Free Software Foundation; either version 2 17 of the License, or (at your option) any later version. 18 19 Proteios is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 GNU General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place - Suite 330, 27 Boston, MA 02111-1307, USA. 28 */ 29 29 package org.proteios.action.directory; 30 30 … … 85 85 86 86 /** 87 * Displays properties of a Directory and the content of that directory.88 *89 * @author gregory90 87 * Displays properties of a Directory and the content of that directory. 88 * 89 * @author gregory 90 */ 91 91 public class ViewActiveDirectory 92 92 extends ProteiosAction<ViewActiveDirectory> 93 93 { 94 /** 95 * Session identifier for an active directory 96 */ 97 public static final VInteger VDIRID = new VInteger("active.dir.id", 1, true); 98 public static final VBoolean VSELECT = new VBoolean("select", true); 99 public static final VBoolean VSELECTMOVEDIR = new VBoolean( 100 "select.move.dir", false); 101 public static final VBoolean VMOVEFILESSTART = new VBoolean("moveFilesStart", false); 102 public static final VBoolean VMOVEFILES = new VBoolean("moveFiles", false); 103 public static final VBoolean VTABLEUPDATEBUTTONCLICKED = new VBoolean("tableUpdateButtonClicked", false); 104 105 106 /** 107 * Creates a layout for viewing/selecting the contents of a directory. The 108 * details of what the layout contains depends on Boolean flags transferred 109 * as valid parameters, that indicate the purpose of the directory listing. 110 * The general layout consists of a directory table and a file table. The 111 * directory table has two tabs, a 'contents' tab and a 'properties' tab. 112 * The directory 'contents' tab shows a list of sub-directories in the 113 * current directory, as well as a link to the parent directory. The file 114 * table shows a list of files in the current directory. The file table may 115 * be configured by the user via a popup window, and also has a filter row 116 * below the table header. 117 */ 118 @Override 119 protected void runMe() 120 throws ActionException, InvalidParameterValue 121 { 122 log.debug("Start"); 123 // Define 124 Boolean select, selectMoveDir, moveFilesStart, moveFilesMode = null; 125 String actionId; 126 DbControl dc; 127 Integer itemId, start, max; 128 ItemQuery<File> query; 129 Directory rootDir; 130 User user; 131 ItemFactory factory; 132 List<String> columnOrder; 133 Project activeP; 134 QueryFactory qf; 135 // 136 // Fetch table update button clicked flag 137 boolean tableUpdateButtonClicked = fetchTableUpdateButtonClickedFlag(); 138 log.debug("tableUpdateButtonClicked = " + tableUpdateButtonClicked); 139 // Create 140 // Check if user has selected file[s] in directory table to move 141 moveFilesStart = getValidBoolean(VMOVEFILESSTART); 142 if (moveFilesStart == null) 143 { 144 moveFilesStart = false; 145 log 146 .debug("Input moveFilesStart == null, reset to moveFilesStart = " + moveFilesStart); 147 } 148 log.debug("moveFilesStart = " + moveFilesStart); 149 if (moveFilesStart) 150 { 151 // Check input 152 List<Integer> tmpFileIds = getValidIntegerList(ItemIdField.VPARAM); 153 log.debug("tmpFileIds from ItemIdField.VPARAM for input check = " + tmpFileIds); 154 if (tmpFileIds != null && tmpFileIds.size() > 0) 155 { 156 setSessionAttribute(VSELECT, true); 157 setSessionAttribute(VSELECTMOVEDIR, true); 158 setSessionAttribute(VMOVEFILES, true); 159 setSessionAttribute(ForwardField.VPARAM, MoveFiles.class.getName()); 160 } 161 else 162 { 163 setError("Select at least one file to move"); 164 } 165 } 166 select = getSessionAttribute(VSELECT); 167 actionId = getSessionAttribute(ForwardField.VPARAM); 168 selectMoveDir = getSessionAttribute(VSELECTMOVEDIR); 169 moveFilesMode = getSessionAttribute(VMOVEFILES); 170 qf = getQueryFactory(); 171 dc = newDbControl(); 172 activeP = getActiveProject(dc); 173 // Use 174 if (selectMoveDir == null) 175 { 176 selectMoveDir = false; 177 log 178 .debug("Input selectMoveDir == null, reset to selectMoveDir = " + selectMoveDir); 179 } 180 if (moveFilesMode == null) 181 { 182 moveFilesMode = false; 183 log 184 .debug("Input moveFilesMode == null, reset to moveFilesMode = " + moveFilesMode); 185 } 186 log.debug("select = " + select + " selectMoveDir = " + selectMoveDir + " moveFilesMode = " + moveFilesMode); 187 /*********************************************************************** 188 * Create file table 189 */ 190 // A user clicked a directory 191 itemId = getSessionAttribute(ViewActiveDirectory.VDIRID); 192 if (itemId == null) 193 { 194 // No directory selected, first time 195 user = getOwner(); 196 dc.reattachItem(user); 197 rootDir = user.getHomeDirectory(); 198 } 199 else 200 { 201 factory = getItemFactory(dc); 202 rootDir = factory.getById(Directory.class, itemId); 203 } 204 // Query with parameters 205 query = rootDir.getFileQuery(); 206 start = 0; 207 max = 1000000000; 208 columnOrder = getValidStringList(ConfigureTableFactory2.VCOLUMNORDER); 209 // Use 210 setAttribute(ConfigureTableFactory2.VDATACLASS, FileData.class 211 .getName()); 212 setAttribute(ConfigureTableFactory2.VWRAPPERCLASS, File.class.getName()); 213 // Configure TableFactory2 214 ConfigureTableFactory2 confTF2 = new ConfigureTableFactory2(getOwner()); 215 confTF2.setExternalTableUpdateButtonClicked(tableUpdateButtonClicked); 216 TableFactory2 tableFactory2 = confTF2.configure(dc, File.class, 217 FileData.class, query, start, max, columnOrder, this, this 218 .getTableFactory2()); 219 // Create file table 220 Table fileTable = tableFactory2.build(); 221 // Add asPopup parameter to hide the menu in the next step. This is needed when the action is used 222 // in the wizard 223 if (getActionFactory().getAsPopup()) 224 { 225 TextField<Boolean> asPopup = new TextField<Boolean>( 226 ActionFactory.VPOPUP); 227 asPopup.setHidden(true); 228 asPopup.setValue(true); 229 fileTable.add(asPopup); 230 } 231 232 /** 233 * If in the top level of the project, add all files visible to the 234 * project, but which are not in an accessible directory 235 */ 236 if (activeP != null && activeP.getProjectDirectory() != null && activeP.getProjectDirectory().equals(rootDir)) 237 { 238 log.debug("Checking for exclude directories"); 239 query = qf.select(File.class); 240 query.exclude(Include.MINE); 241 query.include(Include.IN_PROJECT); 242 ItemQuery<Directory> dirQuery = qf.select(Directory.class); 243 dirQuery.exclude(Include.MINE); 244 dirQuery.include(Include.IN_PROJECT); 245 List<Directory> allDirs = dirQuery.list(dc); 246 // Specifically add the current dir so that files are not repeated 247 query.restrictPermanent(Restrictions.neq(Hql.property("directory"), 248 Hql.entity(rootDir))); 249 for (Directory currentDir : allDirs) 250 { 251 log.debug("Excluded dir: " + currentDir.getName()); 252 query.restrictPermanent(Restrictions.neq(Hql 253 .property("directory"), Hql.entity(currentDir))); 254 } 255 tableFactory2 = confTF2.configure(dc, File.class, FileData.class, 256 query, start, max, columnOrder, this, this.getTableFactory2()); 257 Table newTable = tableFactory2.build(); 258 for (Row r : newTable.getRows()) 259 { 260 r.getTags().add("shared"); 261 fileTable.addRow(r); 262 } 263 } 264 fileTable.setTitle("Files"); 265 // Only add file view action if no dedicated file selection 266 if (select == null || select) 267 { 268 /* 269 * Column actions are transferred to cells in rows, when the table 270 * is built. 271 */ 272 for (Row row : fileTable.getRows()) 273 { 274 for (Cell<?> cell : row.getCells()) 275 { 276 cell.setActionLink(null); 277 } 278 } 279 } 280 // 281 fileTable.add(new TextField<String>(ConfigureTableFactory2.VWRAPPERCLASS, File.class.getName())); 282 fileTable.add(new TextField<String>(ConfigureTableFactory2.VDATACLASS, FileData.class.getName())); 283 // Add query parameters 284 fileTable.add(new TextField<Integer>(ConfigureTableFactory2.VQUERYSTARTAT, start)); 285 // Set forward action 286 fileTable.add(new TextField<String>(ConfigureTableFactory2.VFORWARDTO, ViewActiveDirectory.class.getName())); 287 // Set this action as the table configuration action 288 fileTable.setConfigureTableAction(getActionFactory().getActionLink( 289 ConfigureTableFactory2.class, "")); 290 // We do not use the scroller when browsing for files 291 fileTable.setScroller(null); 292 // Add column order 293 List<Column> header = fileTable.getHeader(); 294 for (int i = 0; i < header.size(); i++) 295 { 296 AttributeDefinition ad = header.get(i).getAttributeDefinition(); 297 fileTable.add(new TextField<String>(ConfigureTableFactory2.VCOLUMNORDER, ad.getKey())); 298 } 299 // Add class name needed for delete action 300 fileTable.add(new TextField<String>(FormFactory.VCLASSNAME, File.class.getName())); 301 // Add optional form title 302 String formTitle = fetchFormTitle(select, selectMoveDir); 303 fileTable.add(new TitleField(formTitle)); 304 // Add optional special name for "Next" button 305 String nextButtonName = fetchNextButtonName(select, selectMoveDir); 306 fileTable.add(new NextButtonNameField(nextButtonName)); 307 // Use getRequest().getAttribute("table") in a 308 // subsequent action to get the created table. 309 // 310 // Add update button 311 Toolbar fileToolbar = new Toolbar(); 312 fileTable.setToolbar(fileToolbar); 313 ActionLink update = getActionFactory().getActionLink( 314 ViewActiveDirectory.class, "Update"); 315 update.addParameter(VTABLEUPDATEBUTTONCLICKED, true); 316 fileToolbar.add(update); 317 // 318 String path = rootDir.getPath().toString(); 319 fileTable.setTitle(fileTable.getTitle()); 320 // 321 ClassDescriptor wrapperDescriptor = new ClassDescriptor(File.class); 322 setAttribute("table", fileTable); 323 setAttribute("tableQuery", query); 324 setAttribute("header", header); 325 setAttribute("wrapperDescriptor", wrapperDescriptor); 326 /* 327 * Directory table 328 */ 329 // prependDirectories(fileTable, rootDir, select, selectMoveDir); 330 Table dirTable = createDirectoryTable(fileTable, rootDir, select, 331 selectMoveDir, moveFilesMode, moveFilesStart); 332 Toolbar dirToolbar = new Toolbar(); 333 dirTable.setToolbar(dirToolbar); 334 dirTable.add(new TextField<String>(ConfigureTableFactory2.VWRAPPERCLASS, Directory.class.getName())); 335 // We do not use the scroller when browsing for directories 336 dirTable.setScroller(null); 337 // 338 TabSet ts = null; 339 Title title = null; 340 /*********************************************************************** 341 * Directory content form 342 */ 343 if (select == null || select) 344 { 345 // Get optional special title for file selection form 346 formTitle = fetchFormTitle(select, selectMoveDir); 347 // Get optional special name for "Next" button 348 nextButtonName = fetchNextButtonName(select, selectMoveDir); 349 /* 350 * If selection is for directory to move file to, override above. 351 */ 352 if (selectMoveDir) 353 { 354 // Add button to directory table tool bar 355 // Remove default buttons 356 dirToolbar.list().clear(); 357 // dirToolbar.clear(); 358 // Add a possibly renamed "Next" button 359 ActionLink al = new ActionLink(nextButtonName, actionId); 360 dirToolbar.setDefaultAction(al); 361 dirToolbar.add(al); 362 /* 363 * Moving several files 364 */ 365 log.debug("moveFilesMode = " + moveFilesMode); 366 if (moveFilesMode) 367 { 368 /* 369 * This action may be called several times when 370 * navigating from the source to the target directory. 371 * First time the id values for selected files are 372 * stored in the default valid parameter VInteger ItemIdField.VPARAM, 373 * otherwise they are stored in valid parameter VInteger ViewActiveFile.VFILEID. 374 */ 375 List<Integer> tmpFileIds = null; 376 // Check if first time when navigating to target directory 377 if (moveFilesStart) 378 { 379 tmpFileIds = getValidIntegerList(ItemIdField.VPARAM); 380 log.debug("tmpFileIds from ItemIdField.VPARAM = " + tmpFileIds); 381 } 382 else 383 { 384 tmpFileIds = getValidIntegerList(ViewActiveFile.VFILEID); 385 log.debug("tmpFileIds from ViewActiveFile.VFILEID = " + tmpFileIds); 386 } 387 log.debug("tmpFileIds = " + tmpFileIds); 388 // Add id values for selected files as parameters to action link 389 if (tmpFileIds != null && tmpFileIds.size() > 0) 390 { 391 // Set id values for source files 392 for (Integer fileId : tmpFileIds) 393 { 394 getFormFactory().addHiddenField(dirTable, ViewActiveFile.VFILEID, fileId); 395 } 396 } 397 } 398 } 399 title = new Title(formTitle); 400 // Add button to file table tool bar 401 // Remove default buttons 402 fileToolbar.list().clear(); 403 fileToolbar.clear(); 404 // Add update button 405 fileToolbar.add(update); 406 // Add a possibly renamed "Next" button 407 ActionLink al = new ActionLink(nextButtonName, actionId); 408 // fileToolbar.setDefaultAction(al); 409 fileToolbar.setDefaultAction(update); 410 fileToolbar.add(al); 411 log.debug("(2) fileToolbar.getDefaultAction() = " + fileToolbar 412 .getDefaultAction()); 413 } 414 else 415 { 416 title = new Title("Files"); 417 // Simple browsing of the directory 418 // Button for new directory 419 ActionLink newDirectoryBtn = getActionFactory().getActionLink( 420 NewDirectory.class, "NewDirectory"); 421 dirToolbar.add(newDirectoryBtn); 422 // Button for deleting directory 423 ActionLink deleteDirectoryBtn = getActionFactory().getActionLink( 424 DeleteDirectory.class, "DeleteDirectory"); 425 dirToolbar.add(deleteDirectoryBtn); 426 // Add directory tool bar 427 dirTable.setToolbar(dirToolbar); 428 // Simple browsing of the directory 429 // Button for moving file[s] 430 ActionLink moveAction = getActionFactory().getActionLink( 431 ViewActiveDirectory.class, "Move"); 432 moveAction.addParameter(VMOVEFILESSTART, true); 433 fileToolbar.add(moveAction); 434 if (fileTable.getRows().size() == 0) 435 { 436 moveAction.disable(); 437 } 438 // Button for deleting file 439 ActionLink deleteAction = getActionFactory().getActionLink( 440 DeleteItems.class, "Delete"); 441 fileToolbar.add(deleteAction); 442 if (fileTable.getRows().size() == 0) 443 { 444 deleteAction.disable(); 445 } 446 // Button for sharing directory 447 PopupLink shareAction = new PopupLink(); 448 GUIElement<?> popupContent = ShareToProject.createPermissionForm(true); 449 shareAction.setContent(popupContent); 450 shareAction.setLabel("UseInProject"); 451 // Button for sharing file 452 PopupLink shareFileAction = new PopupLink(); 453 GUIElement<?> popupContent2 = ShareToProject.createPermissionForm(false); 454 shareFileAction.setContent(popupContent2); 455 shareFileAction.setLabel("UseInProject"); 456 457 if (dc.getSessionControl().getActiveProjectId() == 0) 458 { 459 shareAction.disable(); 460 shareFileAction.disable(); 461 } 462 dirToolbar.add(shareAction); 463 fileToolbar.add(shareFileAction); 464 // Button for uploading file 465 ActionLink upload = getActionFactory().getActionLink(NewFile.class, 466 "UploadFile"); 467 fileToolbar.add(upload); 468 // Button for uploading demo files 469 fileToolbar.add(getActionFactory().getActionLink( 470 UploadDemoFiles.class, "UploadDemoFiles")); 471 log.debug("(3) fileToolbar.getDefaultAction() = " + fileToolbar 472 .getDefaultAction()); 473 /******************************************************************* 474 * Directory content container 475 */ 476 RowContainer contentContainer = new RowContainer(); 477 contentContainer.add(dirTable); 478 contentContainer.add(fileTable); 479 /******************************************************************* 480 * Directory properties form 481 */ 482 Form propertiesForm = getFormFactory().getForm(Directory.class, 483 rootDir); 484 // Toolbar 485 Toolbar dirToolbar2 = new Toolbar(); 486 dirToolbar2.add(getActionFactory().getActionLink( 487 SaveDirectory.class, "Save")); 488 propertiesForm.setToolbar(dirToolbar2); 489 /******************************************************************* 490 * Directory extensions 491 */ 492 @SuppressWarnings("unused") 493 List<DirectoryContext> directoryContexts = getRegistry() 494 .getContexts(DirectoryContext.class); 495 if (directoryContexts == null) 496 { 497 log.debug("directoryContexts = null"); 498 } 499 else 500 { 501 log.debug("directoryContexts.size() = " + directoryContexts 502 .size()); 503 } 504 if (!directoryContexts.isEmpty()) 505 { 506 Table dirExtTable = new Table("dirExtensionsTable"); 507 List<Column> dirExtHeader = new ArrayList<Column>(2); 508 Column<String> name = new Column<String>("Name"); 509 dirExtHeader.add(name); 510 Column<String> description = new Column<String>("Description"); 511 dirExtHeader.add(description); 512 dirExtTable.setHeader(dirExtHeader); 513 int rowId = 0; 514 for (DirectoryContext context : directoryContexts) 515 { 516 rowId++; 517 Row row = new Row(rowId); 518 // Name column 519 log.debug("context.getLabel() = \"" + context.getLabel() + "\""); 520 Cell<String> nameCell = new Cell<String>(context.getLabel()); 521 AbstractLink link = context 522 .getActionLink(getActionFactory()); 523 // Link the extensions so that when one is selected the 524 // files table/form is posted to the given action. 525 CrossLink postTableLink = new CrossLink(dirTable, link); 526 nameCell.setActionLink(postTableLink); 527 row.addCell(nameCell); 528 // Description column 529 log.debug("context.getDescription() = \"" + context.getDescription() + "\""); 530 Cell<String> descCell = new Cell<String>(context.getDescription()); 531 descCell.setActionLink(postTableLink); 532 row.addCell(descCell); 533 // 534 dirExtTable.addRow(row); 535 } 536 PopupLink dirExtensions = new PopupLink(); 537 TitledWindow popup = new TitledWindow( 538 "ExtensionsForDirectories"); 539 popup.setStatic(false); 540 popup.setContent(dirExtTable); 541 dirExtensions.setLabel("ExtensionsForDirectories"); 542 dirExtensions.setContent(popup); 543 dirToolbar.add(dirExtensions); 544 } 545 /******************************************************************* 546 * File extensions 547 */ 548 @SuppressWarnings("unused") 549 List<FileContext> fileContexts = getRegistry().getContexts( 550 FileContext.class); 551 if (fileContexts == null) 552 { 553 log.debug("fileContexts = null"); 554 } 555 else 556 { 557 log.debug("fileContexts.size() = " + fileContexts.size()); 558 } 559 if (!fileContexts.isEmpty()) 560 { 561 Table fileExtTable = new Table("fileExtensionsTable"); 562 List<Column> fileExtHeader = new ArrayList<Column>(2); 563 Column<String> name = new Column<String>("Name"); 564 fileExtHeader.add(name); 565 Column<String> description = new Column<String>("Description"); 566 fileExtHeader.add(description); 567 fileExtTable.setHeader(fileExtHeader); 568 int rowId = 0; 569 for (FileContext context : fileContexts) 570 { 571 rowId++; 572 Row row = new Row(rowId); 573 // Name column 574 log.debug("context.getLabel() = \"" + context.getLabel() + "\""); 575 Cell<String> nameCell = new Cell<String>(context.getLabel()); 576 AbstractLink link = context 577 .getActionLink(getActionFactory()); 578 // Link the extensions so that when one is selected the 579 // files table/form is posted to the given action. 580 CrossLink postTableLink = new CrossLink(fileTable, link); 581 nameCell.setActionLink(postTableLink); 582 row.addCell(nameCell); 583 // Description column 584 log.debug("context.getDescription() = \"" + context.getDescription() + "\""); 585 Cell<String> descCell = new Cell<String>(context.getDescription()); 586 descCell.setActionLink(postTableLink); 587 row.addCell(descCell); 588 // 589 fileExtTable.addRow(row); 590 } 591 TitledWindow popup = new TitledWindow("ExtensionsForFiles"); 592 popup.setStatic(false); 593 popup.setContent(fileExtTable); 594 PopupLink fileExtensions = new PopupLink(); 595 fileExtensions.setLabel("ExtensionsForFiles"); 596 fileExtensions.setContent(popup); 597 fileToolbar.add(fileExtensions); 598 } 599 /******************************************************************* 600 * Tab set 601 */ 602 ts = new TabSet(); 603 // Content tab 604 Tab contentTab = new Tab("Content", "dirContent"); 605 contentTab.setGuiElement(contentContainer); 606 contentTab.setSelected(true); 607 ts.add(contentTab); 608 // Properties tab 609 Tab propertiesTab = new Tab("Properties", "dirProperties"); 610 propertiesTab.setGuiElement(propertiesForm); 611 ts.add(propertiesTab); 612 } 613 /*********************************************************************** 614 * Layout 615 */ 616 RowLayout layout = getLayoutFactory().getRowLayout(); 617 layout.add(title); 618 // Directory tab set 619 if (ts != null) 620 { 621 layout.add(ts); 622 } 623 else 624 { 625 if (selectMoveDir) 626 { 627 layout.add(dirTable); 628 } 629 else 630 { 631 layout.add(dirTable); 632 // Add file table 633 layout.add(fileTable); 634 } 635 } 636 // 637 setLayout(layout); 638 } 639 640 641 /** 642 * Obtains title for file/directory selection form from valid parameter. 643 * 644 * @param select Boolean Indicates file selection 645 * @param selectMoveDir Boolean Indicates directory selection 646 * @return String Title for file selection form 647 */ 648 @SuppressWarnings("unchecked") 649 private String fetchFormTitle(Boolean select, Boolean selectMoveDir) 650 { 651 String formTitle = null; 652 if (select == null || select) 653 { 654 // Get optional special title for file selection form 655 try 656 { 657 formTitle = getString(TitleField.VPARAM); 658 } 659 catch (InvalidParameterValue e) 660 {} 661 if (formTitle == null || formTitle.equals("")) 662 { 663 formTitle = getSessionAttribute(TitleField.VPARAM); 664 } 665 if (formTitle == null || formTitle.equals("")) 666 { 667 formTitle = new String("Select file[s]"); 668 } 669 // If selection is for directory to move file to, override above 670 if (selectMoveDir) 671 { 672 formTitle = new String("Move to target directory"); 673 } 674 } 675 return formTitle; 676 } 677 678 679 /** 680 * Obtains name for for "Next" button in file/directory selection form from 681 * valid parameter. 682 * 683 * @param select Boolean Indicates file selection 684 * @param selectMoveDir Boolean Indicates directory selection 685 * @return String Name for "Next" button in file selection form 686 */ 687 @SuppressWarnings("unchecked") 688 private String fetchNextButtonName(Boolean select, Boolean selectMoveDir) 689 { 690 String nextButtonName = null; 691 if (select == null || select) 692 { 693 // Get optional special name for "Next" button 694 try 695 { 696 nextButtonName = getString(NextButtonNameField.VPARAM); 697 } 698 catch (InvalidParameterValue e) 699 {} 700 if (nextButtonName == null || nextButtonName.equals("")) 701 { 702 nextButtonName = getSessionAttribute(NextButtonNameField.VPARAM); 703 } 704 if (nextButtonName == null || nextButtonName.equals("")) 705 { 706 nextButtonName = new String("Next"); 707 } 708 // If selection is for directory to move file to, override above 709 if (selectMoveDir) 710 { 711 nextButtonName = new String("Next"); 712 } 713 } 714 return nextButtonName; 715 } 716 717 718 /** 719 * Creates a directory table showing sub-directories in current directory, 720 * as well as a link to parent directory. The table columns are defined by 721 * the template table. 722 * 723 * @param templateTable Table Template table for selecting columns. 724 * @param dir Directory Source directory. 725 * @param select Boolean Flag indicating file selection mode. 726 * @param selectMoveDir Boolean Flag indicating directory selection mode 727 * (overrides file selection mode). 728 * @param moveFilesMode Boolean Flag indicating file batch move mode. 729 * @param moveFilesStart Boolean Flag indicating file batch move start. 730 * @return Table 731 */ 732 @SuppressWarnings("unchecked") 733 private Table createDirectoryTable(Table templateTable, Directory dir, 734 Boolean select, Boolean selectMoveDir, Boolean moveFilesMode, Boolean moveFilesStart) 735 { 736 // Define 737 ItemQuery<Directory> query; 738 TableFactory tfactory; 739 DbControl dc; 740 Project activeP; 741 QueryFactory qf; 742 String path = dir.getPath().toString(); 743 // Create 744 qf = getQueryFactory(); 745 dc = newDbControl(); 746 activeP = getActiveProject(dc); 747 tfactory = getTableFactory(); 748 tfactory.setDbControl(dc); 749 query = dir.getSubDirectories(); 750 if (activeP != null) 751 { 752 query.include(Include.IN_PROJECT); 753 } 754 tfactory.reset(); 755 tfactory.setDbControl(dir.getDbControl()); 756 tfactory.setItemClass(Directory.class); 757 tfactory.setQuery(query); 758 // Allow unlimited number of rows in table 759 tfactory.setMaxResults(0); 760 ActionLink clickAction = null; 761 if (select == null || select) 762 { 763 // Get optional special title for file selection form 764 String formTitle = fetchFormTitle(select, selectMoveDir); 765 // Get optional special name for "Next" button 766 String nextButtonName = fetchNextButtonName(select, selectMoveDir); 767 clickAction = getActionFactory().getActionLink(SelectFile.class, 768 "View"); 769 clickAction 770 .addParameter(TitleField.VPARAM, formTitle); 771 clickAction.addParameter(NextButtonNameField.VPARAM, 772 nextButtonName); 773 if (moveFilesMode) 774 { 775 /* 776 * This action may be called several times when 777 * navigating from the source to the target directory. 778 * First time the id values for selected files are 779 * stored in the default valid parameter VInteger ItemIdField.VPARAM, 780 * otherwise they are stored in valid parameter VInteger ViewActiveFile.VFILEID. 781 */ 782 List<Integer> tmpFileIds = null; 783 // Check if first time when navigating to target directory 784 if (moveFilesStart) 785 { 786 try 787 { 788 tmpFileIds = getValidIntegerList(ItemIdField.VPARAM); 789 } 790 catch (Exception e) 791 { 792 log.debug("Exception when trying to retrieve file id list from ItemIdField.VPARAM: " + e); 793 } 794 log.debug("tmpFileIds from ItemIdField.VPARAM = " + tmpFileIds); 795 } 796 else 797 { 798 try 799 { 800 tmpFileIds = getValidIntegerList(ViewActiveFile.VFILEID); 801 } 802 catch (Exception e) 803 { 804 log.debug("Exception when trying to retrieve file id list from ViewActiveFile.VFILEID: " + e); 805 } 806 log.debug("tmpFileIds from ViewActiveFile.VFILEID = " + tmpFileIds); 807 } 808 log.debug("tmpFileIds = " + tmpFileIds); 809 // Add id values for selected files as parameters to click action 810 if (tmpFileIds != null && tmpFileIds.size() > 0) 811 { 812 // Set id values for source files 813 for (Integer fileId : tmpFileIds) 814 { 815 clickAction.addParameter(ViewActiveFile.VFILEID, fileId); 816 } 817 } 818 } 819 } 820 else 821 { 822 clickAction = getActionFactory().getActionLink(ViewDirectory.class, 823 "View"); 824 } 825 tfactory.setColumnAction("Name", clickAction); 826 Table tmpTable = tfactory.build(); 827 /** 828 * If in the top level of the project, also show directories that are 829 * shared to the project, but originate in other projects 830 */ 831 if (activeP != null && activeP.getProjectDirectory().equals(dir)) 832 { 833 dir.getProjectKey(); 834 query = qf.select(Directory.class); 835 query.exclude(Include.MINE); 836 query.include(Include.IN_PROJECT); 837 List<Directory> allDirs = query.list(dc); 838 List<Integer> excludeDirs = new ArrayList<Integer>(); 839 boolean use = false; 840 // Only list the top directories, do not include the current dir or 841 // directories with it as parent 842 for (Directory currentDir : allDirs) 843 { 844 if (!allDirs.contains(currentDir.getParent()) && !currentDir 845 .equals(dir) && !currentDir.getParent().equals(dir)) 846 { 847 log.debug("Included dir: " + currentDir.getName()); 848 use = true; 849 } 850 else 851 { 852 excludeDirs.add(currentDir.getId()); 853 log.debug("Excluded dir: " + currentDir.getName()); 854 } 855 } 856 query.reset(); 857 // Add directories if there are any 858 if (use) 859 { 860 for (Integer id : excludeDirs) 861 { 862 query.restrict(Restrictions.neq(Hql.property("id"), 863 Expressions.integer(id.intValue()))); 864 } 865 tfactory.setQuery(query); 866 Table tabletop = tfactory.build(); 867 for (Row r : tabletop.getRows()) 868 { 869 r.getTags().add("shared"); 870 } 871 // Merge the tables 872 for (Row r : tmpTable.getRows()) 873 { 874 tabletop.addRow(r); 875 } 876 tmpTable = tabletop; 877 } 878 } 879 // Create adapted directory table 880 Table table = new Table("DirectoryTable"); 881 // Set title explicitly, to get correct plural for "Directory" 882 table.setTitle("Directory"); 883 table.setSubtitle(path); 884 // Adapt header to template table 885 /* 886 * Simply using the template header, 887 * table.setHeader(templateTable.getHeader()); would work if the latter 888 * did not include an appended filter row. 889 */ 890 List<Column> adaptedHeader = adaptTableHeader(0, templateTable, 891 tmpTable); 892 table.setHeader(adaptedHeader); 893 // Adapt directory table data to template table 894 for (Row row : tmpTable.getRows()) 895 { 896 // Clear checkbox if navigating to target directory 897 if (selectMoveDir != null && selectMoveDir) 898 { 899 row.getCells().get(0).setValue(null); 900 } 901 // Add slash to directory names 902 Cell nameCell = row.getCells().get(1); 903 String dirName = (String) nameCell.getValue(); 904 nameCell.setValue(dirName + "/"); 905 // For column 2 and upwards, add empty cells if necessary. 906 // row = adaptTableRow(row, 2, templateTable, tmpTable); 907 row = adaptTableRow(row, 2, templateTable, tmpTable); 908 table.getRows().add(0, row); 909 } 910 Directory parentDir = dir.getParent(); 911 if (!dir.isRootDirectory() && parentDir != null && !parentDir 912 .isRootDirectory()) 913 { 914 // Prepend parent directory row 915 Row parentDirRow = tfactory.createRow(parentDir); 916 // Clear checkbox 917 parentDirRow.getCells().get(0).setValue(null); 918 // Add slash to directory names 919 Cell nameCell = parentDirRow.getCells().get(1); 920 nameCell.setValue("../"); 921 // For column 2 and upwards, add empty cells if necessary. 922 // parentDirRow = adaptTableRow(parentDirRow, 2, templateTable, 923 // tmpTable); 924 parentDirRow = adaptTableRow(parentDirRow, 2, templateTable, 925 tmpTable); 926 table.getRows().add(0, parentDirRow); 927 } 928 return table; 929 } 930 931 932 /** 933 * Adapts a table header for source items so it fits in a table for template 934 * items. The tables for source and template items are used to find what 935 * cells in the source row are applicable in the template table. This is 936 * done by checking the names for each column. A column in the template 937 * table that has a corresponding column in the source table will have the 938 * source cell inserted, otherwise an empty cell. Columns unique to the 939 * source table will not trigger insertion of a cell. 940 * 941 * @param startIndex int Index for first column to check 942 * @param templateTable Table Table for template items 943 * @param sourceTable Table Table for source items 944 * @return List<Column> Output header for source item, modified to fit into 945 * template table. 946 */ 947 @SuppressWarnings("unchecked") 948 private List<Column> adaptTableHeader(int startIndex, Table templateTable, 949 Table sourceTable) 950 { 951 if (startIndex >= templateTable.getHeader().size()) 952 { 953 // No columns to adapt, return input header. 954 return sourceTable.getHeader(); 955 } 956 /* 957 * Get hash table of column names and column indices in source table. 958 */ 959 Hashtable<String, Integer> sourceColumnNameHashtable = new Hashtable<String, Integer>( 960 0); 961 for (int i = startIndex; i < sourceTable.getHeader().size(); i++) 962 { 963 Column srcc = sourceTable.getHeader().get(i); 964 String sourceColumnName = srcc.getValue(); 965 if (sourceColumnName != null) 966 { 967 // Add source column name to hash table. 968 sourceColumnNameHashtable.put(sourceColumnName, new Integer(i)); 969 log 970 .debug("i = " + i + " sourceColumnNameHashtable.get(" + sourceColumnName + ").intValue() = " + sourceColumnNameHashtable 971 .get(sourceColumnName).intValue()); 972 } 973 } 974 /* 975 * For column startIndex and upwards, only keep source columns for 976 * columns existing in both source and template tables. Add empty 977 * columns for columns unique to template table. 978 */ 979 Table tmpTable = new Table("TemporaryTable"); 980 // Add columns up to startIndex. 981 for (int i = 0; i < startIndex; i++) 982 { 983 Column column = sourceTable.getHeader().get(i); 984 tmpTable.add(column); 985 log 986 .debug("i = " + i + " column \"" + column.getValue() + "\" copied."); 987 } 988 /* 989 * For column startIndex and upwards, add empty columns if necessary. 990 */ 991 for (int i = startIndex; i < templateTable.getHeader().size(); i++) 992 { 993 Column c = templateTable.getHeader().get(i); 994 // Only add visible columns in template table 995 if (!c.isVisible()) 996 { 997 continue; 998 } 999 // Check if corresponding source table column exists, if any. 1000 String templateColumnName = c.getValue(); 1001 if (sourceColumnNameHashtable.containsKey(templateColumnName)) 1002 { 1003 // Source table column OK 1004 int sourceColumnIndex = sourceColumnNameHashtable.get( 1005 templateColumnName).intValue(); 1006 Column column = sourceTable.getHeader().get(sourceColumnIndex); 1007 // If initial Id column, remove column name 1008 if (i == 0 && column.getValue().equals("Id")) 1009 { 1010 column.setValue(""); 1011 } 1012 tmpTable.add(column); 1013 log 1014 .debug("i = " + i + " templateColumnName = \"" + templateColumnName + "\" column \"" + column 1015 .getValue() + "\" inserted."); 1016 } 1017 else 1018 { 1019 // Add new column for template column not in source table 1020 Column column = new Column(templateColumnName); 1021 // If initial Id column, remove column name 1022 if (i == 0 && column.getValue().equals("Id")) 1023 { 1024 column.setValue(""); 1025 } 1026 tmpTable.add(column); 1027 log 1028 .debug("i = " + i + " templateColumnName = \"" + templateColumnName + "\" new column \"" + column 1029 .getValue() + "\" inserted."); 1030 } 1031 } 1032 // Return adapted source header. 1033 return tmpTable.getHeader(); 1034 } 1035 1036 1037 /** 1038 * Adapts a table row for source items so it fits in a table for template 1039 * items. The tables for source and template items are used to find what 1040 * cells in the source row are applicable in the template table. This is 1041 * done by checking the names for each column. A column in the template 1042 * table that has a corresponding column in the source table will have the 1043 * source cell inserted, otherwise an empty cell. Columns unique to the 1044 * source table will not trigger insertion of a cell. 1045 * 1046 * @param row Row Input row from source table to be adapted. 1047 * @param startIndex int Index for first column to check 1048 * @param templateTable Table Table for template items 1049 * @param sourceTable Table Table for source items 1050 * @return Row Output row for source item, modified to fit into template 1051 * table. 1052 */ 1053 @SuppressWarnings("unchecked") 1054 private Row adaptTableRow(Row row, int startIndex, Table templateTable, 1055 Table sourceTable) 1056 { 1057 if (startIndex >= row.getCells().size()) 1058 { 1059 // No cells to adapt, return input row. 1060 return row; 1061 } 1062 /* 1063 * Get hash table of column names and column indices in source table. 1064 */ 1065 Hashtable<String, Integer> sourceColumnNameHashtable = new Hashtable<String, Integer>( 1066 0); 1067 for (int i = startIndex; i < sourceTable.getHeader().size(); i++) 1068 { 1069 Column srcc = sourceTable.getHeader().get(i); 1070 String sourceColumnName = srcc.getValue(); 1071 if (sourceColumnName != null) 1072 { 1073 // Add source column name to hash table. 1074 sourceColumnNameHashtable.put(sourceColumnName, new Integer(i)); 1075 log 1076 .debug("i = " + i + " sourceColumnNameHashtable.get(" + sourceColumnName + ").intValue() = " + sourceColumnNameHashtable 1077 .get(sourceColumnName).intValue()); 1078 } 1079 } 1080 /* 1081 * For column startIndex and upwards, only keep source cells for columns 1082 * existing in both source and template tables. Add empty cells for 1083 * columns unique to template table. 1084 */ 1085 ArrayList<Cell<?>> cellList = new ArrayList<Cell<?>>(0); 1086 // Add cells up to startIndex. 1087 for (int i = 0; i < startIndex; i++) 1088 { 1089 Cell<?> cell = row.getCells().get(i); 1090 cellList.add(cell); 1091 log 1092 .debug("New row i = " + i + " cell value \"" + cell.getValue() + "\" copied."); 1093 } 1094 /* 1095 * For column startIndex and upwards, add empty cells if necessary. 1096 */ 1097 Cell emptyCell = new Cell<String>(null); 1098 for (int i = startIndex; i < templateTable.getHeader().size(); i++) 1099 { 1100 Column c = templateTable.getHeader().get(i); 1101 // Only add visible columns in template table 1102 if (!c.isVisible()) 1103 { 1104 continue; 1105 } 1106 // Check if corresponding source table cell exists, if any. 1107 String templateColumnName = c.getValue(); 1108 if (sourceColumnNameHashtable.containsKey(templateColumnName)) 1109 { 1110 // Source table cell OK 1111 int sourceCellIndex = sourceColumnNameHashtable.get( 1112 templateColumnName).intValue(); 1113 Cell<?> cell = row.getCells().get(sourceCellIndex); 1114 cellList.add(cell); 1115 log 1116 .debug("New row i = " + i + " templateColumnName = \"" + templateColumnName + "\" cell value \"" + cell 1117 .getValue() + "\" inserted."); 1118 } 1119 else 1120 { 1121 // Add empty cell for template column not in source table 1122 cellList.add(emptyCell); 1123 log 1124 .debug("New row i = " + i + " templateColumnName = \"" + templateColumnName + "\" empty cell inserted."); 1125 } 1126 } 1127 // Construct adapted source row. 1128 row.setCells(cellList); 1129 return row; 1130 } 1131 1132 1133 /** 1134 * Convenience method for fetching the 1135 * table update button clicked flag. 1136 * 1137 * @return boolean The table update button clicked flag. 1138 */ 1139 private boolean fetchTableUpdateButtonClickedFlag() 1140 { 1141 // Get table update button clicked flag 1142 boolean tableUpdateButtonClicked = false; 1143 Boolean tableUpdateButtonClickedFlagFromRequest = false; 1144 try 1145 { 1146 tableUpdateButtonClickedFlagFromRequest = getValidBoolean(VTABLEUPDATEBUTTONCLICKED); 1147 if (tableUpdateButtonClickedFlagFromRequest == null) 1148 { 1149 tableUpdateButtonClicked = false; 1150 } 1151 else 1152 { 1153 tableUpdateButtonClicked = tableUpdateButtonClickedFlagFromRequest; 1154 } 1155 } 1156 catch (Exception e) 1157 { 1158 log.debug("Exception when trying to get valid parameter VTABLEUPDATEBUTTONCLICKED: " + e); 1159 } 1160 log.debug("tableUpdateButtonClickedFlagFromRequest = " + tableUpdateButtonClickedFlagFromRequest + " tableUpdateButtonClicked = " + tableUpdateButtonClicked); 1161 // 1162 log.debug("tableUpdateButtonClicked = " + tableUpdateButtonClicked); 1163 return tableUpdateButtonClicked; 1164 } 94 /** 95 * Session identifier for an active directory 96 */ 97 public static final VInteger VDIRID = new VInteger("active.dir.id", 1, true); 98 public static final VBoolean VSELECT = new VBoolean("select", true); 99 public static final VBoolean VSELECTMOVEDIR = new VBoolean( 100 "select.move.dir", false); 101 public static final VBoolean VMOVEFILESSTART = new VBoolean("moveFilesStart", false); 102 public static final VBoolean VMOVEFILES = new VBoolean("moveFiles", false); 103 public static final VBoolean VTABLEUPDATEBUTTONCLICKED = new VBoolean("tableUpdateButtonClicked", false); 104 105 /** 106 * Creates a layout for viewing/selecting the contents of a directory. The 107 * details of what the layout contains depends on Boolean flags transferred 108 * as valid parameters, that indicate the purpose of the directory listing. 109 * The general layout consists of a directory table and a file table. The 110 * directory table has two tabs, a 'contents' tab and a 'properties' tab. 111 * The directory 'contents' tab shows a list of sub-directories in the 112 * current directory, as well as a link to the parent directory. The file 113 * table shows a list of files in the current directory. The file table may 114 * be configured by the user via a popup window, and also has a filter row 115 * below the table header. 116 */ 117 @Override 118 protected void runMe() 119 throws ActionException, InvalidParameterValue 120 { 121 log.debug("Start"); 122 // Define 123 Boolean select, selectMoveDir, moveFilesStart, moveFilesMode = null; 124 String actionId; 125 DbControl dc; 126 Integer itemId, start, max; 127 ItemQuery<File> query; 128 Directory rootDir; 129 User user; 130 ItemFactory factory; 131 List<String> columnOrder; 132 Project activeP; 133 QueryFactory qf; 134 // 135 // Fetch table update button clicked flag 136 boolean tableUpdateButtonClicked = fetchTableUpdateButtonClickedFlag(); 137 log.debug("tableUpdateButtonClicked = " + tableUpdateButtonClicked); 138 // Create 139 // Check if user has selected file[s] in directory table to move 140 moveFilesStart = getValidBoolean(VMOVEFILESSTART); 141 if (moveFilesStart == null) 142 { 143 moveFilesStart = false; 144 log 145 .debug("Input moveFilesStart == null, reset to moveFilesStart = " + moveFilesStart); 146 } 147 log.debug("moveFilesStart = " + moveFilesStart); 148 if (moveFilesStart) 149 { 150 // Check input 151 List<Integer> tmpFileIds = getValidIntegerList(ItemIdField.VPARAM); 152 log.debug("tmpFileIds from ItemIdField.VPARAM for input check = " + tmpFileIds); 153 if (tmpFileIds != null && tmpFileIds.size() > 0) 154 { 155 setSessionAttribute(VSELECT, true); 156 setSessionAttribute(VSELECTMOVEDIR, true); 157 setSessionAttribute(VMOVEFILES, true); 158 setSessionAttribute(ForwardField.VPARAM, MoveFiles.class.getName()); 159 } 160 else 161 { 162 setError("Select at least one file to move"); 163 } 164 } 165 select = getSessionAttribute(VSELECT); 166 actionId = getSessionAttribute(ForwardField.VPARAM); 167 selectMoveDir = getSessionAttribute(VSELECTMOVEDIR); 168 moveFilesMode = getSessionAttribute(VMOVEFILES); 169 qf = getQueryFactory(); 170 dc = newDbControl(); 171 activeP = getActiveProject(dc); 172 // Use 173 if (selectMoveDir == null) 174 { 175 selectMoveDir = false; 176 log 177 .debug("Input selectMoveDir == null, reset to selectMoveDir = " + selectMoveDir); 178 } 179 if (moveFilesMode == null) 180 { 181 moveFilesMode = false; 182 log 183 .debug("Input moveFilesMode == null, reset to moveFilesMode = " + moveFilesMode); 184 } 185 log.debug("select = " + select + " selectMoveDir = " + selectMoveDir + " moveFilesMode = " + moveFilesMode); 186 /*********************************************************************** 187 * Create file table 188 */ 189 // A user clicked a directory 190 itemId = getSessionAttribute(ViewActiveDirectory.VDIRID); 191 if (itemId == null) 192 { 193 // No directory selected, first time 194 user = getOwner(); 195 dc.reattachItem(user); 196 rootDir = user.getHomeDirectory(); 197 } 198 else 199 { 200 factory = getItemFactory(dc); 201 rootDir = factory.getById(Directory.class, itemId); 202 } 203 // Query with parameters 204 query = rootDir.getFileQuery(); 205 start = 0; 206 max = 1000000000; 207 columnOrder = getValidStringList(ConfigureTableFactory2.VCOLUMNORDER); 208 // Use 209 setAttribute(ConfigureTableFactory2.VDATACLASS, FileData.class 210 .getName()); 211 setAttribute(ConfigureTableFactory2.VWRAPPERCLASS, File.class.getName()); 212 // Configure TableFactory2 213 ConfigureTableFactory2 confTF2 = new ConfigureTableFactory2(getOwner()); 214 confTF2.setExternalTableUpdateButtonClicked(tableUpdateButtonClicked); 215 TableFactory2 tableFactory2 = confTF2.configure(dc, File.class, 216 FileData.class, query, start, max, columnOrder, this, this 217 .getTableFactory2()); 218 // Create file table 219 Table fileTable = tableFactory2.build(); 220 // Add asPopup parameter to hide the menu in the next step. This is needed when the action is used 221 // in the wizard 222 if (getActionFactory().getAsPopup()) 223 { 224 TextField<Boolean> asPopup = new TextField<Boolean>( 225 ActionFactory.VPOPUP); 226 asPopup.setHidden(true); 227 asPopup.setValue(true); 228 fileTable.add(asPopup); 229 } 230 231 /** 232 * If in the top level of the project, add all files visible to the 233 * project, but which are not in an accessible directory 234 */ 235 if (activeP != null && activeP.getProjectDirectory() != null && activeP.getProjectDirectory().equals(rootDir)) 236 { 237 log.debug("Checking for exclude directories"); 238 query = qf.select(File.class); 239 query.exclude(Include.MINE); 240 query.include(Include.IN_PROJECT); 241 ItemQuery<Directory> dirQuery = qf.select(Directory.class); 242 dirQuery.exclude(Include.MINE); 243 dirQuery.include(Include.IN_PROJECT); 244 List<Directory> allDirs = dirQuery.list(dc); 245 // Specifically add the current dir so that files are not repeated 246 query.restrictPermanent(Restrictions.neq(Hql.property("directory"), 247 Hql.entity(rootDir))); 248 for (Directory currentDir : allDirs) 249 { 250 log.debug("Excluded dir: " + currentDir.getName()); 251 query.restrictPermanent(Restrictions.neq(Hql 252 .property("directory"), Hql.entity(currentDir))); 253 } 254 tableFactory2 = confTF2.configure(dc, File.class, FileData.class, 255 query, start, max, columnOrder, this, this.getTableFactory2()); 256 Table newTable = tableFactory2.build(); 257 for (Row r : newTable.getRows()) 258 { 259 r.getTags().add("shared"); 260 fileTable.addRow(r); 261 } 262 } 263 fileTable.setTitle("Files"); 264 // Only add file view action if no dedicated file selection 265 if (select == null || select) 266 { 267 /* 268 * Column actions are transferred to cells in rows, when the table 269 * is built. 270 */ 271 for (Row row : fileTable.getRows()) 272 { 273 for (Cell<?> cell : row.getCells()) 274 { 275 cell.setActionLink(null); 276 } 277 } 278 } 279 // 280 fileTable.add(new TextField<String>(ConfigureTableFactory2.VWRAPPERCLASS, File.class.getName())); 281 fileTable.add(new TextField<String>(ConfigureTableFactory2.VDATACLASS, FileData.class.getName())); 282 // Add query parameters 283 fileTable.add(new TextField<Integer>(ConfigureTableFactory2.VQUERYSTARTAT, start)); 284 // Set forward action 285 fileTable.add(new TextField<String>(ConfigureTableFactory2.VFORWARDTO, ViewActiveDirectory.class.getName())); 286 // Set this action as the table configuration action 287 fileTable.setConfigureTableAction(getActionFactory().getActionLink( 288 ConfigureTableFactory2.class, "")); 289 // We do not use the scroller when browsing for files 290 fileTable.setScroller(null); 291 // Add column order 292 List<Column> header = fileTable.getHeader(); 293 for (int i = 0; i < header.size(); i++) 294 { 295 AttributeDefinition ad = header.get(i).getAttributeDefinition(); 296 fileTable.add(new TextField<String>(ConfigureTableFactory2.VCOLUMNORDER, ad.getKey())); 297 } 298 // Add class name needed for delete action 299 fileTable.add(new TextField<String>(FormFactory.VCLASSNAME, File.class.getName())); 300 // Add optional form title 301 String formTitle = fetchFormTitle(select, selectMoveDir); 302 fileTable.add(new TitleField(formTitle)); 303 // Add optional special name for "Next" button 304 String nextButtonName = fetchNextButtonName(select, selectMoveDir); 305 fileTable.add(new NextButtonNameField(nextButtonName)); 306 // Use getRequest().getAttribute("table") in a 307 // subsequent action to get the created table. 308 // 309 // Add update button 310 Toolbar fileToolbar = new Toolbar(); 311 fileTable.setToolbar(fileToolbar); 312 ActionLink update = getActionFactory().getActionLink( 313 ViewActiveDirectory.class, "Update"); 314 update.addParameter(VTABLEUPDATEBUTTONCLICKED, true); 315 fileToolbar.add(update); 316 // 317 String path = rootDir.getPath().toString(); 318 fileTable.setTitle(fileTable.getTitle()); 319 // 320 ClassDescriptor wrapperDescriptor = new ClassDescriptor(File.class); 321 setAttribute("table", fileTable); 322 setAttribute("tableQuery", query); 323 setAttribute("header", header); 324 setAttribute("wrapperDescriptor", wrapperDescriptor); 325 /* 326 * Directory table 327 */ 328 // prependDirectories(fileTable, rootDir, select, selectMoveDir); 329 Table dirTable = createDirectoryTable(fileTable, rootDir, select, 330 selectMoveDir, moveFilesMode, moveFilesStart); 331 Toolbar dirToolbar = new Toolbar(); 332 dirTable.setToolbar(dirToolbar); 333 dirTable.add(new TextField<String>(ConfigureTableFactory2.VWRAPPERCLASS, Directory.class.getName())); 334 // We do not use the scroller when browsing for directories 335 dirTable.setScroller(null); 336 // 337 TabSet ts = null; 338 Title title = null; 339 /*********************************************************************** 340 * Directory content form 341 */ 342 if (select == null || select) 343 { 344 // Get optional special title for file selection form 345 formTitle = fetchFormTitle(select, selectMoveDir); 346 // Get optional special name for "Next" button 347 nextButtonName = fetchNextButtonName(select, selectMoveDir); 348 /* 349 * If selection is for directory to move file to, override above. 350 */ 351 if (selectMoveDir) 352 { 353 // Add button to directory table tool bar 354 // Remove default buttons 355 dirToolbar.list().clear(); 356 // dirToolbar.clear(); 357 // Add a possibly renamed "Next" button 358 ActionLink al = new ActionLink(nextButtonName, actionId); 359 dirToolbar.setDefaultAction(al); 360 dirToolbar.add(al); 361 /* 362 * Moving several files 363 */ 364 log.debug("moveFilesMode = " + moveFilesMode); 365 if (moveFilesMode) 366 { 367 /* 368 * This action may be called several times when 369 * navigating from the source to the target directory. 370 * First time the id values for selected files are 371 * stored in the default valid parameter VInteger ItemIdField.VPARAM, 372 * otherwise they are stored in valid parameter VInteger ViewActiveFile.VFILEID. 373 */ 374 List<Integer> tmpFileIds = null; 375 // Check if first time when navigating to target directory 376 if (moveFilesStart) 377 { 378 tmpFileIds = getValidIntegerList(ItemIdField.VPARAM); 379 log.debug("tmpFileIds from ItemIdField.VPARAM = " + tmpFileIds); 380 } 381 else 382 { 383 tmpFileIds = getValidIntegerList(ViewActiveFile.VFILEID); 384 log.debug("tmpFileIds from ViewActiveFile.VFILEID = " + tmpFileIds); 385 } 386 log.debug("tmpFileIds = " + tmpFileIds); 387 // Add id values for selected files as parameters to action link 388 if (tmpFileIds != null && tmpFileIds.size() > 0) 389 { 390 // Set id values for source files 391 for (Integer fileId : tmpFileIds) 392 { 393 getFormFactory().addHiddenField(dirTable, ViewActiveFile.VFILEID, fileId); 394 } 395 } 396 } 397 } 398 title = new Title(formTitle); 399 // Add button to file table tool bar 400 // Remove default buttons 401 fileToolbar.list().clear(); 402 fileToolbar.clear(); 403 // Add update button 404 fileToolbar.add(update); 405 // Add a possibly renamed "Next" button 406 ActionLink al = new ActionLink(nextButtonName, actionId); 407 // fileToolbar.setDefaultAction(al); 408 fileToolbar.setDefaultAction(update); 409 fileToolbar.add(al); 410 log.debug("(2) fileToolbar.getDefaultAction() = " + fileToolbar 411 .getDefaultAction()); 412 } 413 else 414 { 415 title = new Title("Files"); 416 // Simple browsing of the directory 417 // Button for new directory 418 ActionLink newDirectoryBtn = getActionFactory().getActionLink( 419 NewDirectory.class, "NewDirectory"); 420 dirToolbar.add(newDirectoryBtn); 421 // Button for deleting directory 422 ActionLink deleteDirectoryBtn = getActionFactory().getActionLink( 423 DeleteDirectory.class, "DeleteDirectory"); 424 dirToolbar.add(deleteDirectoryBtn); 425 // Add directory tool bar 426 dirTable.setToolbar(dirToolbar); 427 // Simple browsing of the directory 428 // Button for moving file[s] 429 ActionLink moveAction = getActionFactory().getActionLink( 430 ViewActiveDirectory.class, "Move"); 431 moveAction.addParameter(VMOVEFILESSTART, true); 432 fileToolbar.add(moveAction); 433 if (fileTable.getRows().size() == 0) 434 { 435 moveAction.disable(); 436 } 437 // Button for deleting file 438 ActionLink deleteAction = getActionFactory().getActionLink( 439 DeleteItems.class, "Delete"); 440 fileToolbar.add(deleteAction); 441 if (fileTable.getRows().size() == 0) 442 { 443 deleteAction.disable(); 444 } 445 // Button for sharing directory 446 PopupLink shareAction = new PopupLink(); 447 GUIElement<?> popupContent = ShareToProject.createPermissionForm(true); 448 shareAction.setContent(popupContent); 449 shareAction.setLabel("UseInProject"); 450 // Button for sharing file 451 PopupLink shareFileAction = new PopupLink(); 452 GUIElement<?> popupContent2 = ShareToProject.createPermissionForm(false); 453 shareFileAction.setContent(popupContent2); 454 shareFileAction.setLabel("UseInProject"); 455 456 if (dc.getSessionControl().getActiveProjectId() == 0) 457 { 458 shareAction.disable(); 459 shareFileAction.disable(); 460 } 461 dirToolbar.add(shareAction); 462 fileToolbar.add(shareFileAction); 463 // Button for uploading file 464 ActionLink upload = getActionFactory().getActionLink(NewFile.class, 465 "UploadFile"); 466 fileToolbar.add(upload); 467 log.debug("(3) fileToolbar.getDefaultAction() = " + fileToolbar 468 .getDefaultAction()); 469 /******************************************************************* 470 * Directory content container 471 */ 472 RowContainer contentContainer = new RowContainer(); 473 contentContainer.add(dirTable); 474 contentContainer.add(fileTable); 475 /******************************************************************* 476 * Directory properties form 477 */ 478 Form propertiesForm = getFormFactory().getForm(Directory.class, 479 rootDir); 480 // Toolbar 481 Toolbar dirToolbar2 = new Toolbar(); 482 dirToolbar2.add(getActionFactory().getActionLink( 483 SaveDirectory.class, "Save")); 484 propertiesForm.setToolbar(dirToolbar2); 485 /******************************************************************* 486 * Directory extensions 487 */ 488 @SuppressWarnings("unused") 489 List<DirectoryContext> directoryContexts = getRegistry() 490 .getContexts(DirectoryContext.class); 491 if (directoryContexts == null) 492 { 493 log.debug("directoryContexts = null"); 494 } 495 else 496 { 497 log.debug("directoryContexts.size() = " + directoryContexts 498 .size()); 499 } 500 if (!directoryContexts.isEmpty()) 501 { 502 Table dirExtTable = new Table("dirExtensionsTable"); 503 List<Column> dirExtHeader = new ArrayList<Column>(2); 504 Column<String> name = new Column<String>("Name"); 505 dirExtHeader.add(name); 506 Column<String> description = new Column<String>("Description"); 507 dirExtHeader.add(description); 508 dirExtTable.setHeader(dirExtHeader); 509 int rowId = 0; 510 for (DirectoryContext context : directoryContexts) 511 { 512 rowId++; 513 Row row = new Row(rowId); 514 // Name column 515 log.debug("context.getLabel() = \"" + context.getLabel() + "\""); 516 Cell<String> nameCell = new Cell<String>(context.getLabel()); 517 AbstractLink link = context 518 .getActionLink(getActionFactory()); 519 // Link the extensions so that when one is selected the 520 // files table/form is posted to the given action. 521 CrossLink postTableLink = new CrossLink(dirTable, link); 522 nameCell.setActionLink(postTableLink); 523 row.addCell(nameCell); 524 // Description column 525 log.debug("context.getDescription() = \"" + context.getDescription() + "\""); 526 Cell<String> descCell = new Cell<String>(context.getDescription()); 527 descCell.setActionLink(postTableLink); 528 row.addCell(descCell); 529 // 530 dirExtTable.addRow(row); 531 } 532 PopupLink dirExtensions = new PopupLink(); 533 TitledWindow popup = new TitledWindow( 534 "ExtensionsForDirectories"); 535 popup.setStatic(false); 536 popup.setContent(dirExtTable); 537 dirExtensions.setLabel("ExtensionsForDirectories"); 538 dirExtensions.setContent(popup); 539 dirToolbar.add(dirExtensions); 540 } 541 /******************************************************************* 542 * File extensions 543 */ 544 @SuppressWarnings("unused") 545 List<FileContext> fileContexts = getRegistry().getContexts( 546 FileContext.class); 547 if (fileContexts == null) 548 { 549 log.debug("fileContexts = null"); 550 } 551 else 552 { 553 log.debug("fileContexts.size() = " + fileContexts.size()); 554 } 555 if (!fileContexts.isEmpty()) 556 { 557 Table fileExtTable = new Table("fileExtensionsTable"); 558 List<Column> fileExtHeader = new ArrayList<Column>(2); 559 Column<String> name = new Column<String>("Name"); 560 fileExtHeader.add(name); 561 Column<String> description = new Column<String>("Description"); 562 fileExtHeader.add(description); 563 fileExtTable.setHeader(fileExtHeader); 564 int rowId = 0; 565 for (FileContext context : fileContexts) 566 { 567 rowId++; 568 Row row = new Row(rowId); 569 // Name column 570 log.debug("context.getLabel() = \"" + context.getLabel() + "\""); 571 Cell<String> nameCell = new Cell<String>(context.getLabel()); 572 AbstractLink link = context 573 .getActionLink(getActionFactory()); 574 // Link the extensions so that when one is selected the 575 // files table/form is posted to the given action. 576 CrossLink postTableLink = new CrossLink(fileTable, link); 577 nameCell.setActionLink(postTableLink); 578 row.addCell(nameCell); 579 // Description column 580 log.debug("context.getDescription() = \"" + context.getDescription() + "\""); 581 Cell<String> descCell = new Cell<String>(context.getDescription()); 582 descCell.setActionLink(postTableLink); 583 row.addCell(descCell); 584 // 585 fileExtTable.addRow(row); 586 } 587 TitledWindow popup = new TitledWindow("ExtensionsForFiles"); 588 popup.setStatic(false); 589 popup.setContent(fileExtTable); 590 PopupLink fileExtensions = new PopupLink(); 591 fileExtensions.setLabel("ExtensionsForFiles"); 592 fileExtensions.setContent(popup); 593 fileToolbar.add(fileExtensions); 594 } 595 /******************************************************************* 596 * Tab set 597 */ 598 ts = new TabSet(); 599 // Content tab 600 Tab contentTab = new Tab("Content", "dirContent"); 601 contentTab.setGuiElement(contentContainer); 602 contentTab.setSelected(true); 603 ts.add(contentTab); 604 // Properties tab 605 Tab propertiesTab = new Tab("Properties", "dirProperties"); 606 propertiesTab.setGuiElement(propertiesForm); 607 ts.add(propertiesTab); 608 } 609 /*********************************************************************** 610 * Layout 611 */ 612 RowLayout layout = getLayoutFactory().getRowLayout(); 613 layout.add(title); 614 // Directory tab set 615 if (ts != null) 616 { 617 layout.add(ts); 618 } 619 else 620 { 621 if (selectMoveDir) 622 { 623 layout.add(dirTable); 624 } 625 else 626 { 627 layout.add(dirTable); 628 // Add file table 629 layout.add(fileTable); 630 } 631 } 632 // 633 setLayout(layout); 634 } 635 636 /** 637 * Obtains title for file/directory selection form from valid parameter. 638 * 639 * @param select Boolean Indicates file selection 640 * @param selectMoveDir Boolean Indicates directory selection 641 * @return String Title for file selection form 642 */ 643 @SuppressWarnings("unchecked") 644 private String fetchFormTitle(Boolean select, Boolean selectMoveDir) 645 { 646 String formTitle = null; 647 if (select == null || select) 648 { 649 // Get optional special title for file selection form 650 try 651 { 652 formTitle = getString(TitleField.VPARAM); 653 } 654 catch (InvalidParameterValue e) 655 {} 656 if (formTitle == null || formTitle.equals("")) 657 { 658 formTitle = getSessionAttribute(TitleField.VPARAM); 659 } 660 if (formTitle == null || formTitle.equals("")) 661 { 662 formTitle = new String("Select file[s]"); 663 } 664 // If selection is for directory to move file to, override above 665 if (selectMoveDir) 666 { 667 formTitle = new String("Move to target directory"); 668 } 669 } 670 return formTitle; 671 } 672 673 /** 674 * Obtains name for for "Next" button in file/directory selection form from 675 * valid parameter. 676 * 677 * @param select Boolean Indicates file selection 678 * @param selectMoveDir Boolean Indicates directory selection 679 * @return String Name for "Next" button in file selection form 680 */ 681 @SuppressWarnings("unchecked") 682 private String fetchNextButtonName(Boolean select, Boolean selectMoveDir) 683 { 684 String nextButtonName = null; 685 if (select == null || select) 686 { 687 // Get optional special name for "Next" button 688 try 689 { 690 nextButtonName = getString(NextButtonNameField.VPARAM); 691 } 692 catch (InvalidParameterValue e) 693 {} 694 if (nextButtonName == null || nextButtonName.equals("")) 695 { 696 nextButtonName = getSessionAttribute(NextButtonNameField.VPARAM); 697 } 698 if (nextButtonName == null || nextButtonName.equals("")) 699 { 700 nextButtonName = new String("Next"); 701 } 702 // If selection is for directory to move file to, override above 703 if (selectMoveDir) 704 { 705 nextButtonName = new String("Next"); 706 } 707 } 708 return nextButtonName; 709 } 710 711 /** 712 * Creates a directory table showing sub-directories in current directory, 713 * as well as a link to parent directory. The table columns are defined by 714 * the template table. 715 * 716 * @param templateTable Table Template table for selecting columns. 717 * @param dir Directory Source directory. 718 * @param select Boolean Flag indicating file selection mode. 719 * @param selectMoveDir Boolean Flag indicating directory selection mode 720 * (overrides file selection mode). 721 * @param moveFilesMode Boolean Flag indicating file batch move mode. 722 * @param moveFilesStart Boolean Flag indicating file batch move start. 723 * @return Table 724 */ 725 @SuppressWarnings("unchecked") 726 private Table createDirectoryTable(Table templateTable, Directory dir, 727 Boolean select, Boolean selectMoveDir, Boolean moveFilesMode, Boolean moveFilesStart) 728 { 729 // Define 730 ItemQuery<Directory> query; 731 TableFactory tfactory; 732 DbControl dc; 733 Project activeP; 734 QueryFactory qf; 735 String path = dir.getPath().toString(); 736 // Create 737 qf = getQueryFactory(); 738 dc = newDbControl(); 739 activeP = getActiveProject(dc); 740 tfactory = getTableFactory(); 741 tfactory.setDbControl(dc); 742 query = dir.getSubDirectories(); 743 if (activeP != null) 744 { 745 query.include(Include.IN_PROJECT); 746 } 747 tfactory.reset(); 748 tfactory.setDbControl(dir.getDbControl()); 749 tfactory.setItemClass(Directory.class); 750 tfactory.setQuery(query); 751 // Allow unlimited number of rows in table 752 tfactory.setMaxResults(0); 753 ActionLink clickAction = null; 754 if (select == null || select) 755 { 756 // Get optional special title for file selection form 757 String formTitle = fetchFormTitle(select, selectMoveDir); 758 // Get optional special name for "Next" button 759 String nextButtonName = fetchNextButtonName(select, selectMoveDir); 760 clickAction = getActionFactory().getActionLink(SelectFile.class, 761 "View"); 762 clickAction 763 .addParameter(TitleField.VPARAM, formTitle); 764 clickAction.addParameter(NextButtonNameField.VPARAM, 765 nextButtonName); 766 if (moveFilesMode) 767 { 768 /* 769 * This action may be called several times when 770 * navigating from the source to the target directory. 771 * First time the id values for selected files are 772 * stored in the default valid parameter VInteger ItemIdField.VPARAM, 773 * otherwise they are stored in valid parameter VInteger ViewActiveFile.VFILEID. 774 */ 775 List<Integer> tmpFileIds = null; 776 // Check if first time when navigating to target directory 777 if (moveFilesStart) 778 { 779 try 780 { 781 tmpFileIds = getValidIntegerList(ItemIdField.VPARAM); 782 } 783 catch (Exception e) 784 { 785 log.debug("Exception when trying to retrieve file id list from ItemIdField.VPARAM: " + e); 786 } 787 log.debug("tmpFileIds from ItemIdField.VPARAM = " + tmpFileIds); 788 } 789 else 790 { 791 try 792 { 793 tmpFileIds = getValidIntegerList(ViewActiveFile.VFILEID); 794 } 795 catch (Exception e) 796 { 797 log.debug("Exception when trying to retrieve file id list from ViewActiveFile.VFILEID: " + e); 798 } 799 log.debug("tmpFileIds from ViewActiveFile.VFILEID = " + tmpFileIds); 800 } 801 log.debug("tmpFileIds = " + tmpFileIds); 802 // Add id values for selected files as parameters to click action 803 if (tmpFileIds != null && tmpFileIds.size() > 0) 804 { 805 // Set id values for source files 806 for (Integer fileId : tmpFileIds) 807 { 808 clickAction.addParameter(ViewActiveFile.VFILEID, fileId); 809 } 810 } 811 } 812 } 813 else 814 { 815 clickAction = getActionFactory().getActionLink(ViewDirectory.class, 816 "View"); 817 } 818 tfactory.setColumnAction("Name", clickAction); 819 Table tmpTable = tfactory.build(); 820 /** 821 * If in the top level of the project, also show directories that are 822 * shared to the project, but originate in other projects 823 */ 824 if (activeP != null && activeP.getProjectDirectory().equals(dir)) 825 { 826 dir.getProjectKey(); 827 query = qf.select(Directory.class); 828 query.exclude(Include.MINE); 829 query.include(Include.IN_PROJECT); 830 List<Directory> allDirs = query.list(dc); 831 List<Integer> excludeDirs = new ArrayList<Integer>(); 832 boolean use = false; 833 // Only list the top directories, do not include the current dir or 834 // directories with it as parent 835 for (Directory currentDir : allDirs) 836 { 837 if (!allDirs.contains(currentDir.getParent()) && !currentDir 838 .equals(dir) && !currentDir.getParent().equals(dir)) 839 { 840 log.debug("Included dir: " + currentDir.getName()); 841 use = true; 842 } 843 else 844 { 845 excludeDirs.add(currentDir.getId()); 846 log.debug("Excluded dir: " + currentDir.getName()); 847 } 848 } 849 query.reset(); 850 // Add directories if there are any 851 if (use) 852 { 853 for (Integer id : excludeDirs) 854 { 855 query.restrict(Restrictions.neq(Hql.property("id"), 856 Expressions.integer(id.intValue()))); 857 } 858 tfactory.setQuery(query); 859 Table tabletop = tfactory.build(); 860 for (Row r : tabletop.getRows()) 861 { 862 r.getTags().add("shared"); 863 } 864 // Merge the tables 865 for (Row r : tmpTable.getRows()) 866 { 867 tabletop.addRow(r); 868 } 869 tmpTable = tabletop; 870 } 871 } 872 // Create adapted directory table 873 Table table = new Table("DirectoryTable"); 874 // Set title explicitly, to get correct plural for "Directory" 875 table.setTitle("Directory"); 876 table.setSubtitle(path); 877 // Adapt header to template table 878 /* 879 * Simply using the template header, 880 * table.setHeader(templateTable.getHeader()); would work if the latter 881 * did not include an appended filter row. 882 */ 883 List<Column> adaptedHeader = adaptTableHeader(0, templateTable, 884 tmpTable); 885 table.setHeader(adaptedHeader); 886 // Adapt directory table data to template table 887 for (Row row : tmpTable.getRows()) 888 { 889 // Clear checkbox if navigating to target directory 890 if (selectMoveDir != null && selectMoveDir) 891 { 892 row.getCells().get(0).setValue(null); 893 } 894 // Add slash to directory names 895 Cell nameCell = row.getCells().get(1); 896 String dirName = (String) nameCell.getValue(); 897 nameCell.setValue(dirName + "/"); 898 // For column 2 and upwards, add empty cells if necessary. 899 // row = adaptTableRow(row, 2, templateTable, tmpTable); 900 row = adaptTableRow(row, 2, templateTable, tmpTable); 901 table.getRows().add(0, row); 902 } 903 Directory parentDir = dir.getParent(); 904 if (!dir.isRootDirectory() && parentDir != null && !parentDir 905 .isRootDirectory()) 906 { 907 // Prepend parent directory row 908 Row parentDirRow = tfactory.createRow(parentDir); 909 // Clear checkbox 910 parentDirRow.getCells().get(0).setValue(null); 911 // Add slash to directory names 912 Cell nameCell = parentDirRow.getCells().get(1); 913 nameCell.setValue("../"); 914 // For column 2 and upwards, add empty cells if necessary. 915 // parentDirRow = adaptTableRow(parentDirRow, 2, templateTable, 916 // tmpTable); 917 parentDirRow = adaptTableRow(parentDirRow, 2, templateTable, 918 tmpTable); 919 table.getRows().add(0, parentDirRow); 920 } 921 return table; 922 } 923 924 /** 925 * Adapts a table header for source items so it fits in a table for template 926 * items. The tables for source and template items are used to find what 927 * cells in the source row are applicable in the template table. This is 928 * done by checking the names for each column. A column in the template 929 * table that has a corresponding column in the source table will have the 930 * source cell inserted, otherwise an empty cell. Columns unique to the 931 * source table will not trigger insertion of a cell. 932 * 933 * @param startIndex int Index for first column to check 934 * @param templateTable Table Table for template items 935 * @param sourceTable Table Table for source items 936 * @return List<Column> Output header for source item, modified to fit into 937 * template table. 938 */ 939 @SuppressWarnings("unchecked") 940 private List<Column> adaptTableHeader(int startIndex, Table templateTable, 941 Table sourceTable) 942 { 943 if (startIndex >= templateTable.getHeader().size()) 944 { 945 // No columns to adapt, return input header. 946 return sourceTable.getHeader(); 947 } 948 /* 949 * Get hash table of column names and column indices in source table. 950 */ 951 Hashtable<String, Integer> sourceColumnNameHashtable = new Hashtable<String, Integer>( 952 0); 953 for (int i = startIndex; i < sourceTable.getHeader().size(); i++) 954 { 955 Column srcc = sourceTable.getHeader().get(i); 956 String sourceColumnName = srcc.getValue(); 957 if (sourceColumnName != null) 958 { 959 // Add source column name to hash table. 960 sourceColumnNameHashtable.put(sourceColumnName, new Integer(i)); 961 log 962 .debug("i = " + i + " sourceColumnNameHashtable.get(" + sourceColumnName + ").intValue() = " + sourceColumnNameHashtable 963 .get(sourceColumnName).intValue()); 964 } 965 } 966 /* 967 * For column startIndex and upwards, only keep source columns for 968 * columns existing in both source and template tables. Add empty 969 * columns for columns unique to template table. 970 */ 971 Table tmpTable = new Table("TemporaryTable"); 972 // Add columns up to startIndex. 973 for (int i = 0; i < startIndex; i++) 974 { 975 Column column = sourceTable.getHeader().get(i); 976 tmpTable.add(column); 977 log 978 .debug("i = " + i + " column \"" + column.getValue() + "\" copied."); 979 } 980 /* 981 * For column startIndex and upwards, add empty columns if necessary. 982 */ 983 for (int i = startIndex; i < templateTable.getHeader().size(); i++) 984 { 985 Column c = templateTable.getHeader().get(i); 986 // Only add visible columns in template table 987 if (!c.isVisible()) 988 { 989 continue; 990 } 991 // Check if corresponding source table column exists, if any. 992 String templateColumnName = c.getValue(); 993 if (sourceColumnNameHashtable.containsKey(templateColumnName)) 994 { 995 // Source table column OK 996 int sourceColumnIndex = sourceColumnNameHashtable.get( 997 templateColumnName).intValue(); 998 Column column = sourceTable.getHeader().get(sourceColumnIndex); 999 // If initial Id column, remove column name 1000 if (i == 0 && column.getValue().equals("Id")) 1001 { 1002 column.setValue(""); 1003 } 1004 tmpTable.add(column); 1005 log 1006 .debug("i = " + i + " templateColumnName = \"" + templateColumnName + "\" column \"" + column 1007 .getValue() + "\" inserted."); 1008 } 1009 else 1010 { 1011 // Add new column for template column not in source table 1012 Column column = new Column(templateColumnName); 1013 // If initial Id column, remove column name 1014 if (i == 0 && column.getValue().equals("Id")) 1015 { 1016 column.setValue(""); 1017 } 1018 tmpTable.add(column); 1019 log 1020 .debug("i = " + i + " templateColumnName = \"" + templateColumnName + "\" new column \"" + column 1021 .getValue() + "\" inserted."); 1022 } 1023 } 1024 // Return adapted source header. 1025 return tmpTable.getHeader(); 1026 } 1027 1028 /** 1029 * Adapts a table row for source items so it fits in a table for template 1030 * items. The tables for source and template items are used to find what 1031 * cells in the source row are applicable in the template table. This is 1032 * done by checking the names for each column. A column in the template 1033 * table that has a corresponding column in the source table will have the 1034 * source cell inserted, otherwise an empty cell. Columns unique to the 1035 * source table will not trigger insertion of a cell. 1036 * 1037 * @param row Row Input row from source table to be adapted. 1038 * @param startIndex int Index for first column to check 1039 * @param templateTable Table Table for template items 1040 * @param sourceTable Table Table for source items 1041 * @return Row Output row for source item, modified to fit into template 1042 * table. 1043 */ 1044 @SuppressWarnings("unchecked") 1045 private Row adaptTableRow(Row row, int startIndex, Table templateTable, 1046 Table sourceTable) 1047 { 1048 if (startIndex >= row.getCells().size()) 1049 { 1050 // No cells to adapt, return input row. 1051 return row; 1052 } 1053 /* 1054 * Get hash table of column names and column indices in source table. 1055 */ 1056 Hashtable<String, Integer> sourceColumnNameHashtable = new Hashtable<String, Integer>( 1057 0); 1058 for (int i = startIndex; i < sourceTable.getHeader().size(); i++) 1059 { 1060 Column srcc = sourceTable.getHeader().get(i); 1061 String sourceColumnName = srcc.getValue(); 1062 if (sourceColumnName != null) 1063 { 1064 // Add source column name to hash table. 1065 sourceColumnNameHashtable.put(sourceColumnName, new Integer(i)); 1066 log 1067 .debug("i = " + i + " sourceColumnNameHashtable.get(" + sourceColumnName + ").intValue() = " + sourceColumnNameHashtable 1068 .get(sourceColumnName).intValue()); 1069 } 1070 } 1071 /* 1072 * For column startIndex and upwards, only keep source cells for columns 1073 * existing in both source and template tables. Add empty cells for 1074 * columns unique to template table. 1075 */ 1076 ArrayList<Cell<?>> cellList = new ArrayList<Cell<?>>(0); 1077 // Add cells up to startIndex. 1078 for (int i = 0; i < startIndex; i++) 1079 { 1080 Cell<?> cell = row.getCells().get(i); 1081 cellList.add(cell); 1082 log 1083 .debug("New row i = " + i + " cell value \"" + cell.getValue() + "\" copied."); 1084 } 1085 /* 1086 * For column startIndex and upwards, add empty cells if necessary. 1087 */ 1088 Cell emptyCell = new Cell<String>(null); 1089 for (int i = startIndex; i < templateTable.getHeader().size(); i++) 1090 { 1091 Column c = templateTable.getHeader().get(i); 1092 // Only add visible columns in template table 1093 if (!c.isVisible()) 1094 { 1095 continue; 1096 } 1097 // Check if corresponding source table cell exists, if any. 1098 String templateColumnName = c.getValue(); 1099 if (sourceColumnNameHashtable.containsKey(templateColumnName)) 1100 { 1101 // Source table cell OK 1102 int sourceCellIndex = sourceColumnNameHashtable.get( 1103 templateColumnName).intValue(); 1104 Cell<?> cell = row.getCells().get(sourceCellIndex); 1105 cellList.add(cell); 1106 log 1107 .debug("New row i = " + i + " templateColumnName = \"" + templateColumnName + "\" cell value \"" + cell 1108 .getValue() + "\" inserted."); 1109 } 1110 else 1111 { 1112 // Add empty cell for template column not in source table 1113 cellList.add(emptyCell); 1114 log 1115 .debug("New row i = " + i + " templateColumnName = \"" + templateColumnName + "\" empty cell inserted."); 1116 } 1117 } 1118 // Construct adapted source row. 1119 row.setCells(cellList); 1120 return row; 1121 } 1122 1123 /** 1124 * Convenience method for fetching the 1125 * table update button clicked flag. 1126 * 1127 * @return boolean The table update button clicked flag. 1128 */ 1129 private boolean fetchTableUpdateButtonClickedFlag() 1130 { 1131 // Get table update button clicked flag 1132 boolean tableUpdateButtonClicked = false; 1133 Boolean tableUpdateButtonClickedFlagFromRequest = false; 1134 try 1135 { 1136 tableUpdateButtonClickedFlagFromRequest = getValidBoolean(VTABLEUPDATEBUTTONCLICKED); 1137 if (tableUpdateButtonClickedFlagFromRequest == null) 1138 { 1139 tableUpdateButtonClicked = false; 1140 } 1141 else 1142 { 1143 tableUpdateButtonClicked = tableUpdateButtonClickedFlagFromRequest; 1144 } 1145 } 1146 catch (Exception e) 1147 { 1148 log.debug("Exception when trying to get valid parameter VTABLEUPDATEBUTTONCLICKED: " + e); 1149 } 1150 log.debug("tableUpdateButtonClickedFlagFromRequest = " + tableUpdateButtonClickedFlagFromRequest + " tableUpdateButtonClicked = " + tableUpdateButtonClicked); 1151 // 1152 log.debug("tableUpdateButtonClicked = " + tableUpdateButtonClicked); 1153 return tableUpdateButtonClicked; 1154 } 1165 1155 } -
trunk/client/servlet/src/org/proteios/action/project/UploadDemoFiles.java
r3626 r3899 1 1 /* 2 $Id$ 3 4 Copyright (C) 2007 Fredrik Levander, Gregory Vincic, Olle Mansson 5 6 Files are copyright by their respective authors. The contributions to 7 files where copyright is not explicitly stated can be traced with the 8 source code revision system. 9 10 This file is part of Proteios. 11 Available at http://www.proteios.org/ 12 13 Proteios-2.x is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License 15 as published by the Free Software Foundation; either version 2 16 of the License, or (at your option) any later version. 17 18 Proteios is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place - Suite 330, 26 Boston, MA 02111-1307, USA. 27 */ 2 $Id$ 3 4 Copyright (C) 2007 Fredrik Levander, Gregory Vincic, Olle Mansson 5 Copyright (C) 2010 Gregory Vincic 6 7 Files are copyright by their respective authors. The contributions to 8 files where copyright is not explicitly stated can be traced with the 9 source code revision system. 10 11 This file is part of Proteios. 12 Available at http://www.proteios.org/ 13 14 Proteios-2.x is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License 16 as published by the Free Software Foundation; either version 2 17 of the License, or (at your option) any later version. 18 19 Proteios is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 GNU General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place - Suite 330, 27 Boston, MA 02111-1307, USA. 28 */ 28 29 package org.proteios.action.project; 29 30 31 import java.net.MalformedURLException; 32 import java.net.URL; 33 import java.util.ArrayList; 34 import java.util.List; 35 import org.proteios.Context; 36 import org.proteios.ContextEnabled; 37 import org.proteios.FileContext; 30 38 import org.proteios.action.ProteiosAction; 31 39 import org.proteios.core.DbControl; … … 38 46 import se.lu.thep.waf.ActionException; 39 47 import se.lu.thep.waf.constraints.InvalidParameterValue; 40 import java.net.MalformedURLException;41 import java.net.URL;42 48 43 49 /** 44 * Uploads a set of files for demonstration purposes. 45 * 46 * @author gregory 47 */ 50 Uploads a set of files for demonstration purposes. 51 */ 48 52 public class UploadDemoFiles 49 extends ProteiosAction<UploadDemoFiles> 53 extends ProteiosAction<UploadDemoFiles> 54 implements ContextEnabled 50 55 { 51 private static final String root = "http://www.proteios.org/trac/downloads/demoProjectFiles/"; 52 private ItemFactory factory = null; 53 private DbControl dc = null; 54 55 56 @Override 57 protected void runMe() 58 throws ActionException, InvalidParameterValue 59 { 60 dc = newDbControl(); 61 Project project = isProjectActive(dc); 62 factory = new ItemFactory(dc); 63 /*********************************************************************** 64 * Upload some files 65 */ 66 Directory projectDir = project.getProjectDirectory(); 67 // Project directories get the name of the project 68 addRobotFiles(projectDir); 69 addMascotFiles(projectDir); 70 addPeakListFiles(projectDir); 71 // 72 setMessage("Demo files uploaded"); 73 dc.commit(); 74 } 75 76 77 /** 78 * @param dc 79 * @param parentDir 80 * @throws ActionException 81 */ 82 private void addPeakListFiles(Directory parentDir) 83 throws ActionException 84 { 85 Directory dir = factory.create(Directory.class); 86 dir.setParent(parentDir); 87 dir.setName("Peaklist files"); 88 dc.saveItem(dir); 89 FileType fileType = factory.getById(FileType.class, SystemItems 90 .getId(FileType.MZDATA)); 91 uploadFile(dir, "qtof_A2.xml", fileType); 92 uploadFile(dir, "qtof_A3.xml", fileType); 93 } 94 95 96 /** 97 * @param dc 98 * @param parentDir 99 * @throws ActionException 100 */ 101 private void addMascotFiles(Directory parentDir) 102 throws ActionException 103 { 104 ItemFactory factory = new ItemFactory(dc); 105 Directory dir = factory.create(Directory.class); 106 dir.setParent(parentDir); 107 dir.setName("Mascot files"); 108 dc.saveItem(dir); 109 FileType fileType = factory.getById(FileType.class, SystemItems 110 .getId(FileType.MASCOT_XML)); 111 uploadFile(dir, "result1.xml", fileType); 112 uploadFile(dir, "result2.xml", fileType); 113 } 114 115 116 /** 117 * @param dc 118 * @param parentDir 119 * @throws ActionException 120 */ 121 private void addRobotFiles(Directory parentDir) 122 throws ActionException 123 { 124 ItemFactory factory = new ItemFactory(dc); 125 Directory dir = factory.create(Directory.class); 126 dir.setParent(parentDir); 127 dir.setName("Robot result files"); 128 dc.saveItem(dir); 129 FileType fileType = factory.getById(FileType.class, SystemItems 130 .getId(FileType.SHW_RESULT)); 131 uploadFile(dir, "robotResult.xml", fileType); 132 } 133 134 135 private void uploadFile(Directory dir, String fileName, FileType type) 136 throws ActionException 137 { 138 URL fileUrl = getFile(fileName); 139 File file = factory.create(File.class); 140 file.setDirectory(dir); 141 file.setName(fileName); 142 file.setDescription("Use external plate id 18115042KAISA4 to import"); 143 file.setFileType(type); 144 try 145 { 146 dc.saveItem(file); 147 file.upload(fileUrl.openStream(), false); 148 dc.saveItem(file); 149 } 150 catch (Exception e) 151 { 152 throw new ActionException(e); 153 } 154 } 155 156 157 private URL getFile(String fileName) 158 throws ActionException 159 { 160 try 161 { 162 return new URL(root + fileName); 163 } 164 catch (MalformedURLException e) 165 { 166 throw new ActionException(e); 167 } 168 } 56 private static final String root = "http://www.proteios.org/trac/downloads/demoProjectFiles/"; 57 private ItemFactory factory = null; 58 private DbControl dc = null; 59 60 @Override 61 protected void runMe() throws ActionException, InvalidParameterValue 62 { 63 dc = newDbControl(); 64 Project project = isProjectActive(dc); 65 Directory projectDir = project.getProjectDirectory(); 66 factory = getItemFactory(dc); 67 // Project directories get the name of the project 68 addRobotFiles(projectDir); 69 addMascotFiles(projectDir); 70 addPeakListFiles(projectDir); 71 72 setMessage("Demo files uploaded"); 73 dc.commit(); 74 } 75 76 private void addPeakListFiles(Directory parentDir) throws ActionException 77 { 78 Directory dir = factory.create(Directory.class); 79 dir.setParent(parentDir); 80 dir.setName("Peaklist files"); 81 dc.saveItem(dir); 82 FileType fileType = factory.getById(FileType.class, SystemItems 83 .getId(FileType.MZDATA)); 84 uploadFile(dir, "qtof_A2.xml", fileType); 85 uploadFile(dir, "qtof_A3.xml", fileType); 86 } 87 88 private void addMascotFiles(Directory parentDir) throws ActionException 89 { 90 Directory dir = factory.create(Directory.class); 91 dir.setParent(parentDir); 92 dir.setName("Mascot files"); 93 dc.saveItem(dir); 94 FileType fileType = factory.getById(FileType.class, SystemItems 95 .getId(FileType.MASCOT_XML)); 96 uploadFile(dir, "result1.xml", fileType); 97 uploadFile(dir, "result2.xml", fileType); 98 } 99 100 private void addRobotFiles(Directory parentDir) throws ActionException 101 { 102 Directory dir = factory.create(Directory.class); 103 dir.setParent(parentDir); 104 dir.setName("Robot result files"); 105 dc.saveItem(dir); 106 FileType fileType = factory.getById(FileType.class, SystemItems 107 .getId(FileType.SHW_RESULT)); 108 uploadFile(dir, "robotResult.xml", fileType); 109 } 110 111 private void uploadFile(Directory dir, String fileName, FileType type) throws ActionException 112 { 113 URL fileUrl = getFile(fileName); 114 File file = factory.create(File.class); 115 file.setDirectory(dir); 116 file.setName(fileName); 117 file.setDescription("Use external plate id 18115042KAISA4 to import"); 118 file.setFileType(type); 119 try 120 { 121 dc.saveItem(file); 122 file.upload(fileUrl.openStream(), false); 123 dc.saveItem(file); 124 } 125 catch (Exception e) 126 { 127 throw new ActionException(e); 128 } 129 } 130 131 private URL getFile(String fileName) throws ActionException 132 { 133 try 134 { 135 return new URL(root + fileName); 136 } 137 catch (MalformedURLException e) 138 { 139 throw new ActionException(e); 140 } 141 } 142 143 public List<Context> listContexts() 144 { 145 List<Context> contexts = new ArrayList<Context>(1); 146 /* 147 We want our action to appear as an extension when viewing files. Do 148 this by adding a FileContext to the list of contexts. 149 */ 150 FileContext files = new FileContext("UploadDemoFiles", 151 "Upload demo files", 152 UploadDemoFiles.class); 153 contexts.add(files); 154 return contexts; 155 } 169 156 }
Note: See TracChangeset
for help on using the changeset viewer.