001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.explorer; 029 030import org.opencms.db.CmsResourceState; 031import org.opencms.file.CmsFolder; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsProject; 034import org.opencms.file.CmsProperty; 035import org.opencms.file.CmsPropertyDefinition; 036import org.opencms.file.CmsResource; 037import org.opencms.file.CmsResourceFilter; 038import org.opencms.file.types.CmsResourceTypePlain; 039import org.opencms.file.types.I_CmsResourceType; 040import org.opencms.i18n.CmsMessages; 041import org.opencms.jsp.CmsJspActionElement; 042import org.opencms.loader.CmsLoaderException; 043import org.opencms.main.CmsException; 044import org.opencms.main.CmsLog; 045import org.opencms.main.OpenCms; 046import org.opencms.site.CmsSite; 047import org.opencms.util.CmsStringUtil; 048import org.opencms.workplace.CmsWorkplace; 049import org.opencms.workplace.CmsWorkplaceSettings; 050 051import java.util.ArrayList; 052import java.util.Iterator; 053import java.util.List; 054import java.util.Locale; 055import java.util.StringTokenizer; 056 057import javax.servlet.http.HttpServletRequest; 058 059import org.apache.commons.logging.Log; 060 061/** 062 * Generates the tree view for the OpenCms Workplace.<p> 063 * 064 * The following Workplace files use this class: 065 * <ul> 066 * <li>/views/explorer/tree_fs.jsp 067 * <li>/views/explorer/tree_files.jsp 068 * </ul> 069 * <p> 070 * 071 * @since 6.0.0 072 */ 073public class CmsTree extends CmsWorkplace { 074 075 /** Request parameter name for the includesfiles parameter. */ 076 public static final String PARAM_INCLUDEFILES = "includefiles"; 077 078 /** Request parameter name for the lastknown parameter. */ 079 public static final String PARAM_LASTKNOWN = "lastknown"; 080 081 /** Request parameter name for the projectaware parameter. */ 082 public static final String PARAM_PROJECTAWARE = "projectaware"; 083 084 /** Request parameter name for the resource parameter. */ 085 public static final String PARAM_RESOURCE = "resource"; 086 087 /** Request parameter name for the rootloaded parameter. */ 088 public static final String PARAM_ROOTLOADED = "rootloaded"; 089 090 /** Request parameter name for the showsiteselector parameter. */ 091 public static final String PARAM_SHOWSITESELECTOR = "showsiteselector"; 092 093 /** Request parameter name for the integrator parameter. */ 094 public static final String PARAM_INTEGRATOR = "integrator"; 095 096 /** Request parameter name for the treesite parameter. */ 097 public static final String PARAM_TREESITE = "treesite"; 098 099 /** Request parameter name for the type parameter. */ 100 public static final String PARAM_TYPE = "type"; 101 102 /** The log object for this class. */ 103 private static final Log LOG = CmsLog.getLog(CmsTree.class); 104 105 /** Type name for showing the tree when copying resources. */ 106 private static final String TYPE_COPY = "copy"; 107 108 /** Type name for showing the tree when creating page links in the editor. */ 109 private static final String TYPE_PAGELINK = "pagelink"; 110 111 /** Type name for showing the tree in preferences dialog. */ 112 private static final String TYPE_PREFERENCES = "preferences"; 113 114 /** Type name for showing the tree when creating siblings. */ 115 private static final String TYPE_SIBLING = "sibling"; 116 117 /** Type name for showing the tree in a widget dialog. */ 118 private static final String TYPE_VFSWIDGET = "vfswidget"; 119 120 /** Indicates if only folders or files and folders should be included in the tree. */ 121 private boolean m_includeFiles; 122 123 /** Indicates if a complete new tree should be created. */ 124 private boolean m_newTree; 125 126 /** Indicates project awareness, ie. if resources outside of the current project should be displayed as normal. */ 127 private boolean m_projectAware = true; 128 129 /** The name of the root folder to display the tree from, usually "/". */ 130 private String m_rootFolder; 131 132 /** Flag to indicate if the site selector should be shown in popup tree window. */ 133 private boolean m_showSiteSelector; 134 135 /** The name of the start folder (or "last known" folder) to be loaded. */ 136 private String m_startFolder; 137 138 /** The name of the target folder to be loaded. */ 139 private String m_targetFolder; 140 141 /** The type of the tree (e.g. "copy", "project" etc.). */ 142 private String m_treeType; 143 144 /** 145 * Public constructor.<p> 146 * 147 * @param jsp an initialized JSP action element 148 */ 149 public CmsTree(CmsJspActionElement jsp) { 150 151 super(jsp); 152 } 153 154 /** 155 * Returns the HTML for the tree initialization.<p> 156 * 157 * @param cms the CmsObject 158 * @param encoding the current encoding 159 * @param skinUri the current skin URI 160 * @return the HTML for the tree initialization 161 */ 162 public static String initTree(CmsObject cms, String encoding, String skinUri) { 163 164 StringBuffer retValue = new StringBuffer(512); 165 String servletUrl = OpenCms.getSystemInfo().getOpenCmsContext(); 166 167 // get the localized workplace messages 168 // TODO: Why a new message object, can it not be obtained from session? 169 Locale locale = cms.getRequestContext().getLocale(); 170 CmsMessages messages = OpenCms.getWorkplaceManager().getMessages(locale); 171 172 retValue.append("function initTreeResources() {\n"); 173 retValue.append("\tinitResources(\""); 174 retValue.append(encoding); 175 retValue.append("\", \""); 176 retValue.append(PATH_WORKPLACE); 177 retValue.append("\", \""); 178 retValue.append(skinUri); 179 retValue.append("\", \""); 180 retValue.append(servletUrl); 181 retValue.append("\");\n"); 182 183 // get all available resource types 184 List<I_CmsResourceType> allResTypes = OpenCms.getResourceManager().getResourceTypes(); 185 for (int i = 0; i < allResTypes.size(); i++) { 186 // loop through all types 187 I_CmsResourceType type = allResTypes.get(i); 188 int curTypeId = type.getTypeId(); 189 String curTypeName = type.getTypeName(); 190 // get the settings for the resource type 191 CmsExplorerTypeSettings settings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(curTypeName); 192 if (settings == null) { 193 if (LOG.isWarnEnabled()) { 194 LOG.warn(Messages.get().getBundle().key(Messages.LOG_MISSING_SETTINGS_ENTRY_1, curTypeName)); 195 } 196 settings = OpenCms.getWorkplaceManager().getExplorerTypeSetting( 197 CmsResourceTypePlain.getStaticTypeName()); 198 } 199 retValue.append("\taddResourceType("); 200 retValue.append(curTypeId); 201 retValue.append(", \""); 202 retValue.append(curTypeName); 203 retValue.append("\",\t\""); 204 retValue.append(messages.key(settings.getKey())); 205 retValue.append("\",\t\"" + CmsWorkplace.RES_PATH_FILETYPES); 206 retValue.append(settings.getIcon()); 207 retValue.append("\");\n"); 208 } 209 210 retValue.append("}\n\n"); 211 retValue.append("initTreeResources();\n"); 212 String sharedFolder = OpenCms.getSiteManager().getSharedFolder(); 213 if (sharedFolder != null) { 214 retValue.append("sharedFolderName = '" + sharedFolder + "';"); 215 } 216 return retValue.toString(); 217 } 218 219 /** 220 * Determines the root folder of the current tree dependent on users setting of explorer view restriction.<p> 221 * 222 * @return the root folder resource name to display 223 */ 224 public String getRootFolder() { 225 226 if (m_rootFolder == null) { 227 String folder = "/"; 228 if ((getTreeType() == null) && getSettings().getUserSettings().getRestrictExplorerView()) { 229 folder = getSettings().getUserSettings().getStartFolder(); 230 } 231 try { 232 getCms().readFolder(folder, CmsResourceFilter.IGNORE_EXPIRATION); 233 } catch (CmsException e) { 234 if (LOG.isInfoEnabled()) { 235 LOG.info(e.getLocalizedMessage(), e); 236 } 237 folder = "/"; 238 } 239 m_rootFolder = folder; 240 } 241 return m_rootFolder; 242 } 243 244 /** 245 * Returns the HTML for the site selector box for the explorer tree window.<p> 246 * 247 * @param htmlAttributes optional attributes for the <select> tag 248 * @return HTML code for the site selector box 249 */ 250 public String getSiteSelector(String htmlAttributes) { 251 252 List<String> options = new ArrayList<String>(); 253 List<String> values = new ArrayList<String>(); 254 int selectedIndex = 0; 255 String preSelection = getSettings().getTreeSite(getTreeType()); 256 if (preSelection == null) { 257 if ("".equals(getCms().getRequestContext().getSiteRoot())) { 258 // we are in the root site, getCurrentSite(CmsObject) includes NOT the root site 259 preSelection = ""; 260 } else { 261 // get the site root of the current site 262 preSelection = OpenCms.getSiteManager().getCurrentSite(getCms()).getSiteRoot(); 263 } 264 // set the tree site to avoid discrepancies between selector and tree 265 getSettings().setTreeSite(getTreeType(), preSelection); 266 } 267 268 boolean includeRootSite = true; 269 boolean showSiteUrls = false; 270 if (TYPE_PAGELINK.equals(getTreeType())) { 271 // in wysiwyg editor link dialog, don't show root site, but show site URLs 272 includeRootSite = false; 273 showSiteUrls = true; 274 } 275 List<CmsSite> sites = OpenCms.getSiteManager().getAvailableSites( 276 getCms(), 277 includeRootSite, 278 true, 279 getCms().getRequestContext().getOuFqn()); 280 281 Iterator<CmsSite> i = sites.iterator(); 282 int pos = 0; 283 while (i.hasNext()) { 284 CmsSite site = i.next(); 285 values.add(site.getSiteRoot()); 286 String curOption = substituteSiteTitle(site.getTitle()); 287 if (showSiteUrls && (site.getSiteMatcher() != null)) { 288 // show the site URL in editor link dialog tree 289 curOption = site.getUrl() + " (" + curOption + ")"; 290 if (getCms().getRequestContext().getSiteRoot().equals(site.getSiteRoot())) { 291 // mark the current workplace site in selector 292 curOption = "*" + curOption; 293 } 294 } 295 296 if (site.getSiteRoot().equals(preSelection)) { 297 // this is the user's currently selected site 298 selectedIndex = pos; 299 } 300 options.add(curOption); 301 pos++; 302 } 303 304 return buildSelect(htmlAttributes, options, values, selectedIndex); 305 } 306 307 /** 308 * Returns the html for the explorer tree.<p> 309 * 310 * @return the html for the explorer tree 311 */ 312 public String getTree() { 313 314 StringBuffer result = new StringBuffer(2048); 315 316 List<String> targetFolderList = new ArrayList<String>(); 317 if (getTargetFolder() != null) { 318 // check if there is more than one folder to update (e.g. move operation) 319 StringTokenizer T = new StringTokenizer(getTargetFolder(), "|"); 320 while (T.hasMoreTokens()) { 321 String currentFolder = T.nextToken().trim(); 322 // if (OpenCms.getSiteManager().startsWithShared(currentFolder)) { 323 // currentFolder = OpenCms.getSiteManager().cutShared(currentFolder); 324 // } 325 targetFolderList.add(currentFolder); 326 } 327 } else { 328 targetFolderList.add(null); 329 } 330 331 String storedSiteRoot = null; 332 try { 333 CmsFolder folder = null; 334 List<CmsResource> resources = new ArrayList<CmsResource>(); 335 String oldSiteRoot = getCms().getRequestContext().getSiteRoot(); 336 337 Iterator<String> targets = targetFolderList.iterator(); 338 while (targets.hasNext()) { 339 // iterate over all given target folders 340 String currentTargetFolder = targets.next(); 341 342 if (getSettings().getTreeSite(getTreeType()) != null) { 343 // change the site root for popup window with site selector 344 storedSiteRoot = getCms().getRequestContext().getSiteRoot(); 345 if (newTree() && (currentTargetFolder == null)) { 346 currentTargetFolder = "/"; 347 } 348 getCms().getRequestContext().setSiteRoot(getSettings().getTreeSite(getTreeType())); 349 try { 350 // check presence of target folder 351 getCms().readFolder(currentTargetFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 352 } catch (CmsException e) { 353 // target folder not found, set it to "/" 354 if (LOG.isInfoEnabled()) { 355 LOG.info(e.getLocalizedMessage(), e); 356 } 357 currentTargetFolder = "/"; 358 } 359 } 360 361 // read the selected folder 362 try { 363 folder = getCms().readFolder(currentTargetFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 364 } catch (CmsException e) { 365 // return with error 366 return printError(e); 367 } 368 369 String startFolder = getStartFolder(); 370 String rcSite = getCms().getRequestContext().getSiteRoot(); 371 if (OpenCms.getSiteManager().startsWithShared(currentTargetFolder) 372 && OpenCms.getSiteManager().startsWithShared(rcSite)) { 373 currentTargetFolder = currentTargetFolder.substring( 374 OpenCms.getSiteManager().getSharedFolder().length() - 1); 375 } 376 if ((startFolder == null) || (!currentTargetFolder.startsWith(startFolder))) { 377 // no (valid) start folder given, just load current folder 378 try { 379 if (includeFiles()) { 380 resources.addAll(getCms().getResourcesInFolder( 381 currentTargetFolder, 382 CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)); 383 } else { 384 resources.addAll( 385 getCms().getSubFolders(currentTargetFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)); 386 } 387 } catch (CmsException e) { 388 // return with error 389 return printError(e); 390 } 391 } else { 392 // valid start folder given, load all folders between start and current folder 393 try { 394 if (includeFiles()) { 395 resources.addAll( 396 getCms().getResourcesInFolder(startFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)); 397 } else { 398 resources.addAll( 399 getCms().getSubFolders(startFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)); 400 } 401 StringTokenizer tok = new StringTokenizer( 402 currentTargetFolder.substring(startFolder.length()), 403 "/"); 404 while (tok.hasMoreTokens()) { 405 startFolder += tok.nextToken() + "/"; 406 if (includeFiles()) { 407 resources.addAll(getCms().getResourcesInFolder( 408 startFolder, 409 CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)); 410 } else { 411 resources.addAll( 412 getCms().getSubFolders(startFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)); 413 } 414 } 415 } catch (CmsException e) { 416 // return with error 417 return printError(e); 418 } 419 } 420 } 421 422 result.append("function init() {\n"); 423 424 if (newTree()) { 425 // new tree must be reloaded 426 result.append("parent.initTree();\n"); 427 result.append(getRootNode()); 428 } 429 430 // read the list of project resource to select which resource is "inside" or "outside" 431 List<String> projectResources = new ArrayList<String>(); 432 if (isProjectAware()) { 433 try { 434 projectResources = getCms().readProjectResources(getCms().getRequestContext().getCurrentProject()); 435 } catch (CmsException e) { 436 // use an empty list (all resources are "outside") 437 if (LOG.isInfoEnabled()) { 438 LOG.info(e.getLocalizedMessage(), e); 439 } 440 } 441 } 442 443 // now output all the tree nodes 444 Iterator<CmsResource> i = resources.iterator(); 445 while (i.hasNext()) { 446 CmsResource resource = i.next(); 447 boolean grey = false; 448 if (isProjectAware()) { 449 grey = !CmsProject.isInsideProject(projectResources, resource); 450 } 451 if (!grey) { 452 try { 453 OpenCms.getResourceManager().getResourceType(resource.getTypeId()); 454 } catch (CmsLoaderException e) { 455 // if resource type is not found 456 grey = true; 457 } 458 } 459 460 result.append( 461 getNode( 462 resource.getRootPath(), 463 resource.getName(), 464 resource.getTypeId(), 465 resource.isFolder(), 466 resource.getState(), 467 grey)); 468 } 469 470 if (includeFiles()) { 471 result.append("parent.setIncludeFiles(true);\n"); 472 } 473 result.append("parent.setProjectAware(").append(isProjectAware()).append(");\n"); 474 if (getTreeType() != null) { 475 // this is a popup window tree 476 result.append("parent.setTreeType(\""); 477 result.append(getTreeType()); 478 result.append("\");\n"); 479 String curSite = getSettings().getTreeSite(getTreeType()); 480 if (curSite != null) { 481 // add the current site as prefix if present 482 result.append("parent.setSitePrefix(\""); 483 result.append(getSitePrefix(curSite, oldSiteRoot)); 484 result.append("\");\n"); 485 } 486 } 487 // set the root folder in javascript 488 result.append("parent.setRootFolder(\""); 489 result.append(getRootFolder()); 490 result.append("\");\n"); 491 492 if (folder != null) { 493 if (newTree()) { 494 // new tree 495 result.append("parent.showTree(parent.tree_display.document, \""); 496 result.append(folder.getRootPath().hashCode()); 497 result.append("\");\n"); 498 } else { 499 // update the current tree with the children of the selected node 500 if (resources.size() == 0) { 501 // the node had no children 502 result.append("parent.setNoChilds(\""); 503 result.append(folder.getRootPath().hashCode()); 504 result.append("\");\n"); 505 } 506 result.append("parent.showLoadedNodes(parent.tree_display.document,\""); 507 result.append(folder.getRootPath().hashCode()); 508 result.append("\");\n"); 509 } 510 } 511 512 result.append("}\n"); 513 } finally { 514 if (storedSiteRoot != null) { 515 getCms().getRequestContext().setSiteRoot(storedSiteRoot); 516 } 517 } 518 return result.toString(); 519 } 520 521 /** 522 * Returns the type of this tree (e.g. "copy", "project" etc.), 523 * if null this is the default explorer version.<p> 524 * 525 * @return the current type of the tree (e.g. "copy", "project" etc.) 526 */ 527 public String getTreeType() { 528 529 return m_treeType; 530 } 531 532 /** 533 * Indicates if only folders or files and folders should be included in the tree.<p> 534 * 535 * @return true if files and folders should be included in the tree 536 */ 537 public boolean includeFiles() { 538 539 return m_includeFiles; 540 } 541 542 /** 543 * Returns the HTML for the tree initialization.<p> 544 * 545 * @return the HTML for the tree initialization 546 */ 547 public String initTree() { 548 549 return initTree(getCms(), getEncoding(), getSkinUri()); 550 } 551 552 /** 553 * Returns the project awareness flag.<p> 554 * 555 * @return the project awareness flag 556 */ 557 public boolean isProjectAware() { 558 559 return m_projectAware; 560 } 561 562 /** 563 * Sets the project awareness flag.<p> 564 * 565 * @param projectAware the project awareness flag to set 566 */ 567 public void setProjectAware(boolean projectAware) { 568 569 m_projectAware = projectAware; 570 } 571 572 /** 573 * Indicates if the site selector should be shown depending on the tree type, initial settings and the count of accessible sites.<p> 574 * 575 * @return true if site selector should be shown, otherwise false 576 */ 577 public boolean showSiteSelector() { 578 579 return m_showSiteSelector; 580 } 581 582 /** 583 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 584 */ 585 @Override 586 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 587 588 setIncludeFiles(Boolean.valueOf(request.getParameter(PARAM_INCLUDEFILES)).booleanValue()); 589 setProjectAware(Boolean.valueOf(request.getParameter(PARAM_PROJECTAWARE)).booleanValue()); 590 boolean rootloaded = Boolean.valueOf(request.getParameter(PARAM_ROOTLOADED)).booleanValue(); 591 String resource = request.getParameter(PARAM_RESOURCE); 592 593 setTreeType(request.getParameter(PARAM_TYPE)); 594 String treeSite = request.getParameter(PARAM_TREESITE); 595 if ((getTreeType() != null) && (treeSite != null)) { 596 getSettings().setTreeSite(getTreeType(), treeSite); 597 } 598 599 if (getSettings().getTreeSite(getTreeType()) != null) { 600 String site = getCms().getRequestContext().getSiteRoot(); 601 try { 602 getCms().getRequestContext().setSiteRoot(getSettings().getTreeSite(getTreeType())); 603 if (!getCms().existsResource(resource)) { 604 resource = null; 605 } 606 } finally { 607 getCms().getRequestContext().setSiteRoot(site); 608 } 609 } else { 610 if (!getCms().existsResource(resource)) { 611 resource = null; 612 } 613 } 614 615 computeSiteSelector(request); 616 617 String currentResource; 618 if (getTreeType() == null) { 619 currentResource = getSettings().getExplorerResource(); 620 } else { 621 // get the current tree resource from the settings for a special tree type 622 currentResource = getSettings().getTreeResource(getTreeType()); 623 } 624 625 String lastknown = request.getParameter(PARAM_LASTKNOWN); 626 // both "resource" and "lastknown" must be folders 627 628 if (resource != null) { 629 resource = CmsResource.getFolderPath(resource); 630 } 631 if ((lastknown != null) && (!lastknown.endsWith("/"))) { 632 lastknown += "/"; 633 } 634 635 String rootFolder = getRootFolder(); 636 if (rootFolder.equals(resource) && !rootFolder.equals(currentResource) && (lastknown == null) && !rootloaded) { 637 // direct load of a new tree with subtree (e.g. when returning from an editor) 638 lastknown = getRootFolder(); 639 resource = CmsResource.getFolderPath(currentResource); 640 setNewTree(true); 641 } else if (rootFolder.equals(resource)) { 642 // load new tree if not already loaded 643 setNewTree(!rootloaded); 644 } else { 645 setNewTree(false); 646 } 647 648 if (getTreeType() != null) { 649 getSettings().setTreeResource(getTreeType(), resource); 650 } 651 652 setTargetFolder(resource); 653 setStartFolder(lastknown); 654 } 655 656 /** 657 * Determines if the site selector frame should be shown depending on the tree type or the value of a request parameter.<p> 658 * 659 * If only one site is available, the site selector is not displayed.<p> 660 * 661 * @param request the HttpServletRequest to check 662 */ 663 private void computeSiteSelector(HttpServletRequest request) { 664 665 boolean selectorForType = TYPE_SIBLING.equals(getTreeType()) 666 || TYPE_COPY.equals(getTreeType()) 667 || TYPE_PAGELINK.equals(getTreeType()) 668 || TYPE_PREFERENCES.equals(getTreeType()); 669 boolean showFromRequest = Boolean.valueOf(request.getParameter(PARAM_SHOWSITESELECTOR)).booleanValue(); 670 if (selectorForType || showFromRequest) { 671 // get all available sites 672 int siteCount = OpenCms.getSiteManager().getAvailableSites(getCms(), true).size(); 673 setShowSiteSelector(siteCount > 1); 674 return; 675 } 676 setShowSiteSelector(false); 677 } 678 679 /** 680 * Creates the output for a tree node.<p> 681 * 682 * @param path the path of the resource represented by this tree node 683 * @param title the resource name 684 * @param type the resource type 685 * @param folder if the resource is a folder 686 * @param state the resource state 687 * @param grey if true, the node is displayed in grey 688 * 689 * @return the output for a tree node 690 */ 691 private String getNode(String path, String title, int type, boolean folder, CmsResourceState state, boolean grey) { 692 693 StringBuffer result = new StringBuffer(64); 694 String parent = CmsResource.getParentFolder(path); 695 result.append("parent.aC(\""); 696 // name 697 result.append(title); 698 result.append("\","); 699 // type 700 result.append(type); 701 result.append(","); 702 // folder 703 if (folder) { 704 result.append(1); 705 } else { 706 result.append(0); 707 } 708 result.append(","); 709 // hashcode of path 710 result.append(path.hashCode()); 711 result.append(","); 712 // hashcode of parent path 713 result.append((parent != null) ? parent.hashCode() : 0); 714 result.append(","); 715 // resource state 716 result.append(state); 717 result.append(","); 718 // project status 719 if (grey) { 720 result.append(1); 721 } else { 722 result.append(0); 723 } 724 result.append(");\n"); 725 return result.toString(); 726 } 727 728 /** 729 * Creates a node entry for the root node of the current site.<p> 730 * 731 * @return a node entry for the root node of the current site 732 */ 733 private String getRootNode() { 734 735 CmsResource resource = null; 736 String title = null; 737 String folder = getRootFolder(); 738 try { 739 resource = getCms().readFolder(folder, CmsResourceFilter.IGNORE_EXPIRATION); 740 // get the title information of the folder 741 CmsProperty titleProperty = getCms().readPropertyObject( 742 folder, 743 CmsPropertyDefinition.PROPERTY_TITLE, 744 false); 745 746 if ((titleProperty == null) || titleProperty.isNullProperty()) { 747 getCms().getSitePath(resource); 748 title = resource.getRootPath(); 749 } else { 750 title = titleProperty.getValue(); 751 } 752 return getNode(resource.getRootPath(), title, resource.getTypeId(), true, resource.getState(), false); 753 } catch (CmsException e) { 754 // should usually never happen 755 if (LOG.isInfoEnabled()) { 756 LOG.info(e.getLocalizedMessage(), e); 757 } 758 } 759 return ""; 760 } 761 762 /** 763 * Calculates the prefix that has to be added when selecting a resource in a popup tree window.<p> 764 * 765 * This is needed for the link dialog in editors 766 * as well as the copy, move and link popup dialogs for resources in the VFS.<p> 767 * 768 * @param prefix the current prefix of the resource 769 * @param storedSiteRoot the site root in which the workplace (not the tree!) is 770 * @return the prefix which is added to the resource name 771 */ 772 private String getSitePrefix(String prefix, String storedSiteRoot) { 773 774 if (OpenCms.getSiteManager().isSharedFolder(prefix)) { 775 return prefix; 776 } 777 if (TYPE_PAGELINK.equals(getTreeType())) { 778 // in editor link dialog, create a special prefix for internal links 779 if (!storedSiteRoot.equals(prefix)) { 780 // stored site is not selected site, create complete URL as prefix 781 CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(prefix); 782 prefix = getCms().getRequestContext().removeSiteRoot(prefix); 783 prefix = site.getUrl() + OpenCms.getSystemInfo().getOpenCmsContext() + prefix; 784 } else { 785 // stored site is selected site, don't show prefix at all 786 prefix = ""; 787 } 788 789 } else if (TYPE_COPY.equals(getTreeType()) 790 || TYPE_SIBLING.equals(getTreeType()) 791 || TYPE_VFSWIDGET.equals(getTreeType())) { 792 // in vfs copy|move|link or vfs widget mode, don't add the prefix for the current workplace site 793 if (storedSiteRoot.equals(prefix)) { 794 prefix = ""; 795 } 796 } else if (TYPE_PREFERENCES.equals(getTreeType())) { 797 prefix = ""; 798 } 799 800 return prefix; 801 } 802 803 /** 804 * Returns the name of the start folder (or "last known" folder) to be loaded.<p> 805 * 806 * @return the name of the start folder (or "last known" folder) to be loaded 807 */ 808 private String getStartFolder() { 809 810 return m_startFolder; 811 } 812 813 /** 814 * Returns the target folder name.<p> 815 * 816 * @return the target folder name 817 */ 818 private String getTargetFolder() { 819 820 return m_targetFolder; 821 } 822 823 /** 824 * Returns true if a complete new tree must be loaded, false if an existing 825 * tree is updated or extended.<p> 826 * 827 * @return true if a complete new tree must be loaded 828 */ 829 private boolean newTree() { 830 831 return m_newTree; 832 } 833 834 /** 835 * Creates error information output.<p> 836 * 837 * @param t an error that occurred 838 * @return error information output 839 */ 840 private String printError(Throwable t) { 841 842 StringBuffer result = new StringBuffer(1024); 843 result.append("/*\n"); 844 result.append(CmsStringUtil.escapeHtml(t.getMessage())); 845 result.append("\n*/\n"); 846 result.append("function init() {\n"); 847 result.append("}\n"); 848 return result.toString(); 849 } 850 851 /** 852 * Sets the value to indicate if only folders or files and folders should be included in the tree.<p> 853 * 854 * @param includeFiles if true if files and folders should be included in the tree 855 */ 856 private void setIncludeFiles(boolean includeFiles) { 857 858 m_includeFiles = includeFiles; 859 } 860 861 /** 862 * Sets if a complete tree must be loaded.<p> 863 * 864 * @param newTree if true, a complete tree must be loaded 865 */ 866 private void setNewTree(boolean newTree) { 867 868 m_newTree = newTree; 869 } 870 871 /** 872 * Sets if the site selector should be shown depending on the tree type and the count of accessible sites.<p> 873 * 874 * @param showSiteSelector true if site selector should be shown, otherwise false 875 */ 876 private void setShowSiteSelector(boolean showSiteSelector) { 877 878 m_showSiteSelector = showSiteSelector; 879 } 880 881 /** 882 * Sets the name of the start folder (or "last known" folder) to be loaded.<p> 883 * 884 * @param startFolder the name of the start folder (or "last known" folder) to be loaded 885 */ 886 private void setStartFolder(String startFolder) { 887 888 m_startFolder = startFolder; 889 } 890 891 /** 892 * Sets the target folder name.<p> 893 * 894 * @param targetFolder the target folder name 895 */ 896 private void setTargetFolder(String targetFolder) { 897 898 m_targetFolder = targetFolder; 899 } 900 901 /** 902 * Sets the type of this tree.<p> 903 * 904 * @param type the type of this tree 905 */ 906 private void setTreeType(String type) { 907 908 m_treeType = type; 909 } 910}