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 + m_actionCombo.getValue().toString() 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 m_context.finish(m_updateResources); 569 m_context.error(errors.values().iterator().next()); 570 } else { 571 m_context.finish(m_updateResources); 572 } 573 574 } catch (CmsException e) { 575 m_context.error(e); 576 } 577 } 578 579 /** 580 * Returns the cms context.<p> 581 * 582 * @return the cms context 583 */ 584 private CmsObject getCms() { 585 586 if (m_cms == null) { 587 m_cms = A_CmsUI.getCmsObject(); 588 } 589 return m_cms; 590 } 591 592 /** 593 * Returns the resources that collide with already existing resources.<p> 594 * 595 * @param targetFolder the target folder 596 * @param targetName name of the target if a single file's copy should be named differently 597 * 598 * @return the colliding resources or <code>null</code> if no collisions found 599 * 600 * @throws CmsException in case the checking the resources fails 601 */ 602 private List<CmsResource> getExistingFileCollisions(CmsResource targetFolder, String targetName) 603 throws CmsException { 604 605 List<CmsResource> collidingResources = new ArrayList<CmsResource>(); 606 607 String finalTarget = targetFolder.getRootPath(); 608 if (!finalTarget.endsWith("/")) { 609 finalTarget += "/"; 610 } 611 if (targetName == null) { 612 for (CmsResource source : m_context.getResources()) { 613 if (finalTarget.equals(CmsResource.getParentFolder(source.getRootPath()))) { 614 // copying to the same folder, a new name will be generated 615 return null; 616 } 617 String fileName = finalTarget + source.getName(); 618 if (getRootCms().existsResource(fileName, CmsResourceFilter.ALL)) { 619 collidingResources.add(source); 620 } 621 } 622 } else { 623 String fileName = finalTarget + targetName; 624 if (getRootCms().existsResource(fileName, CmsResourceFilter.ALL)) { 625 collidingResources.add(getRootCms().readResource(fileName, CmsResourceFilter.ALL)); 626 } 627 } 628 return collidingResources.isEmpty() ? null : collidingResources; 629 } 630 631 /** 632 * Returns the root cms context.<p> 633 * 634 * @return the root cms context 635 * 636 * @throws CmsException in case initializing the context fails 637 */ 638 private CmsObject getRootCms() throws CmsException { 639 640 if (m_rootCms == null) { 641 m_rootCms = OpenCms.initCmsObject(getCms()); 642 m_rootCms.getRequestContext().setSiteRoot("/"); 643 } 644 return m_rootCms; 645 } 646 647 /** 648 * Gets a name for the target resource.<p> 649 * 650 * @param source Source 651 * @param target Target 652 * @return Name 653 * @throws CmsException exception 654 */ 655 private String getTargetName(CmsResource source, CmsResource target) throws CmsException { 656 657 String name; 658 String folderRootPath = target.getRootPath(); 659 if (!folderRootPath.endsWith("/")) { 660 folderRootPath += "/"; 661 } 662 if (folderRootPath.equals(CmsResource.getParentFolder(source.getRootPath()))) { 663 name = OpenCms.getResourceManager().getNameGenerator().getCopyFileName( 664 getRootCms(), 665 folderRootPath, 666 source.getName()); 667 } else { 668 name = source.getName(); 669 } 670 return name; 671 } 672 673 /** 674 * Checks whether the folder has a default file of the type container page.<p> 675 * 676 * @param folder the folder to check 677 * 678 * @return <code>true</code> if the folder has a default file of the type container page 679 */ 680 private boolean hasContainerPageDefaultFile(CmsResource folder) { 681 682 try { 683 CmsResource defaultFile = A_CmsUI.getCmsObject().readDefaultFile( 684 folder, 685 CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 686 return (defaultFile != null) && CmsResourceTypeXmlContainerPage.isContainerPage(defaultFile); 687 } catch (CmsSecurityException e) { 688 return false; 689 } 690 } 691 692 /** 693 * Initializes the form fields.<p> 694 * 695 * @return the form component 696 */ 697 private FormLayout initForm() { 698 699 FormLayout form = new FormLayout(); 700 form.setWidth("100%"); 701 m_targetPath = new CmsPathSelectField(); 702 m_targetPath.setCaption( 703 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_TARGET_0)); 704 m_targetPath.setFileSelectCaption( 705 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_SELECT_TARGET_CAPTION_0)); 706 m_targetPath.setResourceFilter(CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireFolder()); 707 m_targetPath.setWidth("100%"); 708 form.addComponent(m_targetPath); 709 710 if (m_dialogMode != DialogMode.move) { 711 m_actionCombo = new ComboBox(); 712 m_actionCombo.setCaption(CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_COPYPAGE_COPY_MODE_0)); 713 m_actionCombo.setNullSelectionAllowed(false); 714 m_actionCombo.setNewItemsAllowed(false); 715 m_actionCombo.setWidth("100%"); 716 if (m_context.getResources().size() == 1) { 717 if (m_context.getResources().get(0).isFile()) { 718 m_actionCombo.addItem(Action.copy_all); 719 m_actionCombo.setItemCaption( 720 Action.copy_all, 721 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_AS_NEW_0)); 722 m_actionCombo.addItem(Action.copy_sibling_all); 723 m_actionCombo.setItemCaption( 724 Action.copy_sibling_all, 725 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_CREATE_SIBLING_0)); 726 if (m_dialogMode == DialogMode.copy_and_move) { 727 m_actionCombo.addItem(Action.move); 728 m_actionCombo.setItemCaption( 729 Action.move, 730 CmsVaadinUtils.getMessageText( 731 org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_MOVE_FILE_0)); 732 } 733 } else { 734 CmsResource folder = m_context.getResources().get(0); 735 m_hasContainerPageDefaultFile = hasContainerPageDefaultFile(folder); 736 if (m_hasContainerPageDefaultFile) { 737 m_actionCombo.addItem(Action.container_page_automatic); 738 m_actionCombo.setItemCaption( 739 Action.container_page_automatic, 740 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_AUTOMATIC_0)); 741 m_actionCombo.addItem(Action.container_page_copy); 742 m_actionCombo.setItemCaption( 743 Action.container_page_copy, 744 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONTAINERPAGE_COPY_0)); 745 m_actionCombo.addItem(Action.container_page_reuse); 746 m_actionCombo.setItemCaption( 747 Action.container_page_reuse, 748 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONTAINERPAGE_REUSE_0)); 749 } 750 if (CmsResourceTypeFolderSubSitemap.isSubSitemap(folder)) { 751 m_actionCombo.addItem(Action.sub_sitemap); 752 m_actionCombo.setItemCaption( 753 Action.sub_sitemap, 754 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_SUBSITEMAP_0)); 755 } 756 m_actionCombo.addItem(Action.copy_sibling_mixed); 757 m_actionCombo.setItemCaption( 758 Action.copy_sibling_mixed, 759 CmsVaadinUtils.getMessageText( 760 org.opencms.workplace.commons.Messages.GUI_COPY_ALL_NO_SIBLINGS_0)); 761 m_actionCombo.addItem(Action.copy_all); 762 m_actionCombo.setItemCaption( 763 Action.copy_all, 764 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_ALL_0)); 765 m_actionCombo.addItem(Action.copy_sibling_all); 766 m_actionCombo.setItemCaption( 767 Action.copy_sibling_all, 768 CmsVaadinUtils.getMessageText( 769 org.opencms.workplace.commons.Messages.GUI_COPY_MULTI_CREATE_SIBLINGS_0)); 770 if (m_dialogMode == DialogMode.copy_and_move) { 771 m_actionCombo.addItem(Action.move); 772 m_actionCombo.setItemCaption( 773 Action.move, 774 CmsVaadinUtils.getMessageText( 775 org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_MOVE_FOLDER_0)); 776 } 777 } 778 } else { 779 m_actionCombo.addItem(Action.copy_sibling_mixed); 780 m_actionCombo.setItemCaption( 781 Action.copy_sibling_mixed, 782 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_ALL_NO_SIBLINGS_0)); 783 m_actionCombo.addItem(Action.copy_all); 784 m_actionCombo.setItemCaption( 785 Action.copy_all, 786 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_ALL_0)); 787 m_actionCombo.addItem(Action.copy_sibling_all); 788 m_actionCombo.setItemCaption( 789 Action.copy_sibling_all, 790 CmsVaadinUtils.getMessageText( 791 org.opencms.workplace.commons.Messages.GUI_COPY_MULTI_CREATE_SIBLINGS_0)); 792 if (m_dialogMode == DialogMode.copy_and_move) { 793 m_actionCombo.addItem(Action.move); 794 m_actionCombo.setItemCaption( 795 Action.move, 796 CmsVaadinUtils.getMessageText( 797 org.opencms.workplace.commons.Messages.GUI_COPY_MOVE_MOVE_RESOURCES_0)); 798 } 799 } 800 m_actionCombo.setItemStyleGenerator(new ItemStyleGenerator() { 801 802 private static final long serialVersionUID = 1L; 803 804 public String getStyle(ComboBox source, Object itemId) { 805 806 String style = null; 807 if (m_defaultActions.contains(itemId)) { 808 style = "bold"; 809 } 810 return style; 811 } 812 }); 813 form.addComponent(m_actionCombo); 814 m_actionCombo.addValueChangeListener(event -> updateOverwriteExisting()); 815 } 816 817 if (m_context.getResources().size() > 1) { 818 m_overwriteExisting = new CheckBox( 819 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_COPY_MULTI_OVERWRITE_0)); 820 m_overwriteExisting.setValue(Boolean.FALSE); 821 form.addComponent(m_overwriteExisting); 822 823 updateOverwriteExisting(); 824 } 825 826 return form; 827 } 828 829 /** 830 * Checks the overwrite existing setting.<p> 831 * 832 * @return <code>true</code> if overwrite existing is set 833 */ 834 private boolean isOverwriteExisting() { 835 836 return (m_overwriteExisting != null) && m_overwriteExisting.getValue().booleanValue(); 837 } 838 839 /** 840 * Displays the confirm overwrite dialog.<p> 841 * 842 * @param collidingResources the colliding resources 843 */ 844 private void showConfirmOverwrite(List<CmsResource> collidingResources) { 845 846 final Window window = CmsBasicDialog.prepareWindow(); 847 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONFIRM_OVERWRITE_TITLE_0)); 848 final CmsConfirmationDialog dialog = new CmsConfirmationDialog( 849 CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_CONFIRM_OVERWRITE_MESSAGE_0), 850 new Runnable() { 851 852 public void run() { 853 854 window.close(); 855 submit(true, null); 856 } 857 }, 858 new Runnable() { 859 860 public void run() { 861 862 window.close(); 863 cancel(); 864 } 865 }); 866 dialog.displayResourceInfo(collidingResources); 867 window.setContent(dialog); 868 UI.getCurrent().addWindow(window); 869 } 870 871 /** 872 * Displays the resolve macro dialog.<p> 873 * 874 * @param resource to be copied. 875 */ 876 private void showMacroResolverDialog(CmsResource resource) { 877 878 final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide); 879 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_COPY_MOVE_SET_MACRO_VALUES_TITLE_0)); 880 m_macroDialog = new CmsMacroResolverDialog(new Runnable() { 881 882 public void run() { 883 884 Map<String, String> map = getMacroMap(); 885 window.close(); 886 submit(true, map); //Overwrite true because this was checked first. If no overwrite, window is closed and this code isn't called 887 } 888 }, new Runnable() { 889 890 public void run() { 891 892 window.close(); 893 cancel(); 894 } 895 }, resource); 896 m_macroDialog.displayResourceInfo(Collections.singletonList(resource)); 897 window.setContent(m_macroDialog); 898 UI.getCurrent().addWindow(window); 899 } 900 901 /** 902 * Updates the default dialog actions.<p> 903 * 904 * @param targetRootPath the target root path 905 */ 906 private void updateDefaultActions(String targetRootPath) { 907 908 if (m_actionCombo != null) { 909 m_defaultActions.clear(); 910 String resPath = m_context.getResources().get(0).getRootPath(); 911 String parentFolder = CmsResource.getParentFolder(resPath); 912 if ((DialogMode.copy_and_move == m_dialogMode) && !parentFolder.equals(targetRootPath)) { 913 m_defaultActions.clear(); 914 m_defaultActions.add(Action.move); 915 } else if (m_context.getResources().size() == 1) { 916 if (m_context.getResources().get(0).isFile()) { 917 m_defaultActions.add(Action.copy_all); 918 } else { 919 m_defaultActions.add(Action.copy_sibling_mixed); 920 if (m_hasContainerPageDefaultFile) { 921 m_defaultActions.clear(); 922 m_defaultActions.add(Action.container_page_automatic); 923 m_defaultActions.add(Action.container_page_copy); 924 m_defaultActions.add(Action.container_page_reuse); 925 } 926 CmsResource folder = m_context.getResources().get(0); 927 if (CmsResourceTypeFolderSubSitemap.isSubSitemap(folder)) { 928 m_defaultActions.clear(); 929 m_defaultActions.add(Action.sub_sitemap); 930 } 931 } 932 } else { 933 m_defaultActions.add(Action.copy_sibling_mixed); 934 } 935 if (!m_defaultActions.isEmpty()) { 936 m_actionCombo.setValue(m_defaultActions.get(0)); 937 } 938 m_actionCombo.markAsDirty(); 939 } 940 } 941}