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, 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.ui.dialogs; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.file.CmsResource.CmsResourceCopyMode; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.CmsVfsException; 035import org.opencms.file.types.CmsResourceTypeFolderSubSitemap; 036import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 037import org.opencms.i18n.tools.CmsContainerPageCopier; 038import org.opencms.i18n.tools.CmsContainerPageCopier.NoCustomReplacementException; 039import org.opencms.lock.CmsLockActionRecord; 040import org.opencms.lock.CmsLockUtil; 041import org.opencms.main.CmsException; 042import org.opencms.main.CmsIllegalArgumentException; 043import org.opencms.main.CmsLog; 044import org.opencms.main.OpenCms; 045import org.opencms.security.CmsSecurityException; 046import org.opencms.staticexport.CmsLinkManager; 047import org.opencms.ui.A_CmsUI; 048import org.opencms.ui.CmsVaadinUtils; 049import org.opencms.ui.I_CmsDialogContext; 050import org.opencms.ui.apps.sitemanager.CmsSiteManager; 051import org.opencms.ui.components.CmsBasicDialog; 052import org.opencms.ui.components.CmsConfirmationDialog; 053import org.opencms.ui.components.CmsErrorDialog; 054import org.opencms.ui.components.CmsMacroResolverDialog; 055import org.opencms.ui.components.CmsOkCancelActionHandler; 056import org.opencms.ui.components.fileselect.CmsPathSelectField; 057import org.opencms.util.CmsMacroResolver; 058import org.opencms.util.CmsStringUtil; 059import org.opencms.util.CmsUUID; 060 061import java.util.ArrayList; 062import java.util.Arrays; 063import java.util.Collections; 064import java.util.HashMap; 065import java.util.HashSet; 066import java.util.List; 067import java.util.Map; 068import java.util.Set; 069 070import org.apache.commons.logging.Log; 071 072import com.vaadin.ui.Button; 073import com.vaadin.ui.Button.ClickEvent; 074import com.vaadin.ui.Button.ClickListener; 075import com.vaadin.ui.FormLayout; 076import com.vaadin.ui.UI; 077import com.vaadin.ui.Window; 078import com.vaadin.v7.ui.CheckBox; 079import com.vaadin.v7.ui.ComboBox; 080import com.vaadin.v7.ui.ComboBox.ItemStyleGenerator; 081 082/** 083 * The copy move dialog.<p> 084 */ 085@SuppressWarnings("deprecation") 086public class CmsCopyMoveDialog extends CmsBasicDialog { 087 088 /** The copy/move actions. */ 089 public static enum Action { 090 091 /** Copy container page automatic mode. */ 092 container_page_automatic, 093 /** Copy container page including referenced elements. */ 094 container_page_copy, 095 /** Copy container page reuse referenced elements. */ 096 container_page_reuse, 097 /** Copy resources as new. */ 098 copy_all, 099 /** Create siblings. */ 100 copy_sibling_all, 101 /** Copy and preserve siblings. */ 102 copy_sibling_mixed, 103 /** Move resources. */ 104 move, 105 /** Copy sub sitemap, adjust internal links. */ 106 sub_sitemap; 107 } 108 109 /** The dialog mode. */ 110 public static enum DialogMode { 111 /** Allow copy only. */ 112 copy, 113 /** Allow copy and move. */ 114 copy_and_move, 115 /** Allow move only. */ 116 move 117 } 118 119 /** Logger instance for this class. */ 120 static final Log LOG = CmsLog.getLog(CmsCopyMoveDialog.class); 121 122 /** The serial version id. */ 123 private static final long serialVersionUID = 1L; 124 125 /** The default actions. */ 126 List<Action> m_defaultActions; 127 128 /** The action radio buttons. */ 129 private ComboBox m_actionCombo; 130 131 /** The cancel button. */ 132 private Button m_cancelButton; 133 134 /** The cms context. */ 135 private CmsObject m_cms; 136 137 /** The dialog context. */ 138 private I_CmsDialogContext m_context; 139 140 /** Flag indicating the move option is allowed. */ 141 private DialogMode m_dialogMode; 142 143 /** Indicates the copy folder has a default file of the type container page. */ 144 private boolean m_hasContainerPageDefaultFile; 145 146 /**Dialog for editing key value pairs used as macros. Only used for sitemap folder*/ 147 private CmsMacroResolverDialog m_macroDialog; 148 149 /** The OK button. */ 150 private Button m_okButton; 151 152 /** The overwrite existing resources checkbox. */ 153 private CheckBox m_overwriteExisting; 154 155 /** The root cms context. */ 156 private CmsObject m_rootCms; 157 158 /** The target path select field. */ 159 private CmsPathSelectField m_targetPath; 160 161 /** The resources to update after dialog close. */ 162 private Set<CmsUUID> m_updateResources; 163 164 /** 165 * Constructor.<p> 166 * 167 * @param context the dialog context 168 * @param mode the dialog mode 169 */ 170 public CmsCopyMoveDialog(final I_CmsDialogContext context, DialogMode mode) { 171 172 m_dialogMode = mode; 173 m_updateResources = new HashSet<CmsUUID>(); 174 m_context = context; 175 m_defaultActions = new ArrayList<Action>(); 176 displayResourceInfo(context.getResources()); 177 FormLayout form = initForm(); 178 setContent(form); 179 updateDefaultActions(null); 180 m_okButton = new Button(CmsVaadinUtils.getMessageText(org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_OK_0)); 181 m_okButton.addClickListener(new ClickListener() { 182 183 private static final long serialVersionUID = 1L; 184 185 public void buttonClick(ClickEvent event) { 186 187 submit(false, null); 188 } 189 }); 190 addButton(m_okButton); 191 m_cancelButton = new Button( 192 CmsVaadinUtils.getMessageText(org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_CANCEL_0)); 193 m_cancelButton.addClickListener(new ClickListener() { 194 195 private static final long serialVersionUID = 1L; 196 197 public void buttonClick(ClickEvent event) { 198 199 cancel(); 200 } 201 }); 202 addButton(m_cancelButton); 203 setActionHandler(new CmsOkCancelActionHandler() { 204 205 private static final long serialVersionUID = 1L; 206 207 @Override 208 protected void cancel() { 209 210 CmsCopyMoveDialog.this.cancel(); 211 } 212 213 @Override 214 protected void ok() { 215 216 submit(false, null); 217 } 218 }); 219 } 220 221 /** 222 * Preselects the target folder.<p> 223 * 224 * @param structureId the target structure id 225 * 226 * @throws CmsException in case the target can not be read or is not a folder 227 */ 228 public void setTargetFolder(CmsUUID structureId) throws CmsException { 229 230 CmsObject cms = A_CmsUI.getCmsObject(); 231 CmsResource res = cms.readResource(structureId); 232 setTargetForlder(res); 233 } 234 235 /** 236 * Preselects the target folder.<p> 237 * 238 * @param resource the target resource 239 */ 240 public void setTargetForlder(CmsResource resource) { 241 242 if (resource.isFolder()) { 243 if (m_context.getResources().size() == 1) { 244 try { 245 if (m_dialogMode.equals(DialogMode.copy) 246 | (m_dialogMode.equals(DialogMode.copy_and_move) 247 && CmsResource.getParentFolder(m_context.getResources().get(0).getRootPath()).equals( 248 resource.getRootPath()))) { 249 m_targetPath.setValue(getTargetName(m_context.getResources().get(0), resource)); 250 } else { 251 252 m_targetPath.setValue( 253 getCms().getSitePath(resource) + getTargetName(m_context.getResources().get(0), resource)); 254 } 255 } catch (CmsException e) { 256 m_targetPath.setValue(getCms().getSitePath(resource)); 257 } 258 } else { 259 m_targetPath.setValue(getCms().getSitePath(resource)); 260 } 261 262 updateDefaultActions(resource.getRootPath()); 263 } else { 264 throw new CmsIllegalArgumentException( 265 org.opencms.workplace.commons.Messages.get().container( 266 org.opencms.workplace.commons.Messages.ERR_COPY_MULTI_TARGET_NOFOLDER_1, 267 A_CmsUI.getCmsObject().getSitePath(resource))); 268 } 269 } 270 271 /** 272 * Get bunle values from dialog.<p> 273 * 274 * @return map of key-value pairs to be resolved as macro. if null or empty, then ignored 275 */ 276 protected Map<String, String> getMacroMap() { 277 278 return m_macroDialog.getMacroMap(); 279 } 280 281 /** 282 * Performs the single resource operation.<p> 283 * 284 * @param source the source 285 * @param target the target 286 * @param action the action 287 * @param overwrite if existing resources should be overwritten 288 * @param makroMap map of key-value pairs to be resolved as macro. if null or empty, then ignored 289 * 290 * @throws CmsException in case the operation fails 291 */ 292 protected void performSingleOperation( 293 CmsResource source, 294 CmsResource target, 295 Action action, 296 boolean overwrite, 297 Map<String, String> makroMap) 298 throws CmsException { 299 300 performSingleOperation(source, target, getTargetName(source, target), action, overwrite, makroMap); 301 } 302 303 /** 304 * Performs the single resource operation.<p> 305 * 306 * @param source the source 307 * @param target the target folder 308 * @param name the target resource name 309 * @param action the action 310 * @param overwrite if existing resources should be overwritten 311 * @param macroMap map of key-value pairs to be resolved as macro. if null or empty, then ignored 312 * 313 * @throws CmsException in case the operation fails 314 */ 315 protected void performSingleOperation( 316 CmsResource source, 317 CmsResource target, 318 String name, 319 Action action, 320 boolean overwrite, 321 Map<String, String> macroMap) 322 throws CmsException { 323 324 // add new parent and source to the update resources 325 m_updateResources.add(target.getStructureId()); 326 m_updateResources.add(source.getStructureId()); 327 328 String finalTarget = target.getRootPath(); 329 if (finalTarget.equals(source.getRootPath()) || finalTarget.startsWith(source.getRootPath())) { 330 throw new CmsVfsException( 331 org.opencms.workplace.commons.Messages.get().container( 332 org.opencms.workplace.commons.Messages.ERR_COPY_ONTO_ITSELF_1, 333 finalTarget)); 334 } 335 finalTarget = CmsStringUtil.joinPaths(finalTarget, name); 336 // delete existing target resource if selected or confirmed by the user 337 if (overwrite && getRootCms().existsResource(finalTarget, CmsResourceFilter.ONLY_VISIBLE)) { 338 CmsLockUtil.ensureLock( 339 getRootCms(), 340 getRootCms().readResource(finalTarget, CmsResourceFilter.ONLY_VISIBLE)); 341 if (getRootCms().existsResource(finalTarget, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { 342 if ((action != Action.container_page_automatic) 343 && (action != Action.container_page_copy) 344 && (action != Action.container_page_reuse)) { 345 // container page copy modes don't just call copyResource(), they need special handling for the overwrite case 346 getRootCms().deleteResource(finalTarget, CmsResource.DELETE_PRESERVE_SIBLINGS); 347 } 348 } 349 } 350 // copy the resource 351 if (action == Action.move) { 352 // add former parent to the update resources 353 CmsResource parent = getRootCms().readParentFolder(source.getStructureId()); 354 m_updateResources.add(parent.getStructureId()); 355 CmsLockActionRecord lockRecord = CmsLockUtil.ensureLock(getRootCms(), source); 356 getRootCms().moveResource(source.getRootPath(), finalTarget); 357 if (lockRecord.getChange() == CmsLockActionRecord.LockChange.locked) { 358 getRootCms().unlockResource(finalTarget); 359 } 360 } else if ((action == Action.container_page_automatic) 361 || (action == Action.container_page_copy) 362 || (action == Action.container_page_reuse)) { 363 CmsContainerPageCopier copier = new CmsContainerPageCopier(m_context.getCms()); 364 try { 365 366 CmsContainerPageCopier.CopyMode mode = action == Action.container_page_automatic 367 ? CmsContainerPageCopier.CopyMode.automatic 368 : (action == Action.container_page_copy 369 ? CmsContainerPageCopier.CopyMode.smartCopyAndChangeLocale 370 : CmsContainerPageCopier.CopyMode.reuse); 371 copier.setCopyMode(mode); 372 copier.run(m_context.getResources().get(0), target, name); 373 m_context.finish( 374 Arrays.asList( 375 copier.getTargetFolder().getStructureId(), 376 copier.getCopiedFolderOrPage().getStructureId())); 377 } catch (CmsException e) { 378 m_context.error(e); 379 } catch (NoCustomReplacementException e) { 380 String errorMessage = CmsVaadinUtils.getMessageText( 381 org.opencms.ui.Messages.GUI_COPYPAGE_NO_REPLACEMENT_FOUND_1, 382 e.getResource().getRootPath()); 383 CmsErrorDialog.showErrorDialog(errorMessage, e); 384 } 385 } else { 386 387 CmsResourceCopyMode copyMode = null; 388 switch ((Action)m_actionCombo.getValue()) { 389 case copy_all: 390 copyMode = CmsResource.COPY_AS_NEW; 391 break; 392 case copy_sibling_all: 393 copyMode = CmsResource.COPY_AS_SIBLING; 394 break; 395 case copy_sibling_mixed: 396 case sub_sitemap: 397 default: 398 copyMode = CmsResource.COPY_PRESERVE_SIBLING; 399 } 400 401 //Copies resources. Adjust links if action==Action.sub_sitemap, resolves macro if marcoMap if not null or empty 402 CmsMacroResolver.copyAndResolveMacro( 403 getRootCms(), 404 source.getRootPath(), 405 finalTarget, 406 macroMap, 407 action == Action.sub_sitemap, 408 copyMode); 409 410 getRootCms().unlockResource(finalTarget); 411 412 CmsResource copyResource = getRootCms().readResource(finalTarget, CmsResourceFilter.IGNORE_EXPIRATION); 413 m_updateResources.add(copyResource.getStructureId()); 414 } 415 } 416 417 /** 418 * Updates the 'overwrite existing' checkbox state depending on the currently selected mode.<p> 419 */ 420 protected void updateOverwriteExisting() { 421 422 if (m_overwriteExisting != null) { 423 boolean move = (m_dialogMode == DialogMode.move) || (m_actionCombo.getValue() == Action.move); 424 if (move) { 425 m_overwriteExisting.setValue(Boolean.FALSE); 426 m_overwriteExisting.setVisible(false); 427 } else { 428 m_overwriteExisting.setVisible(true); 429 } 430 } 431 } 432 433 /** 434 * Cancels the dialog action.<p> 435 */ 436 void cancel() { 437 438 m_context.finish(Collections.<CmsUUID> emptyList()); 439 } 440 441 /** 442 * Submits the dialog action.<p> 443 * 444 * @param overwrite to forcefully overwrite existing files 445 * @param makroMap map of key-value pairs to be resolved as macro. if null or empty, then ignored 446 */ 447 void submit(boolean overwrite, Map<String, String> makroMap) { 448 449 try { 450 CmsResource targetFolder = null; 451 String targetName = null; 452 String target = m_targetPath.getValue(); 453 boolean isSingleResource = m_context.getResources().size() == 1; 454 // resolve relative paths 455 target = CmsLinkManager.getAbsoluteUri( 456 target, 457 CmsResource.getParentFolder(getCms().getSitePath(m_context.getResources().get(0)))); 458 459 // check if the given path is a root path 460 CmsObject cms = OpenCms.getSiteManager().getSiteForRootPath(target) != null ? getRootCms() : getCms(); 461 462 if (cms.existsResource(target, CmsResourceFilter.ALL.addRequireFolder())) { 463 // The target is an existing folder 464 // always copy files into that folder 465 targetFolder = cms.readResource(target); 466 } else if (cms.existsResource(target, CmsResourceFilter.ALL.addRequireFile())) { 467 // The target is an existing file 468 if (isSingleResource) { 469 // Replace the file with the resource copied, if it is just a single resource 470 if (target.equals(m_context.getResources().get(0).getRootPath())) { 471 throw new CmsVfsException( 472 org.opencms.workplace.commons.Messages.get().container( 473 org.opencms.workplace.commons.Messages.ERR_COPY_ONTO_ITSELF_1, 474 target)); 475 } 476 targetName = CmsResource.getName(target); 477 targetFolder = cms.readResource(CmsResource.getParentFolder(target)); 478 } else { 479 // Throw an error if a single file should be replaced with multiple resources 480 // since we cannot copy multiple resources to a single file 481 throw new CmsVfsException( 482 org.opencms.workplace.commons.Messages.get().container( 483 org.opencms.workplace.commons.Messages.ERR_COPY_MULTI_TARGET_NOFOLDER_1, 484 target)); 485 } 486 } else { 487 // The target does not exist 488 if (isSingleResource) { 489 // If we have a single resource, we could possible create the target as copy of that resource 490 if (cms.existsResource( 491 CmsResource.getParentFolder(target), 492 CmsResourceFilter.ALL.addRequireFolder())) { 493 targetName = CmsResource.getName(target); 494 targetFolder = cms.readResource(CmsResource.getParentFolder(target)); 495 } else { 496 // If the parent folder of the resource does not exist, we will not create it automatically. 497 // Thus we need to throw an exception. 498 throw new CmsVfsException( 499 org.opencms.workplace.commons.Messages.get().container( 500 org.opencms.workplace.commons.Messages.ERR_COPY_TARGET_PARENT_FOLDER_MISSING_1, 501 target)); 502 } 503 } else { 504 // We cannot copy multiple resources to a single resource 505 throw new CmsVfsException( 506 org.opencms.workplace.commons.Messages.get().container( 507 org.opencms.workplace.commons.Messages.ERR_COPY_MULTI_TARGET_NOFOLDER_1, 508 target)); 509 } 510 } 511 512 Action action = m_actionCombo != null ? (Action)m_actionCombo.getValue() : Action.move; 513 514 overwrite = overwrite || isOverwriteExisting(); 515 if (!overwrite || action.equals(Action.move)) { 516 List<CmsResource> collidingResources = getExistingFileCollisions(targetFolder, targetName); 517 if (collidingResources != null) { 518 if (action.equals(Action.move)) { 519 throw new CmsVfsException( 520 org.opencms.workplace.commons.Messages.get().container( 521 org.opencms.workplace.commons.Messages.ERR_MOVE_FORCES_OVERWRITE_EXISTING_RESOURCE_0)); 522 } else { 523 showConfirmOverwrite(collidingResources); 524 return; 525 } 526 } 527 } 528 Map<CmsResource, CmsException> errors = new HashMap<CmsResource, CmsException>(); 529 530 //Check if dialog for macro resolver has to be shown: action correct?, makroMap==null (default, not set by dialog yet) 531 if ((action == Action.sub_sitemap) & (makroMap == null)) { 532 if (CmsSiteManager.isFolderWithMacros(getRootCms(), m_context.getResources().get(0).getRootPath())) { 533 showMacroResolverDialog(m_context.getResources().get(0)); 534 return; 535 } 536 } 537 if (targetName == null) { 538 for (CmsResource source : m_context.getResources()) { 539 try { 540 performSingleOperation(source, targetFolder, action, overwrite, makroMap); 541 } catch (CmsException e) { 542 errors.put(source, e); 543 LOG.error( 544 "Error while executing " 545 + action 546 + " on resource " 547 + source.getRootPath(), 548 e); 549 } 550 } 551 } else { 552 // this will only be the case in a single resource scenario 553 CmsResource source = m_context.getResources().get(0); 554 try { 555 performSingleOperation(source, targetFolder, targetName, action, overwrite, makroMap); 556 } catch (CmsException e) { 557 errors.put(source, e); 558 LOG.error( 559 "Error while executing " 560 + m_actionCombo.getValue().toString() 561 + " on resource " 562 + source.getRootPath(), 563 e); 564 } 565 } 566 567 if (!errors.isEmpty()) { 568 if (m_context instanceof CmsEmbeddedDialogContext) { 569 // In ADE, finish() would trigger a reload and cause the error message to not be displayed, 570 // and we can only trigger the dialog for a single resource there anyway 571 m_context.error(errors.values().iterator().next()); 572 } else { 573 m_context.finish(m_updateResources); 574 m_context.error(errors.values().iterator().next()); 575 } 576 } else { 577 m_context.finish(m_updateResources); 578 } 579 580 } catch (CmsException e) { 581 m_context.error(e); 582 } 583 } 584 585 /** 586 * Returns the cms context.<p> 587 * 588 * @return the cms context 589 */ 590 private CmsObject getCms() { 591 592 if (m_cms == null) { 593 m_cms = A_CmsUI.getCmsObject(); 594 } 595 return m_cms; 596 } 597 598 /** 599 * Returns the resources that collide with already existing resources.<p> 600 * 601 * @param targetFolder the target folder 602 * @param targetName name of the target if a single file's copy should be named differently 603 * 604 * @return the colliding resources or <code>null</code> if no collisions found 605 * 606 * @throws CmsException in case the checking the resources fails 607 */ 608 private List<CmsResource> getExistingFileCollisions(CmsResource targetFolder, String targetName) 609 throws CmsException { 610 611 List<CmsResource> collidingResources = new ArrayList<CmsResource>(); 612 613 String finalTarget = targetFolder.getRootPath(); 614 if (!finalTarget.endsWith("/")) { 615 finalTarget += "/"; 616 } 617 if (targetName == null) { 618 for (CmsResource source : m_context.getResources()) { 619 if (finalTarget.equals(CmsResource.getParentFolder(source.getRootPath()))) { 620 // copying to the same folder, a new name will be generated 621 return null; 622 } 623 String fileName = finalTarget + source.getName(); 624 if (getRootCms().existsResource(fileName, CmsResourceFilter.ALL)) { 625 collidingResources.add(source); 626 } 627 } 628 } else { 629 String fileName = finalTarget + targetName; 630 if (getRootCms().existsResource(fileName, CmsResourceFilter.ALL)) { 631 collidingResources.add(getRootCms().readResource(fileName, CmsResourceFilter.ALL)); 632 } 633 } 634 return collidingResources.isEmpty() ? null : collidingResources; 635 } 636 637 /** 638 * Returns the root cms context.<p> 639 * 640 * @return the root cms context 641 * 642 * @throws CmsException in case initializing the context fails 643 */ 644 private CmsObject getRootCms() throws CmsException { 645 646 if (m_rootCms == null) { 647 m_rootCms = OpenCms.initCmsObject(getCms()); 648 m_rootCms.getRequestContext().setSiteRoot("/"); 649 } 650 return m_rootCms; 651 } 652 653 /** 654 * Gets a name for the target resource.<p> 655 * 656 * @param source Source 657 * @param target Target 658 * @return Name 659 * @throws CmsException exception 660 */ 661 private String getTargetName(CmsResource source, CmsResource target) throws CmsException { 662 663 String name; 664 String folderRootPath = target.getRootPath(); 665 if (!folderRootPath.endsWith("/")) { 666 folderRootPath += "/"; 667 } 668 if (folderRootPath.equals(CmsResource.getParentFolder(source.getRootPath()))) { 669 name = OpenCms.getResourceManager().getNameGenerator().getCopyFileName( 670 getRootCms(), 671 folderRootPath, 672 source.getName()); 673 } else { 674 name = source.getName(); 675 } 676 return name; 677 } 678 679 /** 680 * Checks whether the folder has a default file of the type container page.<p> 681 * 682 * @param folder the folder to check 683 * 684 * @return <code>true</code> if the folder has a default file of the type container page 685 */ 686 private boolean hasContainerPageDefaultFile(CmsResource folder) { 687 688 try { 689 CmsResource defaultFile = A_CmsUI.getCmsObject().readDefaultFile( 690 folder, 691 CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 692 return (defaultFile != null) && CmsResourceTypeXmlContainerPage.isContainerPage(defaultFile); 693 } catch (CmsSecurityException e) { 694 return false; 695 } 696 } 697 698 /** 699 * Initializes the form fields.<p> 700 * 701 * @return the form component 702 */ 703 private FormLayout initForm() { 704 705 FormLayout form = new FormLayout(); 706 form.setWidth("100%"); 707 m_targetPath = new CmsPathSelectField(); 708 m_targetPath.setCaption( 709 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_TARGET_0)); 710 m_targetPath.setFileSelectCaption( 711 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_SELECT_TARGET_CAPTION_0)); 712 m_targetPath.setResourceFilter(CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireFolder()); 713 m_targetPath.setWidth("100%"); 714 form.addComponent(m_targetPath); 715 716 if (m_dialogMode != DialogMode.move) { 717 m_actionCombo = new ComboBox(); 718 m_actionCombo.setCaption(CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_COPYPAGE_COPY_MODE_0)); 719 m_actionCombo.setNullSelectionAllowed(false); 720 m_actionCombo.setNewItemsAllowed(false); 721 m_actionCombo.setWidth("100%"); 722 if (m_context.getResources().size() == 1) { 723 if (m_context.getResources().get(0).isFile()) { 724 m_actionCombo.addItem(Action.copy_all); 725 m_actionCombo.setItemCaption( 726 Action.copy_all, 727 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_AS_NEW_0)); 728 m_actionCombo.addItem(Action.copy_sibling_all); 729 m_actionCombo.setItemCaption( 730 Action.copy_sibling_all, 731 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_CREATE_SIBLING_0)); 732 if (m_dialogMode == DialogMode.copy_and_move) { 733 m_actionCombo.addItem(Action.move); 734 m_actionCombo.setItemCaption( 735 Action.move, 736 CmsVaadinUtils.getMessageText( 737 org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_MOVE_FILE_0)); 738 } 739 } else { 740 CmsResource folder = m_context.getResources().get(0); 741 m_hasContainerPageDefaultFile = hasContainerPageDefaultFile(folder); 742 if (m_hasContainerPageDefaultFile) { 743 m_actionCombo.addItem(Action.container_page_automatic); 744 m_actionCombo.setItemCaption( 745 Action.container_page_automatic, 746 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_AUTOMATIC_0)); 747 m_actionCombo.addItem(Action.container_page_copy); 748 m_actionCombo.setItemCaption( 749 Action.container_page_copy, 750 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONTAINERPAGE_COPY_0)); 751 m_actionCombo.addItem(Action.container_page_reuse); 752 m_actionCombo.setItemCaption( 753 Action.container_page_reuse, 754 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONTAINERPAGE_REUSE_0)); 755 } 756 if (CmsResourceTypeFolderSubSitemap.isSubSitemap(folder)) { 757 m_actionCombo.addItem(Action.sub_sitemap); 758 m_actionCombo.setItemCaption( 759 Action.sub_sitemap, 760 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_SUBSITEMAP_0)); 761 } 762 m_actionCombo.addItem(Action.copy_sibling_mixed); 763 m_actionCombo.setItemCaption( 764 Action.copy_sibling_mixed, 765 CmsVaadinUtils.getMessageText( 766 org.opencms.workplace.commons.Messages.GUI_COPY_ALL_NO_SIBLINGS_0)); 767 m_actionCombo.addItem(Action.copy_all); 768 m_actionCombo.setItemCaption( 769 Action.copy_all, 770 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_ALL_0)); 771 m_actionCombo.addItem(Action.copy_sibling_all); 772 m_actionCombo.setItemCaption( 773 Action.copy_sibling_all, 774 CmsVaadinUtils.getMessageText( 775 org.opencms.workplace.commons.Messages.GUI_COPY_MULTI_CREATE_SIBLINGS_0)); 776 if (m_dialogMode == DialogMode.copy_and_move) { 777 m_actionCombo.addItem(Action.move); 778 m_actionCombo.setItemCaption( 779 Action.move, 780 CmsVaadinUtils.getMessageText( 781 org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_MOVE_FOLDER_0)); 782 } 783 } 784 } else { 785 m_actionCombo.addItem(Action.copy_sibling_mixed); 786 m_actionCombo.setItemCaption( 787 Action.copy_sibling_mixed, 788 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_ALL_NO_SIBLINGS_0)); 789 m_actionCombo.addItem(Action.copy_all); 790 m_actionCombo.setItemCaption( 791 Action.copy_all, 792 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_ALL_0)); 793 m_actionCombo.addItem(Action.copy_sibling_all); 794 m_actionCombo.setItemCaption( 795 Action.copy_sibling_all, 796 CmsVaadinUtils.getMessageText( 797 org.opencms.workplace.commons.Messages.GUI_COPY_MULTI_CREATE_SIBLINGS_0)); 798 if (m_dialogMode == DialogMode.copy_and_move) { 799 m_actionCombo.addItem(Action.move); 800 m_actionCombo.setItemCaption( 801 Action.move, 802 CmsVaadinUtils.getMessageText( 803 org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_MOVE_RESOURCES_0)); 804 } 805 } 806 m_actionCombo.setItemStyleGenerator(new ItemStyleGenerator() { 807 808 private static final long serialVersionUID = 1L; 809 810 public String getStyle(ComboBox source, Object itemId) { 811 812 String style = null; 813 if (m_defaultActions.contains(itemId)) { 814 style = "bold"; 815 } 816 return style; 817 } 818 }); 819 form.addComponent(m_actionCombo); 820 m_actionCombo.addValueChangeListener(event -> updateOverwriteExisting()); 821 } 822 823 if (m_context.getResources().size() > 1) { 824 m_overwriteExisting = new CheckBox( 825 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_MULTI_OVERWRITE_0)); 826 m_overwriteExisting.setValue(Boolean.FALSE); 827 form.addComponent(m_overwriteExisting); 828 829 updateOverwriteExisting(); 830 } 831 832 return form; 833 } 834 835 /** 836 * Checks the overwrite existing setting.<p> 837 * 838 * @return <code>true</code> if overwrite existing is set 839 */ 840 private boolean isOverwriteExisting() { 841 842 return (m_overwriteExisting != null) && m_overwriteExisting.getValue().booleanValue(); 843 } 844 845 /** 846 * Displays the confirm overwrite dialog.<p> 847 * 848 * @param collidingResources the colliding resources 849 */ 850 private void showConfirmOverwrite(List<CmsResource> collidingResources) { 851 852 final Window window = CmsBasicDialog.prepareWindow(); 853 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONFIRM_OVERWRITE_TITLE_0)); 854 final CmsConfirmationDialog dialog = new CmsConfirmationDialog( 855 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONFIRM_OVERWRITE_MESSAGE_0), 856 new Runnable() { 857 858 public void run() { 859 860 window.close(); 861 submit(true, null); 862 } 863 }, 864 new Runnable() { 865 866 public void run() { 867 868 window.close(); 869 cancel(); 870 } 871 }); 872 dialog.displayResourceInfo(collidingResources); 873 window.setContent(dialog); 874 UI.getCurrent().addWindow(window); 875 } 876 877 /** 878 * Displays the resolve macro dialog.<p> 879 * 880 * @param resource to be copied. 881 */ 882 private void showMacroResolverDialog(CmsResource resource) { 883 884 final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide); 885 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_SET_MACRO_VALUES_TITLE_0)); 886 m_macroDialog = new CmsMacroResolverDialog(new Runnable() { 887 888 public void run() { 889 890 Map<String, String> map = getMacroMap(); 891 window.close(); 892 submit(true, map); //Overwrite true because this was checked first. If no overwrite, window is closed and this code isn't called 893 } 894 }, new Runnable() { 895 896 public void run() { 897 898 window.close(); 899 cancel(); 900 } 901 }, resource); 902 m_macroDialog.displayResourceInfo(Collections.singletonList(resource)); 903 window.setContent(m_macroDialog); 904 UI.getCurrent().addWindow(window); 905 } 906 907 /** 908 * Updates the default dialog actions.<p> 909 * 910 * @param targetRootPath the target root path 911 */ 912 private void updateDefaultActions(String targetRootPath) { 913 914 if (m_actionCombo != null) { 915 m_defaultActions.clear(); 916 String resPath = m_context.getResources().get(0).getRootPath(); 917 String parentFolder = CmsResource.getParentFolder(resPath); 918 if ((DialogMode.copy_and_move == m_dialogMode) && !parentFolder.equals(targetRootPath)) { 919 m_defaultActions.clear(); 920 m_defaultActions.add(Action.move); 921 } else if (m_context.getResources().size() == 1) { 922 if (m_context.getResources().get(0).isFile()) { 923 m_defaultActions.add(Action.copy_all); 924 } else { 925 m_defaultActions.add(Action.copy_sibling_mixed); 926 if (m_hasContainerPageDefaultFile) { 927 m_defaultActions.clear(); 928 m_defaultActions.add(Action.container_page_automatic); 929 m_defaultActions.add(Action.container_page_copy); 930 m_defaultActions.add(Action.container_page_reuse); 931 } 932 CmsResource folder = m_context.getResources().get(0); 933 if (CmsResourceTypeFolderSubSitemap.isSubSitemap(folder)) { 934 m_defaultActions.clear(); 935 m_defaultActions.add(Action.sub_sitemap); 936 } 937 } 938 } else { 939 m_defaultActions.add(Action.copy_sibling_mixed); 940 } 941 if (!m_defaultActions.isEmpty()) { 942 m_actionCombo.setValue(m_defaultActions.get(0)); 943 } 944 m_actionCombo.markAsDirty(); 945 } 946 } 947}