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.xml.content; 029 030import org.opencms.util.CmsStringUtil; 031 032import java.io.Serializable; 033 034/** 035 * Describes both VFS properties and Container Page Element settings, used by the GWT client.<p> 036 * 037 * Warning: This class is used by GWT client-side code (See GwtBase.gwt.xml for a list of 038 * classes used by GWT client-side code). If you change this class, either make sure that 039 * your changes are compatible with GWT, or write a separate client version of the class 040 * and put it into super_src. 041 * 042 * @since 8.0.0 043 */ 044public class CmsXmlContentProperty implements Serializable { 045 046 /** Type constants. */ 047 public enum PropType { 048 049 /** Type constant string. */ 050 string, 051 /** Type constant VFS list. */ 052 vfslist; 053 054 /** 055 * Checks if the given type is {@link #vfslist}.<p> 056 * 057 * @param type the type to check 058 * 059 * @return <code>true</code> if the given type is {@link #vfslist} 060 */ 061 public static boolean isVfsList(String type) { 062 063 if (type == null) { 064 return false; 065 } 066 return valueOf(type.toLowerCase()) == vfslist; 067 } 068 } 069 070 /** The property visibility options. */ 071 public enum Visibility { 072 073 /** Visible only on the element. */ 074 element, 075 076 /** Visible in both element and list parent as an individual setting. */ 077 elementAndParentIndividual, 078 079 /** Visible in both element and list parent as a shared setting. */ 080 elementAndParentShared, 081 082 /** Visible only on list parent, as individual setting. */ 083 parentIndividual, 084 085 /** Visible only on list parent, as shared setting. */ 086 parentShared; 087 088 /** 089 * True if it should be visible on the element itself. 090 * 091 * @return true if visible on the element 092 **/ 093 public boolean isVisibleOnElement() { 094 095 return (this == Visibility.element) 096 || (this == elementAndParentIndividual) 097 || (this == elementAndParentShared); 098 } 099 } 100 101 /** XML node name constants. */ 102 public enum XmlNode { 103 104 /** Value file list node name. */ 105 FileList, 106 /** Container or property name node name. */ 107 Name, 108 /** Element properties node name. */ 109 Properties, 110 /** Value string node name. */ 111 String, 112 /** File list URI node name. */ 113 Uri, 114 /** Value node name. */ 115 Value; 116 } 117 118 /** IDs separator constant. */ 119 public static final String PROP_SEPARATOR = ","; 120 121 /** The serialization uid. */ 122 private static final long serialVersionUID = -7718747702874213381L; 123 124 /** The property visibility. */ 125 protected Visibility m_visibility; 126 127 /** Alias names, separated by pipes, possibly null. */ 128 private String m_aliasName; 129 130 /** Default value. */ 131 private String m_default; 132 133 /** The description. */ 134 private String m_description; 135 136 /** The error message. */ 137 private String m_error; 138 139 /** The include name. */ 140 private String m_includeName; 141 142 /** The name of the property. */ 143 private String m_name; 144 145 /** The nice name. */ 146 private String m_niceName; 147 148 /** The "prefer folder" option. */ 149 private String m_preferFolder; 150 151 /** The validation rule regex. */ 152 private String m_ruleRegex; 153 154 /** The validation rule type. */ 155 private String m_ruleType; 156 157 /** The value which indicates whether the user can influence how this property is going to be inherited. */ 158 private String m_selectInherit; 159 160 /** newvalue:oldvalue pairs separated by pipes. */ 161 private String m_translation; 162 163 /** The property type. */ 164 private String m_type; 165 166 /** The widget to use in the editor. */ 167 private String m_widget; 168 169 /** The widget configuration. */ 170 private String m_widgetConfiguration; 171 172 /** 173 * Public constructor.<p> 174 * 175 * @param name the property name 176 * @param type the property type (string|uri) 177 * @param widget the widget 178 * @param widgetConfiguration the widget configuration 179 * @param ruleRegex the validation rule regex 180 * @param ruleType the validation rule type 181 * @param default1 the default value 182 * @param niceName the nice-name 183 * @param description the description 184 * @param error the error message 185 * @param preferFolder the "prefer folder" option 186 */ 187 public CmsXmlContentProperty( 188 String name, 189 String type, 190 String widget, 191 String widgetConfiguration, 192 String ruleRegex, 193 String ruleType, 194 String default1, 195 String niceName, 196 String description, 197 String error, 198 String preferFolder 199 200 ) { 201 202 this( 203 name, 204 null, 205 type, 206 null, // visibility 207 widget, 208 widgetConfiguration, 209 ruleRegex, 210 ruleType, 211 default1, 212 niceName, 213 description, 214 error, 215 preferFolder, 216 null); 217 } 218 219 /** 220 * Public constructor.<p> 221 * 222 * @param name the property name 223 * @param aliasName the alias name (can also contain multiple aliases separated by pipes) 224 * @param type the property type (string|uri) 225 * @param visibility the visibility of the property, used in the container page element context 226 * @param widget the widget 227 * @param widgetConfiguration the widget configuration 228 * @param ruleRegex the validation rule regex 229 * @param ruleType the validation rule type 230 * @param default1 the default value 231 * @param niceName the nice-name 232 * @param description the description 233 * @param error the error message 234 * @param preferFolder the "prefer folder" option 235 * @param translation the value translation string (newval1:oldval1|newval2:oldval2|...) 236 */ 237 public CmsXmlContentProperty( 238 String name, 239 String aliasName, 240 String type, 241 Visibility visibility, 242 String widget, 243 String widgetConfiguration, 244 String ruleRegex, 245 String ruleType, 246 String default1, 247 String niceName, 248 String description, 249 String error, 250 String preferFolder, 251 String translation 252 253 ) { 254 255 super(); 256 m_name = name; 257 m_type = type; 258 m_visibility = visibility; 259 m_widget = widget; 260 m_widgetConfiguration = widgetConfiguration; 261 m_ruleRegex = ruleRegex; 262 m_ruleType = ruleType; 263 m_default = default1; 264 m_niceName = niceName; 265 m_description = description; 266 m_error = error; 267 m_preferFolder = preferFolder; 268 m_aliasName = CmsStringUtil.isEmptyOrWhitespaceOnly(aliasName) ? null : aliasName; 269 m_translation = CmsStringUtil.isEmptyOrWhitespaceOnly(translation) ? null : translation; 270 } 271 272 /** 273 * Serialization constructor.<p> 274 */ 275 protected CmsXmlContentProperty() { 276 277 // empty 278 } 279 280 /** 281 * Gets the fist non-null value.<p> 282 * 283 * @param o1 the first value 284 * @param o2 the second value 285 * 286 * @return the first non-null value 287 */ 288 private static <T> T firstNotNull(T o1, T o2) { 289 290 if (o1 != null) { 291 return o1; 292 } 293 return o2; 294 } 295 296 /** 297 * Copies this property definition.<p> 298 * 299 * @return a new copy of the current property definition 300 */ 301 public CmsXmlContentProperty copy() { 302 303 return new CmsXmlContentProperty( 304 m_name, 305 m_aliasName, 306 m_type, 307 m_visibility, 308 m_widget, 309 m_widgetConfiguration, 310 m_ruleRegex, 311 m_ruleType, 312 m_default, 313 m_niceName, 314 m_description, 315 m_error, 316 m_preferFolder, 317 m_translation); 318 } 319 320 /** 321 * Gets the alias name (can also be a list of alias names separated by pipes). 322 * 323 * @return the alias name(s) 324 */ 325 public String getAliasName() { 326 327 return m_aliasName; 328 } 329 330 /** 331 * Gets the configured visibility, without using a default value. 332 * 333 * @return the configured visibility 334 */ 335 public Visibility getConfiguredVisibility() { 336 337 return m_visibility; 338 } 339 340 /** 341 * Gets the configured widget, without using a default if it is null.<p> 342 * 343 * @return the configured widget 344 */ 345 public String getConfiguredWidget() { 346 347 return m_widget; 348 } 349 350 /** 351 * Returns the default.<p> 352 * 353 * @return the default 354 */ 355 public String getDefault() { 356 357 return m_default; 358 } 359 360 /** 361 * Returns the description.<p> 362 * 363 * @return the description 364 */ 365 public String getDescription() { 366 367 return m_description; 368 } 369 370 /** 371 * Returns the error.<p> 372 * 373 * @return the error 374 */ 375 public String getError() { 376 377 return m_error; 378 } 379 380 /** 381 * Gets the include name.<p> 382 * 383 * This is only used for element settings in formatters, where defaults from setting configuration files 384 * can be imported. The returned value is used to look up the setting name to look up for such an import in the 385 * setting configuration file. 386 * 387 * @param defaultValue the value that should be returned if no include name is configured 388 * @return the include name 389 */ 390 public String getIncludeName(String defaultValue) { 391 392 if (m_includeName != null) { 393 return m_includeName; 394 } 395 return defaultValue; 396 } 397 398 /** 399 * Returns the property name.<p> 400 * 401 * @return the property name 402 */ 403 public String getName() { 404 405 return m_name; 406 } 407 408 /** 409 * Returns the niceName.<p> 410 * 411 * @return the niceName 412 */ 413 public String getNiceName() { 414 415 return m_niceName; 416 } 417 418 /** 419 * Returns the ruleRegex.<p> 420 * 421 * @return the ruleRegex 422 */ 423 public String getRuleRegex() { 424 425 return m_ruleRegex; 426 } 427 428 /** 429 * Returns the rule type.<p> 430 * 431 * @return the rule type 432 */ 433 public String getRuleType() { 434 435 return m_ruleType; 436 } 437 438 /** 439 * Returns a value which indicates whether the user can control the inheritance of this property.<p> 440 * 441 * @return the "select-inherit" property 442 */ 443 public String getSelectInherit() { 444 445 return m_selectInherit; 446 } 447 448 /** 449 * Gets the value translation string, which has the form newval1:oldval1|newval2:oldval2|... . 450 * 451 * @return the value translation string 452 */ 453 public String getTranslationStr() { 454 455 return m_translation; 456 } 457 458 /** 459 * Returns the property type.<p> 460 * 461 * @return the property type 462 */ 463 public String getType() { 464 465 return m_type; 466 } 467 468 /** 469 * Returns the visibility of the property, used in the container page element context.<p> 470 * 471 * @param defaultValue the default value to return if the visibility is not set 472 * 473 * @return the visibility of the property 474 */ 475 public Visibility getVisibility(Visibility defaultValue) { 476 477 if (m_visibility == null) { 478 return defaultValue; 479 } 480 return m_visibility; 481 } 482 483 /** 484 * Returns the widget.<p> 485 * 486 * @return the widget 487 */ 488 public String getWidget() { 489 490 if (m_widget == null) { 491 return "string"; 492 } 493 return m_widget; 494 } 495 496 /** 497 * Returns the widgetConfiguration.<p> 498 * 499 * @return the widgetConfiguration 500 */ 501 public String getWidgetConfiguration() { 502 503 return m_widgetConfiguration; 504 } 505 506 /** 507 * Returns the value of the "prefer folder" option.<p> 508 * 509 * This flag determines whether a property entered in the sitemap entry editor should be stored by default at the folder 510 * or at the default file of a sitemap entry. It only has an effect if the sitemap entry being edited doesn't already 511 * have a value for that property at either location.<p> 512 * 513 * @return the "prefer folder" flag 514 */ 515 public boolean isPreferFolder() { 516 517 return (m_preferFolder == null) || Boolean.valueOf(m_preferFolder).booleanValue(); 518 519 } 520 521 /** 522 * Merges this object with another one containing default values.<p> 523 * 524 * This method does not modify this object or the object passed as a parameter. 525 * The resulting object's fields will be filled with the values from the default if they're null in this object. 526 * 527 * @param defaults the object with the defaults 528 * 529 * @return the result of merging this object with the defaults 530 */ 531 public CmsXmlContentProperty mergeDefaults(CmsXmlContentProperty defaults) { 532 533 return new CmsXmlContentProperty( 534 firstNotNull(m_name, defaults.m_name), 535 firstNotNull(m_aliasName, defaults.m_aliasName), 536 firstNotNull(m_type, defaults.m_type), 537 firstNotNull(m_visibility, defaults.m_visibility), 538 firstNotNull(m_widget, defaults.m_widget), 539 firstNotNull(m_widgetConfiguration, defaults.m_widgetConfiguration), 540 firstNotNull(m_ruleRegex, defaults.m_ruleRegex), 541 firstNotNull(m_ruleType, defaults.m_ruleType), 542 firstNotNull(m_default, defaults.m_default), 543 firstNotNull(m_niceName, defaults.m_niceName), 544 firstNotNull(m_description, defaults.m_description), 545 firstNotNull(m_error, defaults.m_error), 546 firstNotNull(m_preferFolder, defaults.m_preferFolder), 547 firstNotNull(m_translation, defaults.m_translation)); 548 } 549 550 /** 551 * Returns a modified copy of this bean with a different widget configuration.<p> 552 * 553 * @param config the new widget configuration 554 * @return the copy with the modified widget configuration 555 */ 556 public CmsXmlContentProperty withConfig(String config) { 557 558 return new CmsXmlContentProperty( 559 m_name, 560 m_aliasName, 561 m_type, 562 m_visibility, 563 m_widget, 564 config, 565 m_ruleRegex, 566 m_ruleType, 567 m_default, 568 m_niceName, 569 m_description, 570 m_error, 571 m_preferFolder, 572 m_translation); 573 } 574 575 /** 576 * Copies a property definition, but replaces an empty widget with a given widget.<p> 577 * 578 * @param defaultWidget the widget to use if the set widget is empty 579 * 580 * @return the copied property definition 581 */ 582 public CmsXmlContentProperty withDefaultWidget(String defaultWidget) { 583 584 return new CmsXmlContentProperty( 585 m_name, 586 m_aliasName, 587 m_type, 588 m_visibility, 589 CmsStringUtil.isEmptyOrWhitespaceOnly(m_widget) ? defaultWidget : m_widget, 590 m_widgetConfiguration, 591 m_ruleRegex, 592 m_ruleType, 593 m_default, 594 m_niceName, 595 m_description, 596 m_error, 597 m_preferFolder, 598 m_translation); 599 } 600 601 /** 602 * Creates a copy of this object with its include name set to a specific value.<p> 603 * 604 * @param includeName the include name to use 605 * 606 * @return the copy with the include name set 607 */ 608 public CmsXmlContentProperty withIncludeName(String includeName) { 609 610 CmsXmlContentProperty result = copy(); 611 if (includeName != null) { 612 includeName = includeName.trim(); 613 } 614 result.m_includeName = includeName; 615 return result; 616 } 617 618 /** 619 * Copies a property definition, but replaces the nice name attribute.<p> 620 * 621 * @param name the new nice name attribute 622 * 623 * @return the copied property definition 624 */ 625 public CmsXmlContentProperty withName(String name) { 626 627 return new CmsXmlContentProperty( 628 name, 629 m_aliasName, 630 m_type, 631 m_visibility, 632 m_widget, 633 m_widgetConfiguration, 634 m_ruleRegex, 635 m_ruleType, 636 m_default, 637 m_niceName, 638 m_description, 639 m_error, 640 m_preferFolder, 641 m_translation); 642 } 643 644 /** 645 * Copies a property definition, but replaces the nice name attribute.<p> 646 * 647 * @param niceName the new nice name attribute 648 * 649 * @return the copied property definition 650 */ 651 public CmsXmlContentProperty withNiceName(String niceName) { 652 653 return new CmsXmlContentProperty( 654 m_name, 655 m_aliasName, 656 m_type, 657 m_visibility, 658 m_widget, 659 m_widgetConfiguration, 660 m_ruleRegex, 661 m_ruleType, 662 m_default, 663 niceName, 664 m_description, 665 m_error, 666 m_preferFolder, 667 m_translation); 668 } 669 670 /** 671 * Copies the property definition, but replaces the fields related to validation. 672 * 673 * @param pattern the validation pattern 674 * @param type the validation type 675 * @param error the validation error message 676 * 677 * @return the copied property definition 678 */ 679 public CmsXmlContentProperty withValidation(String pattern, String type, String error) { 680 681 return new CmsXmlContentProperty( 682 m_name, 683 m_aliasName, 684 m_type, 685 m_visibility, 686 m_widget, 687 m_widgetConfiguration, 688 pattern, 689 type, 690 m_default, 691 m_niceName, 692 m_description, 693 error, 694 m_preferFolder, 695 m_translation); 696 } 697 698}