1 31 32 package org.opencms.frontend.templateone.form; 33 34 import org.opencms.file.CmsFile; 35 import org.opencms.file.CmsObject; 36 import org.opencms.file.CmsProperty; 37 import org.opencms.file.CmsPropertyDefinition; 38 import org.opencms.file.CmsRequestContext; 39 import org.opencms.file.CmsResource; 40 import org.opencms.file.CmsResourceFilter; 41 import org.opencms.i18n.CmsLocaleManager; 42 import org.opencms.loader.CmsLoaderException; 43 import org.opencms.main.CmsException; 44 import org.opencms.main.CmsIllegalArgumentException; 45 import org.opencms.main.CmsLog; 46 import org.opencms.main.OpenCms; 47 import org.opencms.util.CmsMacroResolver; 48 import org.opencms.util.CmsStringUtil; 49 import org.opencms.widgets.CmsSelectWidget; 50 import org.opencms.widgets.CmsSelectWidgetOption; 51 import org.opencms.widgets.I_CmsWidget; 52 import org.opencms.widgets.I_CmsWidgetDialog; 53 import org.opencms.widgets.I_CmsWidgetParameter; 54 import org.opencms.xml.content.CmsXmlContent; 55 import org.opencms.xml.content.CmsXmlContentFactory; 56 import org.opencms.xml.types.I_CmsXmlContentValue; 57 58 import java.util.ArrayList ; 59 import java.util.Collections ; 60 import java.util.Comparator ; 61 import java.util.HashMap ; 62 import java.util.Iterator ; 63 import java.util.LinkedList ; 64 import java.util.List ; 65 import java.util.Locale ; 66 import java.util.Map ; 67 import java.util.SortedSet ; 68 import java.util.TreeSet ; 69 70 import org.apache.commons.logging.Log; 71 72 147 public class CmsSelectWidgetXmlcontentType extends CmsSelectWidget { 148 149 161 private static final class CmsResourceSelectWidgetOption extends CmsSelectWidgetOption { 162 163 164 private CmsResource m_resource; 165 166 174 public CmsResourceSelectWidgetOption(CmsResource resource) { 175 176 this(resource, false); 177 178 } 179 180 190 public CmsResourceSelectWidgetOption(CmsResource resource, boolean isDefault) { 191 192 this(resource, isDefault, resource.getName()); 193 194 } 195 196 208 public CmsResourceSelectWidgetOption(CmsResource resource, boolean isDefault, String optionText) { 209 210 this(resource, isDefault, optionText, null); 211 212 } 213 214 228 public CmsResourceSelectWidgetOption(CmsResource resource, boolean isDefault, String optionText, String helpText) { 229 230 super(resource.getRootPath(), isDefault, optionText, helpText); 231 m_resource = resource; 232 233 } 234 235 241 CmsResource getResource() { 242 243 return m_resource; 244 } 245 246 } 247 248 260 private final class CmsResourceSelectWidgetOptionComparator implements Comparator { 261 262 263 private String m_comparatorMacro; 264 265 266 private CmsObject m_macroCmsObjectInner; 267 268 269 private CmsMacroResolver m_macroResolverInner; 270 271 284 private CmsResourceSelectWidgetOptionComparator(CmsObject cms, String comparatorMacro) 285 throws CmsException { 286 287 if (CmsStringUtil.isEmpty(comparatorMacro)) { 288 m_comparatorMacro = "${opencms.filename}"; 289 } else { 290 m_comparatorMacro = comparatorMacro; 291 } 292 m_macroCmsObjectInner = OpenCms.initCmsObject(cms); 293 m_macroCmsObjectInner.getRequestContext().setSiteRoot("/"); 294 m_macroResolverInner = new CmsMacroResolver(); 295 m_macroResolverInner.setCmsObject(m_macroCmsObjectInner); 296 } 297 298 301 public int compare(Object o1, Object o2) { 302 303 CmsResourceSelectWidgetOption option1 = (CmsResourceSelectWidgetOption)o1; 304 CmsResourceSelectWidgetOption option2 = (CmsResourceSelectWidgetOption)o2; 305 CmsResource resource1 = option1.getResource(); 306 CmsResource resource2 = option2.getResource(); 307 308 String sort1, sort2; 309 310 CmsRequestContext requestContext = m_macroCmsObjectInner.getRequestContext(); 312 requestContext.setUri(resource1.getRootPath()); 313 m_macroResolverInner.setResourceName(resource1.getName()); 315 sort1 = m_macroResolverInner.resolveMacros(m_comparatorMacro); 316 requestContext.setUri(resource2.getRootPath()); 317 m_macroResolverInner.setResourceName(resource2.getName()); 318 sort2 = m_macroResolverInner.resolveMacros(m_comparatorMacro); 319 return sort1.compareTo(sort2); 320 } 321 322 } 323 324 328 public static final String CONFIGURATION_OPTION_DISPLAY_MACRO = "displayOptionMacro"; 329 330 333 public static final String CONFIGURATION_OPTION_SORT_MACRO = "sortMacro"; 334 335 336 public static final String CONFIGURATION_RESOURCETYPENAME = "resourcetypeName"; 337 338 339 public static final String CONFIGURATION_TOPFOLDER = "folder"; 340 341 342 private static final Log LOG = CmsLog.getLog(CmsSelectWidgetXmlcontentType.class); 343 344 345 protected CmsObject m_macroCmsObject; 346 347 348 protected CmsMacroResolver m_macroResolver; 349 350 354 private String m_displayOptionMacro; 355 356 357 private Map m_filterProperties; 358 359 360 private CmsResource m_resourceFolder; 361 362 363 private int m_resourceTypeID; 364 365 369 private String m_sortMacro; 370 371 378 public CmsSelectWidgetXmlcontentType() { 379 380 this(""); 381 } 382 383 389 public CmsSelectWidgetXmlcontentType(String configuration) { 390 391 super(configuration); 392 m_filterProperties = new HashMap (); 393 394 } 395 396 402 public String getDisplayOptionMacro() { 403 404 return m_displayOptionMacro; 405 } 406 407 413 public CmsResource getResourceFolder() { 414 415 return m_resourceFolder; 416 } 417 418 424 public int getResourceTypeID() { 425 426 return m_resourceTypeID; 427 } 428 429 432 public I_CmsWidget newInstance() { 433 434 return new CmsSelectWidgetXmlcontentType(getConfiguration()); 435 } 436 437 455 protected List parseSelectOptions(CmsObject cms, I_CmsWidgetDialog widgetDialog, I_CmsWidgetParameter param) 456 throws CmsIllegalArgumentException { 457 458 if (m_macroCmsObject == null) { 459 try { 460 m_macroCmsObject = OpenCms.initCmsObject(cms); 461 m_macroCmsObject.getRequestContext().setSiteRoot("/"); 462 } catch (CmsException e) { 463 if (LOG.isErrorEnabled()) { 465 LOG.error(Messages.get().getBundle().key( 466 Messages.ERR_SELECTWIDGET_INTERNAL_CONFIGURATION_2, 467 new Object [] {getClass().getName(), getConfiguration()})); 468 } 469 return Collections.EMPTY_LIST; 470 471 } 472 } 473 if (m_macroResolver == null) { 474 m_macroResolver = new CmsMacroResolver(); 475 m_macroResolver.setCmsObject(m_macroCmsObject); 476 m_macroResolver.setKeepEmptyMacros(true); 477 } 478 479 List selectOptions = getSelectOptions(); 480 if (selectOptions == null) { 481 String configuration = getConfiguration(); 482 if (configuration == null) { 483 configuration = param.getDefault(cms); 485 } 486 try { 487 parseConfigurationInternal(configuration, cms, param); 489 490 SortedSet sortOptions = new TreeSet (new CmsResourceSelectWidgetOptionComparator( 492 m_macroCmsObject, 493 m_sortMacro)); 494 CmsSelectWidgetOption option; 495 List resources; 496 CmsResourceFilter filter = CmsResourceFilter.ALL.addRequireType(getResourceTypeID()); 498 CmsRequestContext context = cms.getRequestContext(); 499 String oldSiteroot = context.getSiteRoot(); 500 context.setSiteRoot("/"); 501 resources = cms.readResources(m_resourceFolder.getRootPath(), filter, true); 502 context.setSiteRoot(oldSiteroot); 503 if (resources.size() == 0) { 504 if (LOG.isErrorEnabled()) { 505 LOG.error(Messages.get().getBundle().key( 506 Messages.LOG_ERR_SELECTWIDGET_NO_RESOURCES_FOUND_3, 507 configuration, 508 m_resourceFolder.getRootPath(), 509 OpenCms.getResourceManager().getResourceType(getResourceTypeID()).getTypeName())); 510 } 511 } 512 513 Iterator itResources = resources.iterator(); 514 CmsResource resource; 515 516 String displayName; 517 while (itResources.hasNext()) { 519 520 resource = (CmsResource)itResources.next(); 521 if (hasFilterProperty(resource, cms)) { 524 525 m_macroCmsObject.getRequestContext().setUri(resource.getRootPath()); 528 m_macroResolver.setResourceName(resource.getName()); 530 m_macroResolver.setMessages(widgetDialog.getMessages()); 532 displayName = m_macroResolver.resolveMacros(getDisplayOptionMacro()); 536 if (CmsStringUtil.isEmptyOrWhitespaceOnly(displayName)) { 539 displayName = resolveXpathMacros(cms, resource, getDisplayOptionMacro()); 542 } else { 543 displayName = resolveXpathMacros(cms, resource, displayName); 546 } 547 if (CmsStringUtil.isEmpty(displayName)) { 549 displayName = resource.getName(); 550 } 551 552 displayName = resolveXpathMacros(cms, resource, displayName); 553 554 if (!CmsStringUtil.isEmpty(displayName)) { 555 556 option = new CmsResourceSelectWidgetOption(resource, false, displayName); 558 sortOptions.add(option); 559 } 560 } 561 } 562 selectOptions = new LinkedList (sortOptions); 563 564 } catch (Exception e) { 565 if (LOG.isErrorEnabled()) { 566 LOG.error(Messages.get().getBundle().key( 567 Messages.ERR_SELECTWIDGET_CONFIGURATION_2, 568 getClass(), 569 configuration), e); 570 } 571 } 572 573 if (selectOptions == Collections.EMPTY_LIST) { 574 selectOptions = new ArrayList (); 575 } 576 577 List pOptions = getSelectOptions(); 581 if (pOptions != null) { 582 pOptions.clear(); 583 } 584 Iterator it = selectOptions.iterator(); 585 while (it.hasNext()) { 586 addSelectOption((CmsSelectWidgetOption)it.next()); 587 } 588 } 589 return selectOptions; 590 } 591 592 private boolean hasFilterProperty(CmsResource resource, CmsObject cms) throws CmsException { 593 594 boolean result = false; 595 Iterator itFilterProperties; 596 Map.Entry entry; 597 CmsProperty property; 598 if (m_filterProperties.size() > 0) { 601 itFilterProperties = m_filterProperties.entrySet().iterator(); 602 while (itFilterProperties.hasNext()) { 603 entry = (Map.Entry )itFilterProperties.next(); 604 property = cms.readPropertyObject(resource, (String )entry.getKey(), true); 605 if (property == CmsProperty.getNullProperty()) { 606 continue; 607 } else { 608 if (property.getValue().equals(entry.getValue())) { 610 result = true; 612 break; 613 614 } else { 615 } 617 } 618 } 619 } else { 620 result = true; 622 } 623 624 return result; 625 } 626 627 644 private void parseConfigurationInternal(String configuration, CmsObject cms, I_CmsWidgetParameter param) { 645 646 CmsFile file = ((I_CmsXmlContentValue)param).getDocument().getFile(); 651 m_macroCmsObject.getRequestContext().setUri(file.getRootPath()); 652 List mappings = CmsStringUtil.splitAsList(configuration, '|'); 653 Iterator itMappings = mappings.iterator(); 654 String mapping; 655 String [] keyValue; 656 String key; 657 String value; 658 boolean displayMacroFound = false, sortMacroFound = false, folderFound = false, typeFound = false; 659 while (itMappings.hasNext()) { 660 mapping = (String )itMappings.next(); 661 keyValue = CmsStringUtil.splitAsArray(mapping, '='); 662 if (keyValue.length != 2) { 663 throw new CmsIllegalArgumentException(Messages.get().container( 664 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEYVALUE_LENGTH_1, 665 mapping)); 666 } 667 key = keyValue[0].trim(); 668 value = keyValue[1].trim(); 669 670 m_macroResolver.setResourceName(file.getName()); 672 if (CONFIGURATION_OPTION_DISPLAY_MACRO.equals(key)) { 674 if (displayMacroFound) { 675 throw new CmsIllegalArgumentException(Messages.get().container( 676 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_DUPLICATE_2, 677 key, 678 configuration)); 679 } 680 681 m_displayOptionMacro = value; 682 displayMacroFound = true; 683 } else if (CONFIGURATION_OPTION_SORT_MACRO.equals(key)) { 684 if (sortMacroFound) { 685 throw new CmsIllegalArgumentException(Messages.get().container( 686 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_DUPLICATE_2, 687 key, 688 configuration)); 689 } 690 m_sortMacro = value; 691 sortMacroFound = true; 692 693 } else if (CONFIGURATION_RESOURCETYPENAME.equals(key)) { 694 if (typeFound) { 695 throw new CmsIllegalArgumentException(Messages.get().container( 696 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_DUPLICATE_2, 697 key, 698 configuration)); 699 } 700 try { 703 m_resourceTypeID = OpenCms.getResourceManager().getResourceType(value).getTypeId(); 704 } catch (CmsLoaderException e) { 705 throw new CmsIllegalArgumentException(org.opencms.file.Messages.get().container( 706 org.opencms.file.Messages.ERR_UNKNOWN_RESOURCE_TYPE_1, 707 value), e); 708 } 709 typeFound = true; 710 711 } else if (CONFIGURATION_TOPFOLDER.equals(key)) { 712 if (folderFound) { 713 throw new CmsIllegalArgumentException(Messages.get().container( 714 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_DUPLICATE_2, 715 key, 716 configuration)); 717 } 718 719 value = m_macroResolver.resolveMacros(value); 721 722 try { 723 CmsRequestContext context = cms.getRequestContext(); 724 String oldSiteRoot = context.getSiteRoot(); 725 context.setSiteRoot("/"); 726 CmsResource resource = cms.readResource(value); 727 context.setSiteRoot(oldSiteRoot); 728 if (resource.isFile()) { 729 throw new CmsIllegalArgumentException(Messages.get().container( 730 Messages.ERR_SELECTWIDGET_CONFIGURATION_RESOURCE_NOFOLDER_2, 731 value, 732 configuration)); 733 } 734 m_resourceFolder = resource; 735 } catch (CmsException e) { 736 throw new CmsIllegalArgumentException(Messages.get().container( 737 Messages.ERR_SELECTWIDGET_CONFIGURATION_RESOURCE_INVALID_2, 738 value, 739 configuration), e); 740 } 741 742 folderFound = true; 743 } else { 744 746 CmsPropertyDefinition propDef; 747 try { 748 propDef = cms.readPropertyDefinition(key); 749 } catch (CmsException e) { 750 751 throw new CmsIllegalArgumentException(Messages.get().container( 752 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_UNKNOWN_2, 753 key, 754 getClass().getName()), e); 755 } 756 if (propDef != null) { 757 value = m_macroResolver.resolveMacros(value); 761 m_filterProperties.put(key, value); 762 763 } else { 764 765 throw new CmsIllegalArgumentException(Messages.get().container( 766 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_UNKNOWN_2, 767 key, 768 getClass().getName())); 769 } 770 } 771 } 772 773 if (!displayMacroFound) { 775 throw new CmsIllegalArgumentException(Messages.get().container( 776 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_MISSING_3, 777 CONFIGURATION_OPTION_DISPLAY_MACRO, 778 configuration, 779 getClass().getName())); 780 } 781 if (!folderFound) { 782 throw new CmsIllegalArgumentException(Messages.get().container( 783 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_MISSING_3, 784 CONFIGURATION_TOPFOLDER, 785 configuration, 786 getClass().getName())); 787 } 788 if (!typeFound) { 789 throw new CmsIllegalArgumentException(Messages.get().container( 790 Messages.ERR_SELECTWIDGET_CONFIGURATION_KEY_MISSING_3, 791 CONFIGURATION_RESOURCETYPENAME, 792 configuration, 793 getClass().getName())); 794 } 795 } 796 797 815 private String resolveXpathMacros(CmsObject cms, CmsResource resource, String value) throws CmsException { 816 817 StringBuffer result = new StringBuffer (); 818 int startmacro = value.indexOf("${xpath."); 819 int stopmacro = 0; 820 String xpath; 821 if (startmacro != -1) { 822 823 CmsXmlContent xmlcontent = CmsXmlContentFactory.unmarshal(cms, CmsFile.upgrade(resource, cms)); 825 Locale locale = CmsLocaleManager.getLocale(cms.readPropertyObject( 828 xmlcontent.getFile(), 829 CmsPropertyDefinition.PROPERTY_LOCALE, 830 true).getValue()); 831 832 while (startmacro != -1) { 833 stopmacro = value.indexOf('}'); 834 if (stopmacro == 0) { 835 } 837 838 result.append(value.substring(0, startmacro)); 840 xpath = value.substring(startmacro + 8, stopmacro); 842 try { 848 result.append(xmlcontent.getValue(xpath, locale).getPlainText(cms)); 849 } catch (Exception ex) { 850 if (LOG.isErrorEnabled()) { 851 LOG.error(Messages.get().getBundle().key( 852 Messages.LOG_ERR_SELECTWIDGET_XPATH_INVALID_4, 853 new Object [] { 854 xpath, 855 locale.toString(), 856 xmlcontent.getFile().getRootPath(), 857 ex.getLocalizedMessage()})); 858 } 859 } 860 value = value.substring(stopmacro + 1); 862 863 startmacro = value.indexOf("${xpath."); 865 } 866 } 867 result.append(value); 869 return result.toString(); 870 871 } 872 873 } 874 | Popular Tags |