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.tools.content; 029 030import org.opencms.file.CmsFile; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProperty; 033import org.opencms.file.CmsPropertyDefinition; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.file.types.CmsResourceTypeXmlPage; 037import org.opencms.i18n.CmsLocaleManager; 038import org.opencms.i18n.CmsMessages; 039import org.opencms.jsp.CmsJspActionElement; 040import org.opencms.loader.CmsLoaderException; 041import org.opencms.lock.CmsLock; 042import org.opencms.main.CmsException; 043import org.opencms.main.CmsLog; 044import org.opencms.main.OpenCms; 045import org.opencms.report.I_CmsReport; 046import org.opencms.util.CmsStringUtil; 047import org.opencms.workplace.CmsReport; 048import org.opencms.workplace.CmsWorkplace; 049import org.opencms.workplace.CmsWorkplaceSettings; 050import org.opencms.workplace.editors.CmsDialogElement; 051import org.opencms.workplace.explorer.CmsNewResourceXmlPage; 052import org.opencms.xml.CmsXmlException; 053import org.opencms.xml.page.CmsXmlPage; 054import org.opencms.xml.page.CmsXmlPageFactory; 055import org.opencms.xml.types.CmsXmlHtmlValue; 056 057import java.util.ArrayList; 058import java.util.HashSet; 059import java.util.Iterator; 060import java.util.List; 061import java.util.Locale; 062import java.util.Map; 063import java.util.Set; 064import java.util.StringTokenizer; 065import java.util.TreeMap; 066 067import javax.servlet.http.HttpServletRequest; 068import javax.servlet.http.HttpServletResponse; 069import javax.servlet.jsp.JspException; 070import javax.servlet.jsp.PageContext; 071 072import org.apache.commons.logging.Log; 073 074/** 075 * Provides methods for the change page element name dialog.<p> 076 * 077 * @since 6.0.0 078 */ 079public class CmsElementRename extends CmsReport { 080 081 /** A constant representing the select option all templates. */ 082 public static final String ALL = "ALL"; 083 084 /** The dialog type. */ 085 public static final String DIALOG_TYPE = "renameelement"; 086 087 /** Request parameter name for the locale. */ 088 public static final String PARAM_LOCALE = "locale"; 089 090 /** Request parameter name for the new element name. */ 091 public static final String PARAM_NEW_ELEMENT = "newelement"; 092 093 /** Request parameter name for the old element name. */ 094 public static final String PARAM_OLD_ELEMENT = "oldelement"; 095 096 /** Request parameter name for the recursive search. */ 097 public static final String PARAM_RECURSIVE = "recursive"; 098 099 /** Request parameter name for the remove empty elements. */ 100 public static final String PARAM_REMOVE_EMPTYELEMENTS = "removeemptyelements"; 101 102 /** Request parameter name for the template. */ 103 public static final String PARAM_TEMPLATE = "template"; 104 105 /** Request parameter name for the validate new element. */ 106 public static final String PARAM_VALIDATE_NEW_ELEMENT = "validatenewelement"; 107 108 /** The log object for this class. */ 109 private static final Log LOG = CmsLog.getLog(CmsElementRename.class); 110 111 /** the cms object. */ 112 private CmsObject m_cms; 113 /** the error message. */ 114 private String m_errorMessage; 115 /** the locale use for content definition. */ 116 private String m_paramLocale; 117 /** The new page element name. */ 118 private String m_paramNewElement; 119 /** The old page element name. */ 120 private String m_paramOldElement; 121 /** The recursive parameter. */ 122 private String m_paramRecursive; 123 /** the flag indicating to remove empty elements. */ 124 private String m_paramRemoveEmptyElements; 125 /** the template use for all pages (optional). */ 126 private String m_paramTemplate; 127 /** the flag indicating to remove empty elements. */ 128 private String m_paramValidateNewElement; 129 /** the report for the output. */ 130 private I_CmsReport m_report; 131 132 /** 133 * Public constructor with JSP action element.<p> 134 * 135 * @param jsp an initialized JSP action element 136 */ 137 public CmsElementRename(CmsJspActionElement jsp) { 138 139 super(jsp); 140 } 141 142 /** 143 * Public constructor for testcase using.<p> 144 * 145 * @param jsp an initialized JSP action element 146 * @param cms the cms object 147 * @param resource the resource path 148 * @param recursive if true then do read recursive from the folder 149 * @param template the template 150 * @param locale the locale 151 * @param oldElement the old element name 152 * @param newElement the new element name 153 * @param removeEmptyElements if true then remove all invalid elements with no content 154 * @param validateNewElement if true then validate the new element before renaming 155 */ 156 public CmsElementRename( 157 CmsJspActionElement jsp, 158 CmsObject cms, 159 String resource, 160 String recursive, 161 String template, 162 String locale, 163 String oldElement, 164 String newElement, 165 String removeEmptyElements, 166 String validateNewElement) { 167 168 super(jsp); 169 m_cms = cms; 170 setParamResource(resource); 171 setParamRecursive(recursive); 172 setParamTemplate(template); 173 setParamLocale(locale); 174 setParamOldElement(oldElement); 175 setParamNewElement(newElement); 176 setParamRemoveEmptyElements(removeEmptyElements); 177 setParamValidateNewElement(validateNewElement); 178 } 179 180 /** 181 * Public constructor with JSP variables.<p> 182 * 183 * @param context the JSP page context 184 * @param req the JSP request 185 * @param res the JSP response 186 */ 187 public CmsElementRename(PageContext context, HttpServletRequest req, HttpServletResponse res) { 188 189 this(new CmsJspActionElement(context, req, res)); 190 } 191 192 /** 193 * Renames the element name on the specified resources.<p> 194 * 195 * @param report the cms report 196 */ 197 public void actionRename(I_CmsReport report) { 198 199 m_report = report; 200 List locales = OpenCms.getLocaleManager().getAvailableLocales(); 201 List xmlPages = getXmlPages(); 202 if (ALL.equals(getParamLocale())) { 203 Iterator i = locales.iterator(); 204 while (i.hasNext()) { 205 Locale locale = (Locale)i.next(); 206 performRenameOperation(xmlPages, locale); 207 } 208 } else { 209 performRenameOperation(xmlPages, CmsLocaleManager.getLocale(getParamLocale())); 210 } 211 } 212 213 /** 214 * Performs the move report, will be called by the JSP page.<p> 215 * 216 * @throws JspException if problems including sub-elements occur 217 */ 218 public void actionReport() throws JspException { 219 220 // save initialized instance of this class in request attribute for included sub-elements 221 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this); 222 switch (getAction()) { 223 case ACTION_REPORT_END: 224 actionCloseDialog(); 225 break; 226 case ACTION_REPORT_UPDATE: 227 setParamAction(REPORT_UPDATE); 228 getJsp().include(FILE_REPORT_OUTPUT); 229 break; 230 case ACTION_REPORT_BEGIN: 231 case ACTION_CONFIRMED: 232 default: 233 CmsElementRenameThread thread = new CmsElementRenameThread(getCms(), this); 234 thread.start(); 235 setParamAction(REPORT_BEGIN); 236 setParamThread(thread.getUUID().toString()); 237 getJsp().include(FILE_REPORT_OUTPUT); 238 break; 239 } 240 } 241 242 /** 243 * Builds the html for the available locales select box.<p> 244 * 245 * @param attributes optional attributes for the <select> tag 246 * 247 * @return the html for the available locales select box 248 */ 249 public String buildSelectLocales(String attributes) { 250 251 List options = new ArrayList(); 252 List values = new ArrayList(); 253 List locales = OpenCms.getLocaleManager().getAvailableLocales(); 254 int selectedIndex = -1; 255 if (locales == null) { 256 // no locales found, return empty String 257 return ""; 258 } else { 259 // locales found, create option and value lists 260 CmsMessages messages = Messages.get().getBundle(getLocale()); 261 options.add(messages.key(Messages.GUI_PLEASE_SELECT_0)); 262 values.add(""); 263 options.add(messages.key(Messages.GUI_BUTTON_ALL_0)); 264 values.add(ALL); 265 if (ALL.equals(getParamLocale())) { 266 selectedIndex = 1; 267 } 268 Iterator i = locales.iterator(); 269 int counter = 2; 270 while (i.hasNext()) { 271 Locale locale = (Locale)i.next(); 272 String language = locale.getLanguage(); 273 String displayLanguage = locale.getDisplayLanguage(); 274 if (language.equals(getParamLocale())) { 275 selectedIndex = counter; 276 } 277 options.add(displayLanguage); 278 values.add(language); 279 counter++; 280 } 281 } 282 283 return CmsWorkplace.buildSelect(attributes, options, values, selectedIndex, false); 284 } 285 286 /** 287 * Builds the html for the template select box.<p> 288 * 289 * @param attributes optional attributes for the <select> tag 290 * @return the html for the template select box 291 */ 292 public String buildSelectTemplates(String attributes) { 293 294 List options = new ArrayList(); 295 List values = new ArrayList(); 296 TreeMap templates = null; 297 int selectedIndex = -1; 298 try { 299 // get all available templates 300 templates = CmsNewResourceXmlPage.getTemplates(getCms(), null); 301 } catch (CmsException e) { 302 // can usually be ignored 303 if (LOG.isInfoEnabled()) { 304 LOG.info(e.getLocalizedMessage(), e); 305 } 306 } 307 if (templates == null) { 308 // no templates found, return empty String 309 return ""; 310 } else { 311 // templates found, create option and value lists 312 CmsMessages messages = Messages.get().getBundle(getLocale()); 313 options.add(messages.key(Messages.GUI_PLEASE_SELECT_0)); 314 values.add(""); 315 options.add(messages.key(Messages.GUI_BUTTON_ALL_0)); 316 values.add(ALL); 317 if (ALL.equals(getParamTemplate())) { 318 selectedIndex = 1; 319 } 320 Iterator i = templates.entrySet().iterator(); 321 int counter = 2; 322 while (i.hasNext()) { 323 Map.Entry entry = (Map.Entry)i.next(); 324 String key = (String)entry.getKey(); 325 String path = (String)entry.getValue(); 326 if (path.equals(getParamTemplate())) { 327 selectedIndex = counter; 328 } 329 options.add(key); 330 values.add(path); 331 counter++; 332 } 333 } 334 return buildSelect(attributes, options, values, selectedIndex, false); 335 } 336 337 /** 338 * @see org.opencms.workplace.CmsWorkplace#getCms() 339 */ 340 @Override 341 public CmsObject getCms() { 342 343 if (m_cms == null) { 344 return super.getCms(); 345 } 346 347 return m_cms; 348 } 349 350 /** 351 * Returns the errorMessage.<p> 352 * 353 * @return the errorMessage 354 */ 355 public String getErrorMessage() { 356 357 if (CmsStringUtil.isEmpty(m_errorMessage)) { 358 return ""; 359 } 360 361 return m_errorMessage; 362 } 363 364 /** 365 * Returns the paramLocale.<p> 366 * 367 * @return the paramLocale 368 */ 369 public String getParamLocale() { 370 371 return m_paramLocale; 372 } 373 374 /** 375 * Returns the value of the newvalue parameter.<p> 376 * 377 * @return the value of the newvalue parameter 378 */ 379 public String getParamNewElement() { 380 381 return m_paramNewElement; 382 } 383 384 /** 385 * Returns the value of the oldvalue parametere.<p> 386 * 387 * @return the value of the oldvalue parameter 388 */ 389 public String getParamOldElement() { 390 391 return m_paramOldElement; 392 } 393 394 /** 395 * Returns the value of the recursive parameter.<p> 396 * 397 * @return the value of the recursive parameter 398 */ 399 public String getParamRecursive() { 400 401 return m_paramRecursive; 402 } 403 404 /** 405 * Returns true if the user has set remove empty elements parameter; otherwise false.<p> 406 * 407 * @return true if the user has set remove empty elements parameter; otherwise false 408 */ 409 public String getParamRemoveEmptyElements() { 410 411 return m_paramRemoveEmptyElements; 412 } 413 414 /** 415 * Returns the template.<p> 416 * 417 * @return the template 418 */ 419 public String getParamTemplate() { 420 421 return m_paramTemplate; 422 } 423 424 /** 425 * Returns true if the user has set validate new element parameter; otherwise false.<p>.<p> 426 * 427 * @return true if the user has set validate new element parameter; otherwise false 428 */ 429 public String getParamValidateNewElement() { 430 431 return m_paramValidateNewElement; 432 } 433 434 /** 435 * Sets the errorMessage.<p> 436 * 437 * @param errorMessage the errorMessage to set 438 */ 439 public void setErrorMessage(String errorMessage) { 440 441 m_errorMessage = errorMessage; 442 } 443 444 /** 445 * Sets the locale.<p> 446 * 447 * @param paramLocale the locale to set 448 */ 449 public void setParamLocale(String paramLocale) { 450 451 m_paramLocale = paramLocale; 452 } 453 454 /** 455 * Sets the value of the newvalue parameter.<p> 456 * 457 * @param paramNewValue the value of the newvalue parameter 458 */ 459 public void setParamNewElement(String paramNewValue) { 460 461 m_paramNewElement = paramNewValue; 462 } 463 464 /** 465 * Sets the value of the oldvalue parameter.<p> 466 * 467 * @param paramOldValue the value of the oldvalue parameter 468 */ 469 public void setParamOldElement(String paramOldValue) { 470 471 m_paramOldElement = paramOldValue; 472 } 473 474 /** 475 * Sets the value of the recursive parameter.<p> 476 * 477 * @param paramRecursive the value of the recursive parameter 478 */ 479 public void setParamRecursive(String paramRecursive) { 480 481 m_paramRecursive = paramRecursive; 482 } 483 484 /** 485 * Sets the remove empty elements parameter to true or false.<p> 486 * 487 * @param paramRemoveEmptyElements the remove empty elements parameter to set 488 */ 489 public void setParamRemoveEmptyElements(String paramRemoveEmptyElements) { 490 491 m_paramRemoveEmptyElements = paramRemoveEmptyElements; 492 } 493 494 /** 495 * Sets the param Template.<p> 496 * 497 * @param paramTemplate the template name to set 498 */ 499 public void setParamTemplate(String paramTemplate) { 500 501 m_paramTemplate = paramTemplate; 502 } 503 504 /** 505 * Sets the paramValidateNewElement.<p> 506 * 507 * @param paramValidateNewElement the validate new element parameter to set 508 */ 509 public void setParamValidateNewElement(String paramValidateNewElement) { 510 511 m_paramValidateNewElement = paramValidateNewElement; 512 } 513 514 /** 515 * Does validate the request parameters and returns a buffer with error messages.<p> 516 * 517 * If there were no error messages, the buffer is empty.<p> 518 */ 519 public void validateParameters() { 520 521 // localisation 522 CmsMessages messages = Messages.get().getBundle(getLocale()); 523 524 StringBuffer validationErrors = new StringBuffer(); 525 if (CmsStringUtil.isEmpty(getParamResource())) { 526 validationErrors.append(messages.key(Messages.GUI_ELEM_RENAME_VALIDATE_RESOURCE_FOLDER_0)).append("<br>"); 527 } 528 if (CmsStringUtil.isEmpty(getParamTemplate())) { 529 validationErrors.append(messages.key(Messages.GUI_ELEM_RENAME_VALIDATE_SELECT_TEMPLATE_0)).append("<br>"); 530 } 531 if (CmsStringUtil.isEmpty(getParamLocale())) { 532 validationErrors.append(messages.key(Messages.GUI_ELEM_RENAME_VALIDATE_SELECT_LANGUAGE_0)).append("<br>"); 533 } 534 if (CmsStringUtil.isEmpty(getParamOldElement())) { 535 validationErrors.append(messages.key(Messages.GUI_ELEM_RENAME_VALIDATE_ENTER_OLD_ELEM_0)).append("<br>"); 536 } 537 if (CmsStringUtil.isEmpty(getParamNewElement())) { 538 validationErrors.append(messages.key(Messages.GUI_ELEM_RENAME_VALIDATE_ENTER_NEW_ELEM_0)).append("<br>"); 539 } 540 if (!isValidElement(getParamNewElement())) { 541 validationErrors.append( 542 messages.key( 543 Messages.GUI_ELEM_RENAME_VALIDATE_INVALID_NEW_ELEM_2, 544 getParamNewElement(), 545 getParamTemplate())).append("<br>"); 546 } 547 548 setErrorMessage(validationErrors.toString()); 549 } 550 551 /** 552 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 553 */ 554 @Override 555 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 556 557 // fill the parameter values in the get/set methods 558 fillParamValues(request); 559 // set the dialog type 560 setParamDialogtype(DIALOG_TYPE); 561 // set the action for the JSP switch 562 // set the action for the JSP switch 563 if (DIALOG_CONFIRMED.equals(getParamAction())) { 564 setAction(ACTION_CONFIRMED); 565 } else if (DIALOG_OK.equals(getParamAction())) { 566 setAction(ACTION_OK); 567 } else if (DIALOG_CANCEL.equals(getParamAction())) { 568 setAction(ACTION_CANCEL); 569 } else if (REPORT_UPDATE.equals(getParamAction())) { 570 setAction(ACTION_REPORT_UPDATE); 571 } else if (REPORT_BEGIN.equals(getParamAction())) { 572 setAction(ACTION_REPORT_BEGIN); 573 } else if (REPORT_END.equals(getParamAction())) { 574 setAction(ACTION_REPORT_END); 575 } else { 576 setAction(ACTION_DEFAULT); 577 // add the title for the dialog 578 setParamTitle(key("title.renameelement")); 579 } 580 } 581 582 /** 583 * Returns a retained list of xml pages that belongs to the specified template.<p> 584 * 585 * @param xmlPages a list of all xml pages 586 * @return a retained list of xml pages that belongs to the specified template 587 */ 588 private List getRetainedPagesWithTemplate(List xmlPages) { 589 590 // list of resources belongs to the selected template 591 List resourcesWithTemplate = new ArrayList(); 592 TreeMap templates = null; 593 try { 594 templates = CmsNewResourceXmlPage.getTemplates(getCms(), null); 595 } catch (CmsException e) { 596 if (LOG.isErrorEnabled()) { 597 LOG.error(e.getLocalizedMessage(), e); 598 } 599 } 600 // check if the users selected template is valid. 601 if ((templates != null) && templates.containsValue(getParamTemplate())) { 602 // iterate the xmlPages list and add all resources with the specified template to the resourcesWithTemplate list 603 Iterator i = xmlPages.iterator(); 604 while (i.hasNext()) { 605 CmsResource currentPage = (CmsResource)i.next(); 606 // read the template property 607 CmsProperty templateProperty; 608 try { 609 templateProperty = getCms().readPropertyObject( 610 getCms().getSitePath(currentPage), 611 CmsPropertyDefinition.PROPERTY_TEMPLATE, 612 false); 613 } catch (CmsException e2) { 614 if (LOG.isErrorEnabled()) { 615 LOG.error(e2); 616 } 617 continue; 618 } 619 // add currentResource if the template property value is the same as the given template 620 if (getParamTemplate().equals(templateProperty.getValue())) { 621 resourcesWithTemplate.add(currentPage); 622 } 623 } 624 // retain the list of pages against the list with template 625 xmlPages.retainAll(resourcesWithTemplate); 626 } 627 628 return xmlPages; 629 } 630 631 /** 632 * Returns a set of elements stored in the given template property.<p> 633 * 634 * The elements are stored in the property I_CmsConstants.C_PROPERTY_TEMPLATE_ELEMENTS.<p> 635 * 636 * @param currentTemplate the path of the template to look in 637 * @return a set of elements stored in the given template path 638 */ 639 private Set getTemplateElements(String currentTemplate) { 640 641 Set templateElements = new HashSet(); 642 643 if ((currentTemplate != null) && (currentTemplate.length() > 0)) { 644 // template found, check template-elements property 645 String elements = null; 646 try { 647 // read the property from the template file 648 elements = getCms().readPropertyObject( 649 currentTemplate, 650 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 651 false).getValue(null); 652 } catch (CmsException e) { 653 if (LOG.isWarnEnabled()) { 654 LOG.warn(e.getLocalizedMessage()); 655 } 656 } 657 if (elements != null) { 658 // elements are defined on template file, merge with available elements 659 StringTokenizer T = new StringTokenizer(elements, ","); 660 while (T.hasMoreTokens()) { 661 String currentElement = T.nextToken(); 662 String niceName = null; 663 boolean mandatory = false; 664 int sepIndex = currentElement.indexOf("|"); 665 if (sepIndex != -1) { 666 // nice name found for current element, extract it 667 niceName = currentElement.substring(sepIndex + 1); 668 currentElement = currentElement.substring(0, sepIndex); 669 } 670 if (currentElement.endsWith("*")) { 671 // element is mandatory 672 mandatory = true; 673 currentElement = currentElement.substring(0, currentElement.length() - 1); 674 } 675 676 CmsDialogElement element = new CmsDialogElement(currentElement, niceName, mandatory, true, false); 677 templateElements.add(element); 678 } 679 } 680 } 681 682 return templateElements; 683 } 684 685 /** 686 * Returns a list of xml pages from the specified folder.<p> 687 * 688 * @return a list of xml pages from the specified folder 689 */ 690 private List getXmlPages() { 691 692 boolean isRecursive = Boolean.valueOf(getParamRecursive()).booleanValue(); 693 // filter definition to read only the required resources 694 int xmlPageId; 695 try { 696 xmlPageId = OpenCms.getResourceManager().getResourceType( 697 CmsResourceTypeXmlPage.getStaticTypeName()).getTypeId(); 698 } catch (CmsLoaderException e1) { 699 xmlPageId = CmsResourceTypeXmlPage.getStaticTypeId(); 700 } 701 CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireType(xmlPageId); 702 // trying to read the resources 703 List xmlPages = null; 704 705 try { 706 xmlPages = getCms().readResources(getParamResource(), filter, isRecursive); 707 } catch (CmsException e) { 708 if (LOG.isErrorEnabled()) { 709 LOG.error(e.getLocalizedMessage(), e); 710 } 711 } 712 713 return xmlPages; 714 } 715 716 /** 717 * Checks if the specified element/locale of the given page has a content.<p> 718 * 719 * @param page the xml page 720 * @param element the element name 721 * @param locale the locale 722 * @return false if the specified element/locale of the given page has a content; otherwise true 723 */ 724 private boolean isEmptyElement(CmsXmlPage page, String element, Locale locale) { 725 726 CmsXmlHtmlValue xmlHtmlValue = (CmsXmlHtmlValue)page.getValue(element, locale); 727 if (CmsStringUtil.isNotEmpty(xmlHtmlValue.getPlainText(getCms()))) { 728 return false; 729 } 730 731 return true; 732 } 733 734 /** 735 * Checks if the selected new element is valid for the selected template.<p> 736 * 737 * @param page the xml page 738 * @param element the element name 739 * 740 * @return true if ALL_TEMPLATES selected or the element is valid for the selected template; otherwise false 741 */ 742 private boolean isValidElement(CmsXmlPage page, String element) { 743 744 CmsFile file = page.getFile(); 745 String template; 746 try { 747 template = getCms().readPropertyObject( 748 getCms().getSitePath(file), 749 CmsPropertyDefinition.PROPERTY_TEMPLATE, 750 true).getValue(null); 751 } catch (CmsException e) { 752 return false; 753 } 754 755 return isValidTemplateElement(template, element); 756 } 757 758 /** 759 * Checks if the selected new element is valid for the selected template.<p> 760 * 761 * @param element the element name 762 * 763 * @return true if ALL_TEMPLATES selected or the element is valid for the selected template; otherwise false 764 */ 765 private boolean isValidElement(String element) { 766 767 boolean validateNewElement = Boolean.valueOf(getParamValidateNewElement()).booleanValue(); 768 if (ALL.equals(getParamTemplate()) || !validateNewElement) { 769 return true; 770 } 771 772 return isValidTemplateElement(getParamTemplate(), element); 773 } 774 775 /** 776 * Check if the given template includes the specified element.<p> 777 * 778 * @param template the template 779 * @param element the element name 780 * @return true if the template includes the given element 781 */ 782 private boolean isValidTemplateElement(String template, String element) { 783 784 List elements = new ArrayList(getTemplateElements(template)); 785 Iterator i = elements.iterator(); 786 while (i.hasNext()) { 787 CmsDialogElement currElement = (CmsDialogElement)i.next(); 788 if (element.equals(currElement.getName())) { 789 return true; 790 } 791 } 792 793 return false; 794 } 795 796 /** 797 * Performs the main element rename operation on the filtered resources.<p> 798 * 799 * @param xmlPages the list of xml pages 800 * @param locale the locale specifying the xmlpage node to perform the operation on 801 */ 802 private void performRenameOperation(List xmlPages, Locale locale) { 803 804 // partial localized (stopped due to low prio). 805 boolean removeEmptyElements = Boolean.valueOf(getParamRemoveEmptyElements()).booleanValue(); 806 boolean validateNewElement = Boolean.valueOf(getParamValidateNewElement()).booleanValue(); 807 // the list including at least one resource 808 if ((xmlPages != null) && (xmlPages.size() > 0)) { 809 m_report.println( 810 Messages.get().container(Messages.RPT_RENAME_LANG_1, locale.getLanguage()), 811 I_CmsReport.FORMAT_HEADLINE); 812 // if user has not selected ALL templates, then retain pages with specified template 813 if (!ALL.equals(getParamTemplate())) { 814 xmlPages = getRetainedPagesWithTemplate(xmlPages); 815 } 816 int m = 0; 817 int n = xmlPages.size(); 818 // loop over remained pages 819 Iterator i = xmlPages.iterator(); 820 while (i.hasNext()) { 821 m++; 822 CmsXmlPage page = null; 823 try { 824 // next file from the list 825 CmsResource res = (CmsResource)i.next(); 826 CmsFile file; 827 828 m_report.print( 829 org.opencms.report.Messages.get().container( 830 org.opencms.report.Messages.RPT_SUCCESSION_2, 831 String.valueOf(m), 832 String.valueOf(n)), 833 I_CmsReport.FORMAT_NOTE); 834 m_report.print(Messages.get().container(Messages.RPT_PROCESSING_PAGE_0), I_CmsReport.FORMAT_NOTE); 835 m_report.print( 836 org.opencms.report.Messages.get().container( 837 org.opencms.report.Messages.RPT_ARGUMENT_1, 838 getCms().getSitePath(res))); 839 m_report.println( 840 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 841 842 try { 843 file = getCms().readFile(getCms().getSitePath(res), CmsResourceFilter.IGNORE_EXPIRATION); 844 } catch (CmsException e2) { 845 if (LOG.isErrorEnabled()) { 846 LOG.error(e2); 847 } 848 m_report.println(e2); 849 continue; 850 } 851 // try unmarshaling to xml page 852 try { 853 page = CmsXmlPageFactory.unmarshal(getCms(), file); 854 } catch (CmsXmlException e) { 855 m_report.println(e); 856 continue; 857 } 858 859 // check if the source element exists in the page 860 if (!page.hasValue(getParamOldElement(), locale)) { 861 m_report.println( 862 Messages.get().container(Messages.RPT_NONEXISTANT_ELEM_1, getParamOldElement()), 863 I_CmsReport.FORMAT_NOTE); 864 continue; 865 } 866 867 // check if the target element already exists in the page 868 if (page.hasValue(getParamNewElement(), locale)) { 869 // the page contains already the new element with speicific content. 870 // renaming the old will invalid the xml page 871 m_report.println( 872 Messages.get().container(Messages.RPT_NEW_ELEM_EXISTS_0), 873 I_CmsReport.FORMAT_NOTE); 874 continue; 875 } 876 877 if (validateNewElement) { 878 // check if the target element is valid for the template 879 if (!isValidElement(page, getParamNewElement())) { 880 m_report.println( 881 Messages.get().container(Messages.RPT_INVALID_ARGUMENT_1, getParamNewElement()), 882 I_CmsReport.FORMAT_NOTE); 883 continue; 884 } 885 } 886 887 try { 888 // rename the element from the old value to the new 889 page.renameValue(getParamOldElement(), getParamNewElement(), locale); 890 // write the page with the new content 891 writePageAndReport(page, true); 892 } catch (Throwable t) { 893 LOG.error(t); 894 m_report.println(t); 895 continue; 896 } 897 898 } catch (Throwable t) { 899 LOG.error(t); 900 m_report.println(t); 901 } finally { 902 // finally do remove empty elements of the page 903 // the remove operation is executed if the user has checked the specified checkbox and selected a template (NOT ALL) 904 if (removeEmptyElements) { 905 removeInValidElements(page, locale); 906 } 907 } 908 } 909 } 910 } 911 912 /** 913 * Analyzes xml page and removes any element if this is not valid for the specified template and has no content.<p> 914 * 915 * @param page a xml page 916 * @param locale the locale 917 */ 918 private void removeInValidElements(CmsXmlPage page, Locale locale) { 919 920 if (page == null) { 921 return; 922 } 923 924 if (ALL.equals(getParamTemplate())) { 925 return; 926 } 927 928 // get all elements of this page 929 List pageElements = page.getNames(locale); 930 if (pageElements != null) { 931 Iterator i = pageElements.iterator(); 932 while (i.hasNext()) { 933 String currElement = (String)i.next(); 934 // remove current element only is invalid and has no content 935 if (!isValidElement(currElement) && isEmptyElement(page, currElement, locale)) { 936 page.removeValue(currElement, locale); 937 try { 938 writePageAndReport(page, false); 939 m_report.println( 940 Messages.get().container(Messages.RPT_REMOVE_INVALID_EMPTY_ELEM_1, currElement), 941 I_CmsReport.FORMAT_NOTE); 942 } catch (CmsException e) { 943 // ignore 944 } 945 } 946 } 947 } 948 } 949 950 /** 951 * Writes the given xml page by reporting the result.<p> 952 * 953 * @param page the xml page 954 * @param report if true then some output will be written to the report 955 * @throws CmsException if operation failed 956 */ 957 private void writePageAndReport(CmsXmlPage page, boolean report) throws CmsException { 958 959 CmsFile file = page.getFile(); 960 byte[] content = page.marshal(); 961 file.setContents(content); 962 // check lock 963 CmsLock lock = getCms().getLock(file); 964 if (lock.isNullLock() || lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) { 965 // lock the page 966 checkLock(getCms().getSitePath(file)); 967 // write the file with the new content 968 getCms().writeFile(file); 969 // unlock the page 970 getCms().unlockResource(getCms().getSitePath(file)); 971 if (report) { 972 m_report.println( 973 Messages.get().container(Messages.RPT_ELEM_RENAME_2, getParamOldElement(), getParamNewElement()), 974 I_CmsReport.FORMAT_OK); 975 } 976 } 977 } 978}