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.languagecopy; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsProperty; 032import org.opencms.file.CmsPropertyDefinition; 033import org.opencms.file.CmsResource; 034import org.opencms.file.CmsResourceFilter; 035import org.opencms.file.types.CmsResourceTypeXmlContent; 036import org.opencms.file.types.CmsResourceTypeXmlPage; 037import org.opencms.file.types.I_CmsResourceType; 038import org.opencms.i18n.CmsMessageContainer; 039import org.opencms.jsp.CmsJspActionElement; 040import org.opencms.main.CmsException; 041import org.opencms.main.CmsLog; 042import org.opencms.main.CmsRuntimeException; 043import org.opencms.main.OpenCms; 044import org.opencms.util.CmsStringUtil; 045import org.opencms.workplace.CmsWorkplace; 046import org.opencms.workplace.CmsWorkplaceSettings; 047import org.opencms.workplace.list.A_CmsListDialog; 048import org.opencms.workplace.list.CmsListColumnAlignEnum; 049import org.opencms.workplace.list.CmsListColumnDefinition; 050import org.opencms.workplace.list.CmsListItem; 051import org.opencms.workplace.list.CmsListMetadata; 052import org.opencms.workplace.list.CmsListMultiAction; 053import org.opencms.workplace.list.CmsListOrderEnum; 054import org.opencms.workplace.tools.CmsToolDialog; 055import org.opencms.workplace.tools.CmsToolManager; 056import org.opencms.xml.content.CmsXmlContent; 057import org.opencms.xml.content.CmsXmlContentFactory; 058 059import java.io.FileNotFoundException; 060import java.io.IOException; 061import java.util.ArrayList; 062import java.util.Collections; 063import java.util.HashMap; 064import java.util.LinkedList; 065import java.util.List; 066import java.util.Locale; 067import java.util.Map; 068 069import javax.servlet.ServletException; 070import javax.servlet.http.HttpServletRequest; 071import javax.servlet.http.HttpServletResponse; 072import javax.servlet.jsp.PageContext; 073 074import org.apache.commons.logging.Log; 075 076/** 077 * A list that displays resources and the existance of their language nodes. 078 * <p> 079 * 080 * @since 7.5.1 081 * 082 */ 083public class CmsLanguageCopySelectionList extends A_CmsListDialog { 084 085 /** list action id constant. */ 086 public static final String LIST_ACTION_NONE = "an"; 087 088 /** list column id constant. */ 089 public static final String LIST_COLUMN_ICON = "lcic"; 090 091 /** list action id constant. */ 092 public static final String LIST_COLUMN_ID = "li.id.languagecopyselection"; 093 094 /** list column id constant. */ 095 public static final String LIST_COLUMN_PATH = "lcp"; 096 097 /** list column id constant. */ 098 public static final String LIST_COLUMN_PREFIX_PROPERTY = "cnp-"; 099 100 /** list column id constant. */ 101 public static final String LIST_COLUMN_RESOURCETYPE = "lcrt"; 102 103 /** list item detail id constant. */ 104 public static final String LIST_DETAIL_FULLPATH = "df"; 105 106 /** Multi action for copy. */ 107 public static final String LIST_MACTION_COPY = "mac"; 108 109 /** The request parameter for the paths to work on. */ 110 public static final String PARAM_PATHS = "paths"; 111 112 /** The request parameter for the paths to work on. */ 113 public static final String PARAM_SIBLINGS = "siblings"; 114 115 /** The request parameter for the source language. */ 116 public static final String PARAM_SOURCE_LANGUAGE = "sourcelanguage"; 117 118 /** The request parameter for the target language. */ 119 public static final String PARAM_TARGET_LANGUAGE = "targetlanguage"; 120 121 /** The request parameter for the target language. */ 122 public static final String PARAM_DELETE = "delete"; 123 124 /** The log object for this class. */ 125 private static final Log LOG = CmsLog.getLog(CmsLanguageCopySelectionList.class); 126 127 /** Signals whether to delete the original language node or not. */ 128 private String m_paramDelete; 129 130 /** The source language. */ 131 private String m_paramSourcelanguage; 132 133 /** The target language. */ 134 private String m_paramTargetlanguage; 135 136 /** The paths. */ 137 private String[] m_paths; 138 139 /** 140 * Public constructor. 141 * <p> 142 * 143 * @param jsp an initialized JSP action element 144 * 145 * @throws CmsException if something goes wrong. 146 * 147 * @throws FileNotFoundException if something goes wrong. 148 */ 149 public CmsLanguageCopySelectionList(final CmsJspActionElement jsp) 150 throws FileNotFoundException, CmsException { 151 152 this(jsp, LIST_COLUMN_ID, Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_NAME_0)); 153 } 154 155 /** 156 * Public constructor. 157 * <p> 158 * 159 * @param jsp an initialized JSP action element 160 * @param listId the id of the list 161 * @param listName the list name 162 * 163 * @throws CmsException if something goes wrong. 164 * 165 * @throws FileNotFoundException if something goes wrong. 166 */ 167 public CmsLanguageCopySelectionList( 168 final CmsJspActionElement jsp, 169 final String listId, 170 final CmsMessageContainer listName) 171 throws FileNotFoundException, CmsException { 172 173 this(jsp, listId, listName, LIST_COLUMN_ID, CmsListOrderEnum.ORDER_ASCENDING, null); 174 } 175 176 /** 177 * Public constructor. 178 * <p> 179 * 180 * @param jsp an initialized JSP action element 181 * @param listId the id of the displayed list 182 * @param listName the name of the list 183 * @param sortedColId the a priory sorted column 184 * @param sortOrder the order of the sorted column 185 * @param searchableColId the column to search into 186 * 187 * @throws CmsException if something goes wrong. 188 * @throws FileNotFoundException if something goes wrong. 189 */ 190 @SuppressWarnings("unused") 191 public CmsLanguageCopySelectionList( 192 final CmsJspActionElement jsp, 193 final String listId, 194 final CmsMessageContainer listName, 195 final String sortedColId, 196 final CmsListOrderEnum sortOrder, 197 final String searchableColId) 198 throws FileNotFoundException, CmsException { 199 200 super(jsp, listId, listName, sortedColId, sortOrder, searchableColId); 201 } 202 203 /** 204 * Public constructor with JSP variables. 205 * <p> 206 * 207 * @param context the JSP page context 208 * @param req the JSP request 209 * @param res the JSP response 210 * 211 * @throws CmsException if something goes wrong. 212 * @throws FileNotFoundException if something goes wrong. 213 */ 214 public CmsLanguageCopySelectionList( 215 final PageContext context, 216 final HttpServletRequest req, 217 final HttpServletResponse res) 218 throws FileNotFoundException, CmsException { 219 220 this(new CmsJspActionElement(context, req, res)); 221 } 222 223 /** 224 * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions() 225 */ 226 @Override 227 public void executeListMultiActions() throws IOException, ServletException, CmsRuntimeException { 228 229 if (getParamListAction().equals(LIST_MACTION_COPY)) { 230 231 // create absolute RFS path and store it in dialog object 232 Map<String, String[]> params = new HashMap<String, String[]>(); 233 List<CmsListItem> items = getSelectedItems(); 234 List<String> paths = new LinkedList<String>(); 235 for (CmsListItem item : items) { 236 paths.add(String.valueOf(item.get(LIST_COLUMN_PATH))); 237 } 238 params.put( 239 CmsLanguageCopyFolderAndLanguageSelectDialog.PARAM_COPYRESOURCES, 240 new String[] {CmsStringUtil.listAsString(paths, ",")}); 241 params.put(PARAM_DELETE, new String[] {getParamDelete()}); 242 // the source language 243 params.put(PARAM_SOURCE_LANGUAGE, new String[] {getParamSourcelanguage()}); 244 // the target language 245 params.put(PARAM_TARGET_LANGUAGE, new String[] {getParamTargetlanguage()}); 246 // set style to display report in correct layout 247 params.put(PARAM_STYLE, new String[] {CmsToolDialog.STYLE_NEW}); 248 // set close link to get back to overview after finishing the import 249 params.put(PARAM_CLOSELINK, new String[] {CmsToolManager.linkForToolPath(getJsp(), "/contenttools")}); 250 // redirect to the report output JSP 251 getToolManager().jspForwardPage( 252 this, 253 CmsWorkplace.PATH_WORKPLACE + "admin/contenttools/languagecopy/report.jsp", 254 params); 255 } 256 listSave(); 257 } 258 259 /** 260 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 261 */ 262 @SuppressWarnings("unused") 263 @Override 264 public void executeListSingleActions() throws IOException, ServletException, CmsRuntimeException { 265 266 // do nothing 267 } 268 269 /** 270 * @return the resourcses to copy 271 */ 272 public String[] getCopyResources() { 273 274 List<CmsListItem> items = getSelectedItems(); 275 String paths = ""; 276 boolean initial = true; 277 for (CmsListItem item : items) { 278 if (!initial) { 279 paths.concat(","); 280 } 281 paths.concat(String.valueOf(item.get(LIST_COLUMN_PATH))); 282 initial = false; 283 } 284 return CmsStringUtil.splitAsArray(paths, ","); 285 } 286 287 /** 288 * @return the paths 289 */ 290 public String getParamPaths() { 291 292 return CmsStringUtil.arrayAsString(m_paths, ","); 293 } 294 295 /** 296 * @return the source language 297 */ 298 public String getParamSourcelanguage() { 299 300 return m_paramSourcelanguage; 301 } 302 303 /** 304 * @return the target language 305 */ 306 public String getParamTargetlanguage() { 307 308 return m_paramTargetlanguage; 309 } 310 311 /** 312 * Returns the paramDelete.<p> 313 * 314 * @return the paramDelete 315 */ 316 public String getParamDelete() { 317 318 return m_paramDelete; 319 } 320 321 /** 322 * Sets the paramDelete.<p> 323 * 324 * @param paramDelete the paramDelete to set 325 */ 326 public void setParamDelete(String paramDelete) { 327 328 m_paramDelete = paramDelete; 329 } 330 331 /** 332 * @param paths 333 * the paths to set 334 */ 335 public void setParamPaths(final String paths) { 336 337 m_paths = CmsStringUtil.splitAsArray(paths, ","); 338 } 339 340 /** 341 * @param sourceLanguage 342 * the source language 343 */ 344 public void setParamSourcelanguage(String sourceLanguage) { 345 346 m_paramSourcelanguage = sourceLanguage; 347 } 348 349 /** 350 * @param targetLanguage 351 * the target language 352 */ 353 public void setParamTargetlanguage(String targetLanguage) { 354 355 m_paramTargetlanguage = targetLanguage; 356 } 357 358 /** 359 * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String) 360 */ 361 @Override 362 protected void fillDetails(final String detailId) { 363 364 // do nothing 365 } 366 367 /** 368 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 369 */ 370 @Override 371 protected List<CmsListItem> getListItems() { 372 373 List<CmsListItem> result = new ArrayList<CmsListItem>(); 374 // get content 375 CmsListItem item; 376 int idCounter = 0; 377 for (CmsResource resource : getResources()) { 378 item = getList().newItem(resource.getRootPath()); 379 fillItem(resource, item, idCounter); 380 idCounter++; 381 result.add(item); 382 } 383 return result; 384 } 385 386 /** 387 * @see org.opencms.workplace.CmsWorkplace#initMessages() 388 */ 389 @Override 390 protected void initMessages() { 391 392 // add specific dialog resource bundle 393 addMessages(Messages.get().getBundleName()); 394 // add default resource bundles 395 super.initMessages(); 396 } 397 398 /** 399 * @see org.opencms.workplace.list.A_CmsListDialog#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, 400 * javax.servlet.http.HttpServletRequest) 401 */ 402 @Override 403 protected void initWorkplaceRequestValues(final CmsWorkplaceSettings settings, final HttpServletRequest request) { 404 405 super.initWorkplaceRequestValues(settings, request); 406 } 407 408 /** 409 * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata) 410 */ 411 @Override 412 protected void setColumns(final CmsListMetadata metadata) { 413 414 // enforce re-invocation of this method because columns are varying and must not be cached: 415 metadata.setVolatile(true); 416 417 // add column for icon 418 CmsListColumnDefinition iconCol = new CmsListColumnDefinition(LIST_COLUMN_ICON); 419 iconCol.setName(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_ICON_NAME_0)); 420 iconCol.setHelpText(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_ICON_HELP_0)); 421 iconCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 422 iconCol.setWidth("16"); 423 iconCol.setSorteable(false); 424 metadata.addColumn(iconCol); 425 iconCol.setPrintable(true); 426 427 // add column for name 428 CmsListColumnDefinition nameCol = new CmsListColumnDefinition(LIST_COLUMN_PATH); 429 nameCol.setName(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_PATH_NAME_0)); 430 nameCol.setHelpText(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_PATH_HELP_0)); 431 nameCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 432 nameCol.setSorteable(true); 433 metadata.addColumn(nameCol); 434 nameCol.setPrintable(true); 435 436 // add column for resource type 437 CmsListColumnDefinition typeCol = new CmsListColumnDefinition(LIST_COLUMN_RESOURCETYPE); 438 typeCol.setName(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_RESOURCETYPE_NAME_0)); 439 typeCol.setHelpText(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_RESOURCETYPE_HELP_0)); 440 typeCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 441 typeCol.setSorteable(true); 442 metadata.addColumn(typeCol); 443 typeCol.setPrintable(true); 444 445 // add columns for languages: 446 List<Locale> sysLocales = OpenCms.getLocaleManager().getAvailableLocales(); 447 CmsListColumnDefinition langCol; 448 for (Locale locale : sysLocales) { 449 langCol = new CmsListColumnDefinition(locale.toString()); 450 langCol.setName( 451 Messages.get().container( 452 Messages.GUI_LIST_LANGUAGECOPY_COL_LANGUAGE_NAME_1, 453 new Object[] {locale.toString()})); 454 langCol.setHelpText(Messages.get().container(Messages.GUI_LIST_LANGUAGECOPY_COL_LANGUAGE_HELP_0)); 455 langCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 456 langCol.setSorteable(false); 457 metadata.addColumn(langCol); 458 langCol.setPrintable(true); 459 } 460 461 } 462 463 /** 464 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 465 */ 466 @Override 467 protected void setIndependentActions(final CmsListMetadata metadata) { 468 469 // nothing to do here 470 } 471 472 /** 473 * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata) 474 */ 475 @Override 476 protected void setMultiActions(final CmsListMetadata metadata) { 477 478 // add copy multi action 479 CmsListMultiAction copyAction = new CmsListMultiAction(LIST_MACTION_COPY); 480 copyAction.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_MACTION_COPY_NAME_0)); 481 copyAction.setHelpText(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_MACTION_COPY_HELP_0)); 482 copyAction.setIconPath(ICON_MULTI_ADD); 483 metadata.addMultiAction(copyAction); 484 } 485 486 /** 487 * Fills a single item. 488 * <p> 489 * 490 * @param resource the corresponding resource. 491 * @param item the item to fill. 492 * @param id used for the ID column. 493 */ 494 private void fillItem(final CmsResource resource, final CmsListItem item, final int id) { 495 496 CmsObject cms = getCms(); 497 CmsXmlContent xmlContent; 498 499 I_CmsResourceType type; 500 String iconPath; 501 502 // fill path column: 503 String sitePath = cms.getSitePath(resource); 504 item.set(LIST_COLUMN_PATH, sitePath); 505 506 // fill language node existence column: 507 item.set(LIST_COLUMN_PATH, sitePath); 508 boolean languageNodeExists = false; 509 String languageNodeHtml; 510 511 List<Locale> sysLocales = OpenCms.getLocaleManager().getAvailableLocales(); 512 try { 513 xmlContent = CmsXmlContentFactory.unmarshal(cms, cms.readFile(resource)); 514 for (Locale locale : sysLocales) { 515 languageNodeExists = xmlContent.hasLocale(locale); 516 if (languageNodeExists) { 517 languageNodeHtml = "<input type=\"checkbox\" checked=\"checked\" disabled=\"disabled\"/>"; 518 } else { 519 languageNodeHtml = "<input type=\"checkbox\" disabled=\"disabled\"/>"; 520 } 521 item.set(locale.toString(), languageNodeHtml); 522 523 } 524 } catch (Throwable e1) { 525 LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_LANGUAGECOPY_DETERMINE_LANGUAGE_NODE_1), e1); 526 languageNodeHtml = "n/a"; 527 for (Locale locale : sysLocales) { 528 item.set(locale.toString(), languageNodeHtml); 529 } 530 } 531 532 // type column: 533 type = OpenCms.getResourceManager().getResourceType(resource); 534 item.set(LIST_COLUMN_RESOURCETYPE, type.getTypeName()); 535 536 // icon column with title property for tooltip: 537 String title = ""; 538 try { 539 CmsProperty titleProperty = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, true); 540 title = titleProperty.getValue(); 541 } catch (CmsException e) { 542 LOG.warn(Messages.get().getBundle().key(Messages.LOG_WARN_LANGUAGECOPY_READPROP_1), e); 543 } 544 545 iconPath = getSkinUri() 546 + CmsWorkplace.RES_PATH_FILETYPES 547 + OpenCms.getWorkplaceManager().getExplorerTypeSetting(type.getTypeName()).getIcon(); 548 String iconImage; 549 iconImage = "<img src=\"" + iconPath + "\" alt=\"" + type.getTypeName() + "\" title=\"" + title + "\" />"; 550 item.set(LIST_COLUMN_ICON, iconImage); 551 } 552 553 /** 554 * Reads the resources available for processing based on the path parameters.<p> 555 * 556 * @return the resources available for processing based on the path parameters. 557 */ 558 private List<CmsResource> getResources() { 559 560 List<CmsResource> result = new LinkedList<CmsResource>(); 561 CmsObject cms = getCms(); 562 CmsResourceFilter filter = CmsResourceFilter.ALL; 563 try { 564 for (String path : m_paths) { 565 List<CmsResource> resources = cms.readResources(path, filter, true); 566 // filter out any resource that is no XML content: 567 for (CmsResource resource : resources) { 568 if (resource.isFile()) { 569 if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 570 result.add(resource); 571 } else if (CmsResourceTypeXmlPage.isXmlPage(resource)) { 572 result.add(resource); 573 } 574 } 575 } 576 } 577 } catch (CmsException e) { 578 LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_LANGUAGECOPY_READRESOURCES_0), e); 579 result = Collections.emptyList(); 580 } 581 582 return result; 583 } 584}