001/* 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: AttributeSchema.java,v 1.13 2009/01/13 06:56:08 mahesh_prasad_r Exp $ 026 * 027 * Portions Copyrighted 2014-2016 ForgeRock AS. 028 */ 029 030package com.sun.identity.sm; 031 032import java.security.AccessController; 033import java.text.MessageFormat; 034import java.util.Collections; 035import java.util.HashMap; 036import java.util.HashSet; 037import java.util.Iterator; 038import java.util.Map; 039import java.util.Set; 040 041import org.w3c.dom.Document; 042import org.w3c.dom.Element; 043import org.w3c.dom.Node; 044 045import com.sun.identity.shared.debug.Debug; 046import com.sun.identity.shared.xml.XMLUtils; 047import com.iplanet.sso.SSOException; 048import com.sun.identity.security.EncodeAction; 049 050/** 051 * The class <code>AttributeSchema</code> provides methods to access the 052 * schema of a configuration parameter. Also, it provides methods to set default 053 * and choice values. 054 * 055 * @supported.all.api 056 */ 057public class AttributeSchema { 058 // Debug 059 private Debug debug = Debug.getInstance("amSMS"); 060 061 // Instance variable 062 ServiceSchemaManager ssm; 063 064 ServiceSchema ss; 065 066 PluginSchema ps; 067 068 AttributeSchemaImpl as; 069 070 /** 071 * Constructor. Makes it private so that it cannot be instantiated. 072 */ 073 private AttributeSchema() { 074 } 075 076 /** 077 * Constructor used by ServiceSchema to instantiate 078 * <code>AttributeSchema</code> objects. 079 */ 080 protected AttributeSchema(AttributeSchemaImpl as, ServiceSchemaManager ssm, 081 ServiceSchema ss) { 082 this.ssm = ssm; 083 this.ss = ss; 084 this.as = as; 085 if (as == null) { 086 debug.error("AttributeSchema:: IMPL is NULL"); 087 } 088 } 089 090 protected AttributeSchema(AttributeSchemaImpl as, PluginSchema ps) { 091 this.as = as; 092 this.ps = ps; 093 } 094 095 /** 096 * Returns the name of the attribute. 097 * 098 * @return the name of the attribute 099 */ 100 public String getName() { 101 return (as.getName()); 102 } 103 104 /** 105 * Returns the type of the attribute. 106 * 107 * @return the type of the attribute 108 */ 109 public AttributeSchema.Type getType() { 110 return (as.getType()); 111 } 112 113 /** 114 * Returns Service Schema. 115 * 116 * @return Service Schema. 117 */ 118 public ServiceSchema getServiceSchema() { 119 return ss; 120 } 121 122 /** 123 * Sets the type. 124 * 125 * @param type 126 * to be changed to 127 * @throws SMSException 128 * if an error is encountered when trying to set 129 * @throws SSOException 130 * if the single sign on token is invalid or expired 131 */ 132 public void setType(String type) throws SMSException, SSOException { 133 updateXMLDocument(SMSUtils.ATTRIBUTE_TYPE, type); 134 } 135 136 /** 137 * Returns the list order of the attribute. 138 * 139 * @return The list order of the attribute, or {@code null} if the list order is not defined. 140 */ 141 public AttributeSchema.ListOrder getListOrder() { 142 return as.getListOrder(); 143 } 144 145 /** 146 * Returns the UI type of the attribute. 147 * 148 * @return the UI type of the attribute; or null if the UI Type is not 149 * defined 150 */ 151 public AttributeSchema.UIType getUIType() { 152 return (as.getUIType()); 153 } 154 155 /** 156 * Sets the <code>UIType</code> attribute. 157 * 158 * @param uiType 159 * user interface type. 160 * @throws SMSException 161 * if an error is encountered when trying to set 162 * <code>UIType</code> to the attribute schema. 163 * @throws SSOException 164 * if the single sign on token is invalid or expired 165 */ 166 public void setUIType(String uiType) throws SMSException, SSOException { 167 updateXMLDocument(SMSUtils.ATTRIBUTE_UITYPE, uiType); 168 } 169 170 /** 171 * Returns the syntax of the attribute. 172 * 173 * @return the syntax of the attribute 174 */ 175 public AttributeSchema.Syntax getSyntax() { 176 return (as.getSyntax()); 177 } 178 179 /** 180 * Sets the Syntax attribute. 181 * 182 * @param synt 183 * syntax 184 * @throws SMSException 185 * if an error is encountered when trying to set the attribute 186 * syntax 187 * @throws SSOException 188 * if the single sign on token is invalid or expired 189 */ 190 public void setSyntax(String synt) throws SMSException, SSOException { 191 updateXMLDocument(SMSUtils.ATTRIBUTE_SYNTAX, synt); 192 } 193 194 /** 195 * Returns the I18N key to describe the configuration attribute. 196 * 197 * @return the I18N key to describe the configuration attribute 198 */ 199 public String getI18NKey() { 200 return (as.getI18NKey()); 201 } 202 203 /** 204 * Sets the I18N key to describe the configuration attribute. 205 * 206 * @param i18nKey 207 * the I18N key to describe the attribute 208 * @throws SMSException 209 * if an error is encountered when trying to set I18N key to the 210 * attribute schema 211 * @throws SSOException 212 * if the single sign on token is invalid or expired 213 */ 214 public void setI18NKey(String i18nKey) throws SMSException, SSOException { 215 updateXMLDocument(SMSUtils.I18N_KEY, i18nKey); 216 } 217 218 /** 219 * Returns the value of the <code>cosQualifier</code> for this attribute 220 * that is <code>default, override, operational or merge-cos</code>. 221 * 222 * @return the value of the <code>cosQualifier</code>. 223 */ 224 public String getCosQualifier() { 225 return (as.getCosQualifier()); 226 } 227 228 /** 229 * Sets the <code>cosQualifier</code> attribute 230 * 231 * @param cosq 232 * value of <code>cosQualifier</code>. 233 * @throws SMSException 234 * if an error is encountered when trying to set. 235 * @throws SSOException 236 * if the single sign on token is invalid or expired 237 */ 238 public void setCosQualifier(String cosq) throws SMSException, SSOException { 239 updateXMLDocument(SMSUtils.ATTRIBUTE_COS_QUALIFIER, cosq); 240 } 241 242 /** 243 * Returns the default values of the attribute. If there are no default 244 * values defined for this attribute in the schema then this method returns 245 * a Collections.EMPTY_SET 246 * 247 * @return set of default values of the attribute 248 */ 249 public Set getDefaultValues() { 250 return (as.getDefaultValues()); 251 } 252 253 /** 254 * Returns the default values of the attribute for the given environment 255 * parameters. If there are no default values defined for this attribute in 256 * the schema then this method returns a Collections.EMPTY_SET 257 * 258 * @param envParams 259 * Map of environment parameter to a set of values 260 * @return set of default values of the attribute 261 */ 262 public Set getDefaultValues(Map envParams) { 263 return (as.getDefaultValues(envParams)); 264 } 265 266 /** 267 * Sets the default values of the attribute. 268 * 269 * @param values 270 * the set of default values 271 * @throws SMSException 272 * if an error is encountered when trying to set. 273 * @throws SSOException 274 * if the single sign on token is invalid or expired 275 */ 276 public void setDefaultValues(Set values) throws SMSException, SSOException { 277 updateDefaultValues(values); 278 } 279 280 /** 281 * Protected method to set the default values in the given XML document. 282 * 283 * @throws SMSException 284 * if an error is encountered when trying to set. 285 * @throws SSOException 286 * if the single sign on token is invalid or expired 287 */ 288 void setDefaultValues(Set values, Document document) throws SMSException, 289 SSOException { 290 updateDefaultValues(values, document); 291 } 292 293 /** 294 * Adds a default value to the existing set of default values. 295 * 296 * @param value 297 * the default value to add 298 * @throws SMSException 299 * if an error is encountered when trying to set. 300 * @throws SSOException 301 * if the single sign on token is invalid or expired 302 */ 303 public void addDefaultValue(String value) throws SMSException, SSOException 304 { 305 Set defaultValues = getDefaultValues(); 306 if (defaultValues != Collections.EMPTY_SET) { 307 defaultValues.add(value); 308 } else { 309 defaultValues = new HashSet(); 310 defaultValues.add(value); 311 } 312 updateDefaultValues(defaultValues); 313 } 314 315 /** 316 * Removes the all the default values for the attribute. 317 * 318 * @throws SMSException 319 * if an error is encountered when trying to set. 320 * @throws SSOException 321 * if the single sign on token is invalid or expired 322 * 323 */ 324 public void removeDefaultValues() throws SMSException, SSOException { 325 updateDefaultValues(new HashSet()); 326 } 327 328 /** 329 * Removes the given value from the set of default values. 330 * 331 * @param value 332 * the default value to remove 333 * @throws SMSException 334 * if an error is encountered when trying to set. 335 * @throws SSOException 336 * if the single sign on token is invalid or expired 337 */ 338 public void removeDefaultValue(String value) throws SMSException, 339 SSOException { 340 Set defaultValues = getDefaultValues(); 341 if (defaultValues != Collections.EMPTY_SET) { 342 defaultValues.remove(value); 343 updateDefaultValues(defaultValues); 344 } 345 } 346 347 /** 348 * Returns the possible choice values for the attribute if the attribute 349 * type is either <code>SINGLE_CHOICE</code> or 350 * <code>MULTIPLE_CHOICE</code>. 351 * 352 * @return set of possible choice values 353 */ 354 public String[] getChoiceValues() { 355 return (as.getChoiceValues()); 356 } 357 358 /** 359 * Returns the possible choice values for the attribute if the attribute 360 * type is either <code>SINGLE_CHOICE</code> or 361 * <code>MULTIPLE_CHOICE</code>, for the given environment parameters. 362 * 363 * @param envParams 364 * Map of environment parameter to a set of values 365 * @return set of possible choice values 366 */ 367 public String[] getChoiceValues(Map envParams) { 368 return (as.getChoiceValues(envParams)); 369 } 370 371 /** 372 * Returns the possible choice values for the attribute if the attribute 373 * type is either <code>SINGLE_CHOICE</code> or 374 * <code>MULTIPLE_CHOICE</code>, for the given environment parameters, 375 * along with the values' i18n keys. 376 * 377 * @param envParams 378 * Map of environment parameter to a set of values 379 * @return Map of value to i18n key. 380 */ 381 public Map getChoiceValuesMap(Map envParams) { 382 return as.getChoiceValuesMap(envParams); 383 } 384 385 /** 386 * Indicates whether this AttributeSchema has choice values defined. 387 */ 388 public boolean hasChoiceValues() { 389 return as.hasChoiceValues(); 390 } 391 392 /** 393 * Returns the I18N key for the given choice value. 394 * 395 * @param cValue 396 * choice value. 397 * @return the I18N key for the given choice value 398 */ 399 public String getChoiceValueI18NKey(String cValue) { 400 return (as.getChoiceValueI18NKey(cValue)); 401 } 402 403 /** 404 * Adds a choice value and its i18n key to the existing set of choice 405 * values. 406 * 407 * @param value 408 * the choice value to add 409 * @param i18nKey 410 * the I18N key for the choice value 411 * @throws SMSException 412 * if an error is encountered when trying to set. 413 * @throws SSOException 414 * if the single sign on token is invalid or expired 415 */ 416 public void addChoiceValue(String value, String i18nKey) 417 throws SMSException, SSOException { 418 Map choiceValues = as.getChoiceValuesMap(); 419 choiceValues.put(value, i18nKey); 420 updateChoiceValues(choiceValues); 421 } 422 423 /** 424 * Removes the given value from the set of choice values. 425 * 426 * @param value 427 * the choice value to remove 428 * @throws SMSException 429 * if an error is encountered when trying to set. 430 * @throws SSOException 431 * if the single sign on token is invalid or expired 432 */ 433 public void removeChoiceValue(String value) throws SMSException, 434 SSOException { 435 Map choiceValues = as.getChoiceValuesMap(); 436 if (choiceValues.remove(value) != null) { 437 updateChoiceValues(choiceValues); 438 } 439 } 440 441 /** 442 * Returns the start range if the attribute syntax is either 443 * <code>NUMBER_RANGE</code> or <code>DECIMAL_RANGE</code>. 444 * 445 * @return the start range for the attribute value 446 */ 447 public String getStartRange() { 448 return (as.getStartRange()); 449 } 450 451 /** 452 * Sets the start range attribute. 453 * 454 * @param stRange 455 * start range. 456 * @throws SMSException 457 * if an error is encountered when trying to set 458 * @throws SSOException 459 * if the single sign on token is invalid or expired 460 */ 461 public void setStartRange(String stRange) throws SMSException, SSOException 462 { 463 updateXMLDocument(SMSUtils.ATTRIBUTE_RANGE_START, stRange); 464 } 465 466 /** 467 * Returns the end range if the attribute syntax is either 468 * <code>NUMBER_RANGE</code> or <code>DECIMAL_RANGE</code>. 469 * 470 * @return the end range for the attribute value 471 */ 472 public String getEndRange() { 473 return (as.getEndRange()); 474 } 475 476 /** 477 * Sets the end range Attribute. 478 * 479 * @param edRange 480 * end range. 481 * @throws SMSException 482 * if an error is encountered when trying to set 483 * @throws SSOException 484 * if the single sign on token is invalid or expired 485 */ 486 public void setEndRange(String edRange) throws SMSException, SSOException { 487 updateXMLDocument(SMSUtils.ATTRIBUTE_RANGE_END, edRange); 488 } 489 490 /** 491 * Method to get the validator name for using to validate this service 492 * attribute 493 * 494 * @return the validator name 495 */ 496 public String getValidator() { 497 return (as.getValidator()); 498 } 499 500 /** 501 * Sets the Validator attribute 502 * 503 * @param valid 504 * validator 505 * @throws SMSException 506 * if an error is encountered when trying to set 507 * @throws SSOException 508 * if the single sign on token is invalid or expired 509 */ 510 public void setValidator(String valid) throws SMSException, SSOException { 511 updateXMLDocument(SMSUtils.ATTRIBUTE_VALIDATOR, valid); 512 } 513 514 /** 515 * Returns the minimum number of values for the attribute if the attribute 516 * is of type <code>MULTIPLE_CHOICE</code>. 517 * 518 * @return the minimum number of values 519 */ 520 public int getMinValue() { 521 return (as.getMinValue()); 522 } 523 524 /** 525 * Sets the minimum value attribute. 526 * 527 * @param minV 528 * minimum value. 529 * @throws SMSException 530 * if an error is encountered when trying to set 531 * @throws SSOException 532 * if the single sign on token is invalid or expired 533 */ 534 public void setMinValue(String minV) throws SMSException, SSOException { 535 updateXMLDocument(SMSUtils.ATTRIBUTE_MIN_VALUE, minV); 536 } 537 538 /** 539 * Returns the maximum number of values for the attribute if the attribute 540 * is of type <code>MULTIPLE_CHOICE</code>. 541 * 542 * @return the maximum number of values 543 */ 544 public int getMaxValue() { 545 return (as.getMaxValue()); 546 } 547 548 /** 549 * Sets the maximum value attribute. 550 * 551 * @param maxV 552 * maximum value. 553 * @throws SMSException 554 * if an error is encountered when trying to set 555 * @throws SSOException 556 * if the single sign on token is invalid or expired 557 */ 558 public void setMaxValue(String maxV) throws SMSException, SSOException { 559 updateXMLDocument(SMSUtils.ATTRIBUTE_MAX_VALUE, maxV); 560 } 561 562 /** 563 * Sets the boolean values of the attribute. 564 * 565 * @param trueValue string value for <code>BooleanTrueValue</code>. 566 * @param trueValueI18nKey <code>I18N</code> key for 567 * <code>BooleanTrueValue</code>. 568 * @param falseValue string value for <code>BooleanFalseValue</code>. 569 * @param falseValueI18nKey <code>I18N</code> Key for 570 * <code>BooleanFalseValue</code>. 571 * @throws SMSException if an error is encountered when trying to set. 572 * @throws SSOException if the single sign on token is invalid or expired 573 */ 574 public void setBooleanValues( 575 String trueValue, 576 String trueValueI18nKey, 577 String falseValue, 578 String falseValueI18nKey 579 ) throws SSOException, SMSException { 580 updateBooleanValues(trueValue, trueValueI18nKey, 581 falseValue, falseValueI18nKey, null); 582 } 583 584 585 /** 586 * Returns the string value for <code>BooleanTrueValue</code>. 587 * 588 * @return the string value for <code>BooleanTrueValue</code>. 589 */ 590 public String getTrueValue() { 591 return (as.getTrueValue()); 592 } 593 594 /** 595 * Returns the <code>I18N</code> key for <code>BooleanTrueValue</code>. 596 * 597 * @return the <code>I18N</code> key for <code>BooleanTrueValue</code>. 598 */ 599 public String getTrueValueI18NKey() { 600 return (as.getTrueValueI18NKey()); 601 } 602 603 /** 604 * Returns the string value for <code>BooleanFalseValue</code>. 605 * 606 * @return the string value for <code>BooleanFalseValue</code>. 607 */ 608 public String getFalseValue() { 609 return (as.getFalseValue()); 610 } 611 612 /** 613 * Returns the <code>I18N</code> Key for <code>BooleanFalseValue</code>. 614 * 615 * @return the <code>I18N</code> Key for <code>BooleanFalseValue</code>. 616 */ 617 public String getFalseValueI18NKey() { 618 return (as.getFalseValueI18NKey()); 619 } 620 621 /** 622 * Returns true if the attribute is an optional attribute. 623 * 624 * @return true if the attribute is an optional attribute. 625 */ 626 public boolean isOptional() { 627 return (as.isOptional()); 628 } 629 630 /** 631 * Returns true if the attribute is a service identifier (i.e., in the case 632 * of LDAP it would be the COS Specifier attribute). 633 * 634 * @return true if the attribute is service identifier attribute. 635 */ 636 public boolean isServiceIdentifier() { 637 return (as.isServiceIdentifier()); 638 } 639 640 /** 641 * Checks if the attribute allows to have resource name. 642 * 643 * @return true if the attribute allows to have resource name; false 644 * otherwise 645 */ 646 public boolean isResourceNameAllowed() { 647 return (as.isResourceNameAllowed()); 648 } 649 650 /** 651 * Returns true if the attribute is a service's status attribute. 652 * 653 * @return true if the attribute is a status attribute. 654 */ 655 public boolean isStatusAttribute() { 656 return (as.isStatusAttribute()); 657 } 658 659 /** 660 * Method to get service specific attributes. It return the value of the 661 * "any" attribute, if set in the XML schema for the service 662 * 663 * @return value of "any" attribute 664 */ 665 public String getAny() { 666 return (as.getAny()); 667 } 668 669 /** 670 * Sets the any attribute. 671 * 672 * @param a 673 * value for any attribute. 674 * @throws SMSException 675 * if an error is encountered when trying to set. 676 * @throws SSOException 677 * if the single sign on token is invalid or expired. 678 */ 679 public void setAny(String a) throws SMSException, SSOException { 680 updateXMLDocument(SMSUtils.ATTRIBUTE_ANY, a); 681 } 682 683 /** 684 * Returns URL of the view bean for the attribute. 685 * 686 * @return URL for view bean 687 */ 688 public String getPropertiesViewBeanURL() { 689 return (as.getPropertiesViewBeanURL()); 690 } 691 692 /** 693 * Sets the URL of the view bean for the attribute. 694 * 695 * @param prop 696 * properties view bean URL. 697 * @throws SMSException 698 * if an error is encountered when trying to set. 699 * @throws SSOException 700 * if the single sign on token is invalid or expired. 701 */ 702 public void setPropertiesViewBeanUR(String prop) throws SMSException, 703 SSOException { 704 updateXMLDocument(SMSUtils.ATTRIBUTE_VIEW_BEAN_URL, prop); 705 } 706 707 /** 708 * Returns <code>true</code> if the attribute is searchable; 709 * <code>false</code> otherwise 710 * 711 * @return <code>true</code> if the attribute is an optional attribute; 712 * <code>false</code> otherwise 713 */ 714 public boolean isSearchable() { 715 return (as.isSearchable()); 716 } 717 718 /** 719 * Sets the attribute isSearchable, if value is set to <code>true 720 * </code>, 721 * or <code>false</code>. 722 * 723 * @param value 724 * if set to <code>true</code> the attribute will be 725 * searchable; else searches cannot be performed on this 726 * attribute. 727 * @throws SMSException 728 * if an error is encountered when trying to set 729 * @throws SSOException 730 * if the single sign on token is invalid or expired 731 */ 732 public void setSearchable(String value) throws SMSException, SSOException { 733 if ((!(value.toLowerCase()).equals("yes")) 734 && (!(value.toLowerCase()).equals("no"))) { 735 String[] arg = { value }; 736 debug.error("AttributeSchema: Invalid isSearchable value"); 737 throw new SMSException(SMSEntry.bundle 738 .getString("sms-invalid-searchable-value") 739 + ":" + arg, "sms-invalid-searchable-value"); 740 } 741 updateXMLDocument(SMSUtils.ISSEARCHABLE, value); 742 } 743 744 /** 745 * Returns the name of this attribute when used in a CREST representation. 746 */ 747 public String getResourceName() { 748 String resourceName = as.getResourceName(); 749 return resourceName == null ? getName() : resourceName; 750 } 751 752 /** 753 * Sets the CREST representation name for the attribute. 754 * 755 * @param name 756 * the name of the CREST property. 757 * @throws SMSException 758 * if an error is encountered when trying to set. 759 * @throws SSOException 760 * if the single sign on token is invalid or expired. 761 */ 762 public void setResourceName(String name) throws SSOException, SMSException { 763 updateXMLDocument(SMSUtils.RESOURCE_NAME, name); 764 } 765 766 /** 767 * Returns a string representation of this <code> AttributeSchema </code> 768 * object. 769 * 770 * @return String representation of this object 771 */ 772 public String toString() { 773 return (as.toString()); 774 } 775 776 /** 777 * Method for modifying default values 778 */ 779 protected void updateDefaultValues(Set defaultValues) throws SMSException, 780 SSOException { 781 updateDefaultValues(defaultValues, null); 782 } 783 784 /** 785 * Method for modifying default values given the XML document 786 */ 787 protected void updateDefaultValues(Set defaultValues, Document doc) 788 throws SMSException, SSOException { 789 // Check if the values are valid 790 if (ss != null) { 791 Map tempattrs = new HashMap(1); 792 tempattrs.put(getName(), defaultValues); 793 ss.validateAttributes(tempattrs); 794 } 795 796 // Check if the attributes have to be encoded 797 boolean encode = false; 798 if (getSyntax().equals(Syntax.PASSWORD) 799 || getSyntax().equals(Syntax.ENCRYPTED_PASSWORD)) { 800 encode = true; 801 } 802 803 // Construct DefaultValues node 804 StringBuffer sb = new StringBuffer(100); 805 sb.append(XML_PREFIX).append(DEFAULT_VALUES_BEGIN); 806 Iterator items = defaultValues.iterator(); 807 while (items.hasNext()) { 808 sb.append(VALUE_BEGIN); 809 if (encode) { 810 String encString = (String) items.next(); 811 try { 812 encString = (String) AccessController 813 .doPrivileged(new EncodeAction(encString)); 814 } catch (Throwable e) { 815 debug.error("AttributeSchema: Unable to encode", e); 816 } 817 sb.append(encString); 818 } else { 819 sb.append(SMSSchema.escapeSpecialCharacters((String) items 820 .next())); 821 } 822 sb.append(VALUE_END); 823 } 824 sb.append(DEFAULT_VALUES_END); 825 updateXMLDocument(sb, SMSUtils.ATTRIBUTE_DEFAULT_ELEMENT, doc); 826 } 827 828 protected void updateChoiceValues(Map choiceValues) throws SMSException, 829 SSOException { 830 updateChoiceValues(choiceValues, null); 831 } 832 833 protected void updateChoiceValues(Map choiceValues, Document doc) 834 throws SMSException, SSOException { 835 // Construct ChoiceValues 836 StringBuffer sb = new StringBuffer(100); 837 sb.append(XML_PREFIX).append(CHOICE_VALUES_BEGIN); 838 Iterator items = choiceValues.keySet().iterator(); 839 while (items.hasNext()) { 840 String[] vals = new String[2]; 841 String value = SMSSchema.escapeSpecialCharacters((String) items 842 .next()); 843 String i18nKey = (String) choiceValues.get(value); 844 if (i18nKey == null) { 845 vals[0] = value; 846 sb.append(MessageFormat.format(CHOICE_VALUE, (Object[])vals)); 847 } else { 848 vals[0] = i18nKey; 849 vals[1] = value; 850 sb.append(MessageFormat.format( 851 CHOICE_VALUE_KEY, (Object[])vals)); 852 } 853 } 854 sb.append(CHOICE_VALUES_END); 855 updateXMLDocument(sb, SMSUtils.ATTRIBUTE_CHOICE_VALUES_ELEMENT, doc); 856 } 857 858 protected void updateBooleanValues( 859 String trueValue, 860 String trueValueI18nKey, 861 String falseValue, 862 String falseValueI18nKey, 863 Document doc 864 ) throws SMSException, SSOException { 865 // Construct BooleanValues 866 StringBuffer sb = new StringBuffer(100); 867 sb.append(XML_PREFIX).append(BOOLEAN_VALUES_BEGIN); 868 869 String[] trueVals = new String[2]; 870 if ((trueValueI18nKey != null) && (trueValue != null)) { 871 trueVals[0] = trueValueI18nKey; 872 trueVals[1] = SMSSchema.escapeSpecialCharacters(trueValue); 873 } else { 874 trueVals[0] = getTrueValueI18NKey(); 875 trueVals[1] = getTrueValue(); 876 } 877 sb.append(MessageFormat.format(TRUE_BOOLEAN_KEY, (Object[])trueVals)); 878 879 String[] falseVals = new String[2]; 880 if ((falseValueI18nKey != null) && (falseValue != null)) { 881 falseVals[0] = falseValueI18nKey; 882 falseVals[1] = SMSSchema.escapeSpecialCharacters(falseValue); 883 } else { 884 falseVals[0] = getFalseValueI18NKey(); 885 falseVals[1] = getFalseValue(); 886 } 887 sb.append(MessageFormat.format(FALSE_BOOLEAN_KEY, (Object[])falseVals)); 888 889 sb.append(BOOLEAN_VALUES_END); 890 updateXMLDocument(sb, SMSUtils.ATTRIBUTE_BOOLEAN_VALUES_ELEMENT, doc); 891 } 892 893 protected void updateXMLDocument(StringBuffer sb, String elementName, 894 Document updateDoc) throws SMSException, SSOException { 895 // Update the default element in XML 896 try { 897 // Construct the XML document 898 Document doc = SMSSchema.getXMLDocument(sb.toString(), false); 899 Node node = XMLUtils.getRootNode(doc, elementName); 900 901 // Convert to Schema's document 902 Document schemaDoc = null; 903 if (updateDoc != null) { 904 schemaDoc = updateDoc; 905 } else if (ssm != null) { 906 schemaDoc = ssm.getDocumentCopy(); 907 } else { 908 schemaDoc = ps.getDocumentCopy(); 909 } 910 Node nNode = schemaDoc.importNode(node, true); 911 912 // Traverse the document to get this attribute element 913 Node schemaNode = null; 914 if (ss != null) { 915 schemaNode = ss.getSchemaNode(schemaDoc); 916 } else { 917 schemaNode = ps.getPluginSchemaNode(schemaDoc); 918 } 919 Node attrSchemaNode = XMLUtils.getNamedChildNode(schemaNode, 920 SMSUtils.SCHEMA_ATTRIBUTE, SMSUtils.NAME, getName()); 921 922 // Try getting OrganizationAttributeSchema if AttributeSchema 923 // node is not there within Organization node. 924 // This will be a special case for idrepo service. 925 if (attrSchemaNode == null) { 926 schemaNode = ss.getOrgAttrSchemaNode(schemaDoc); 927 attrSchemaNode = XMLUtils.getNamedChildNode(schemaNode, 928 SMSUtils.SCHEMA_ATTRIBUTE, SMSUtils.NAME, getName()); 929 } 930 Node oNode = XMLUtils.getChildNode(attrSchemaNode, elementName); 931 if (oNode != null) { 932 attrSchemaNode.replaceChild(nNode, oNode); 933 } else { 934 attrSchemaNode.appendChild(nNode); 935 } 936 // Update the schema in the directory 937 if (updateDoc != null) { 938 // do nothing 939 } else if (ssm != null) { 940 ssm.replaceSchema(schemaDoc); 941 } else { 942 ps.replacePluginSchema(schemaDoc); 943 } 944 } catch (Exception e) { 945 throw (new SMSException(e.getMessage(), e, 946 "sms-cannot-update-xml-document")); 947 } 948 } 949 950 /** 951 * update attribute value in attribute schema element 952 */ 953 protected void updateXMLDocument(String attrName, String attrValue) 954 throws SMSException, SSOException { 955 // Update the default element in XML 956 try { 957 // Construct the XML document 958 Document schemaDoc = null; 959 if (ssm != null) { 960 schemaDoc = ssm.getDocumentCopy(); 961 } else { 962 schemaDoc = ps.getDocumentCopy(); 963 } 964 965 // Traverse the document to get this attribute element 966 Node schemaNode = null; 967 if (ss != null) { 968 schemaNode = ss.getSchemaNode(schemaDoc); 969 } else { 970 schemaNode = ps.getPluginSchemaNode(schemaDoc); 971 } 972 973 Node attrSchemaNode = XMLUtils.getNamedChildNode(schemaNode, 974 SMSUtils.SCHEMA_ATTRIBUTE, SMSUtils.NAME, getName()); 975 ((Element) attrSchemaNode).setAttribute(attrName, attrValue); 976 977 // Update the schema in the directory 978 if (ssm != null) { 979 ssm.replaceSchema(schemaDoc); 980 } else { 981 ps.replacePluginSchema(schemaDoc); 982 } 983 } catch (Exception e) { 984 throw (new SMSException(e.getMessage(), e, 985 "sms-cannot-update-xml-document")); 986 } 987 } 988 989 /** 990 * The class <code>Type</code> defines the types of schema attributes and 991 * provides static constants for these types. This could also be viewed as a 992 * higher level structured data types like Set, List, etc. The primitive 993 * data types are defined by <code>Syntax</code>. Currently defined 994 * schema attribute types are <code>SINGLE</code>, <code>LIST</code>, 995 * <code>SINGLE_CHOICE</code>, <code>MULTIPLE_CHOICE</code>, 996 * <code>SIGNATURE</code> and <code>VALIDATOR</code>. 997 */ 998 public static class Type extends Object { 999 1000 /** 1001 * The <code>SINGLE</code> attribute type specifies that the attribute 1002 * can have only a single value. 1003 */ 1004 public static final Type SINGLE = new Type("single"); 1005 1006 /** 1007 * The <code>LIST</code> attribute type specifies that the attribute 1008 * can have multiple values, i.e., multi-valued attribute. 1009 */ 1010 public static final Type LIST = new Type("list"); 1011 1012 /** 1013 * The <code>SINGLE_CHOICE</code> attribute type specifies that the 1014 * attribute can have value defined by the <code>getChoiceValues</code> 1015 * method of <code>AttributeSchema</code>. 1016 */ 1017 public static final Type SINGLE_CHOICE = new Type("single_choice"); 1018 1019 /** 1020 * The <code>MULTIPLE_CHOICE</code> attribute type specifies that the 1021 * attribute can have multiple values defined by the 1022 * <code>getChoiceValues</code> method of <code>AttributeSchema</code>. 1023 */ 1024 public static final Type MULTIPLE_CHOICE = new Type("multiple_choice"); 1025 1026 /** 1027 * The <code>SIGNATURE</code> attribute type specifies that the 1028 * attribute is a signing attribute. 1029 */ 1030 public static final Type SIGNATURE = new Type("signature"); 1031 1032 /** 1033 * The <code>VALIDATOR</code> attribute type specifies that the 1034 * attribute defines a attribute validator plugin. 1035 */ 1036 public static final Type VALIDATOR = new Type("validator"); 1037 1038 private String attrType; 1039 1040 private Type() { 1041 } 1042 1043 private Type(String type) { 1044 attrType = type; 1045 } 1046 1047 /** 1048 * The method returns the string representation of the schema attribute 1049 * type. 1050 * 1051 * @return String string representation of schema attribute type 1052 */ 1053 public String toString() { 1054 return attrType; 1055 } 1056 1057 /** 1058 * Method to check if two schema attribute types are equal. 1059 * 1060 * @param schemaAttrType 1061 * the reference object with which to compare 1062 * 1063 * @return <code>true</code> if the objects are same; <code> 1064 * false</code> 1065 * otherwise 1066 */ 1067 public boolean equals(Object schemaAttrType) { 1068 if (schemaAttrType instanceof Type) { 1069 Type s = (Type) schemaAttrType; 1070 return (s.attrType.equals(attrType)); 1071 } 1072 return (false); 1073 } 1074 1075 /** 1076 * Returns a hash code value for the object. 1077 * 1078 * @return a hash code value for the object 1079 */ 1080 public int hashCode() { 1081 return attrType.hashCode(); 1082 } 1083 } 1084 1085 /** 1086 * This enum {@code ListOrder} defines the list orders of schema attributes and provides constants for these list 1087 * orders. These types will mainly be used by the GUI to determine how to display the schema attributes. 1088 */ 1089 public enum ListOrder { 1090 /** Orders lists naturally. */ 1091 NATURAL, 1092 /** Orders lists in the order they are entered in LDAP. */ 1093 INSERTION 1094 } 1095 1096 /** 1097 * The class <code>UIType</code> defines the UI types of schema attributes 1098 * and provides static constants for these types. These types mainly will be 1099 * used by the GUI to determine how to display the schema attributes. 1100 * Currently defined schema attribute UI types are <code>RADIO</code>, 1101 * <code>LINK</code>, <code>BUTTON</code> and 1102 * <code>NAME_VALUE_LIST</code> 1103 */ 1104 public static class UIType extends Object { 1105 1106 /** 1107 * The <code>RADIO</code> attribute type specifies that the attribute 1108 * should be display as radio button. 1109 */ 1110 public static final UIType RADIO = new UIType("radio"); 1111 1112 /** 1113 * The <code>LINK</code> attribute type specifies that the attribute 1114 * should be display as a link. 1115 */ 1116 public static final UIType LINK = new UIType("link"); 1117 1118 /** 1119 * The <code>BUTTON</code> attribute type specifies that the attribute 1120 * should be display as a button. 1121 */ 1122 public static final UIType BUTTON = new UIType("button"); 1123 1124 /** 1125 * The <code>NAME_VALUE_LIST</code> attribute type specifies that the 1126 * attribute should be display as a name value list widget. 1127 */ 1128 public static final UIType NAME_VALUE_LIST = new UIType( 1129 "name_value_list"); 1130 1131 /** 1132 * The <code>UNORDERED_LIST</code> attribute type specifies that the 1133 * attribute should be display as an unordered list widget. 1134 */ 1135 public static final UIType UNORDEREDLIST = new UIType("unorderedlist"); 1136 1137 /** 1138 * The <code>ORDERED_LIST</code> attribute type specifies that the 1139 * attribute should be display as an ordered list widget. 1140 */ 1141 public static final UIType ORDEREDLIST = new UIType("orderedlist"); 1142 1143 /** 1144 * The <code>MAP_LIST</code> attribute type specifies that the 1145 * attribute should be display as an map list widget. 1146 */ 1147 public static final UIType MAPLIST = new UIType("maplist"); 1148 1149 /** 1150 * The <code>GLOBALMAP_LIST</code> attribute type specifies that the 1151 * attribute should be display as a global map list widget. 1152 */ 1153 public static final UIType GLOBALMAPLIST = new UIType("globalmaplist"); 1154 1155 /** 1156 * The <code>ADDREMOVELIST</code> attribute type specifies that the 1157 * multiple choice attribute should be display as add remove list 1158 * widget. 1159 */ 1160 public static final UIType ADDREMOVELIST = new UIType("addremovelist"); 1161 1162 /** 1163 * The <code>SCRIPTSELECT</code> attribute type specifies that the 1164 * attribute should be display as drop down widget. 1165 */ 1166 public static final UIType SCRIPTSELECT = new UIType("scriptSelect"); 1167 1168 /** 1169 * The <code>GLOBALSCRIPTSELECT</code> attribute type specifies that the 1170 * attribute should be display as drop down widget with only global scripts. 1171 */ 1172 public static final UIType GLOBALSCRIPTSELECT = new UIType("globalScriptSelect"); 1173 1174 private String attrType; 1175 1176 private UIType() { 1177 } 1178 1179 private UIType(String type) { 1180 attrType = type; 1181 } 1182 1183 /** 1184 * The method returns the string representation of the schema attribute 1185 * UI type. 1186 * 1187 * @return String string representation of schema attribute UI type 1188 */ 1189 public String toString() { 1190 return attrType; 1191 } 1192 1193 /** 1194 * Method to check if two schema attribute UI types are equal. 1195 * 1196 * @param schemaAttrType 1197 * the reference object with which to compare 1198 * 1199 * @return <code>true</code> if the objects are same; <code> 1200 * false</code> 1201 * otherwise 1202 */ 1203 public boolean equals(Object schemaAttrType) { 1204 if (schemaAttrType instanceof UIType) { 1205 UIType s = (UIType) schemaAttrType; 1206 return (s.attrType.equals(attrType)); 1207 } 1208 return (false); 1209 } 1210 1211 /** 1212 * Returns a hash code value for the object. 1213 * 1214 * @return a hash code value for the object 1215 */ 1216 public int hashCode() { 1217 return attrType.hashCode(); 1218 } 1219 } 1220 1221 /** 1222 * The class <code>Syntax</code> defines the syntax of the schema 1223 * attributes and provides static constants for these types. In other words, 1224 * this class defines the primitive data types for the schema attributes. 1225 */ 1226 public static class Syntax { 1227 1228 /** 1229 * The <code>BOOLEAN</code> attribute syntax specifies that the 1230 * attribute is of boolean type, i.e., can have a value of either 1231 * <code>true</code> or <code> 1232 * false</code> 1233 */ 1234 public static final Syntax BOOLEAN = new Syntax("boolean"); 1235 1236 /** 1237 * The <code>EMAIL</code> attribute syntax specifies that the 1238 * attribute is a email address. 1239 */ 1240 public static final Syntax EMAIL = new Syntax("email"); 1241 1242 /** 1243 * The <code>URL</code> attribute syntax specifies that the attribute 1244 * is a URL. 1245 */ 1246 public static final Syntax URL = new Syntax("url"); 1247 1248 /** 1249 * The <code>STRING</code> attribute syntax specifies that the 1250 * attribute is of text type, i.e., can have any unicode characters. 1251 */ 1252 public static final Syntax STRING = new Syntax("string"); 1253 1254 /** 1255 * The <code>PARAGRAPH</code> attribute syntax specifies that the 1256 * attribute is of multi-lined text type. 1257 */ 1258 public static final Syntax PARAGRAPH = new Syntax("paragraph"); 1259 1260 /** 1261 * The <code>XML</code> attribute syntax specifies that the attribute 1262 * is of XML type, i.e., can have any unicode characters. 1263 */ 1264 public static final Syntax XML = new Syntax("xml"); 1265 1266 /** 1267 * The <code>SCRIPT</code> attribute syntax specifies that the 1268 * attribute is of multi-lined text type and more specifically a script. 1269 */ 1270 public static final Syntax SCRIPT = new Syntax("script"); 1271 1272 /** 1273 * The <code>PASSWORD</code> attribute syntax specifies that the 1274 * attribute is of password type, will be used by UI to mask the 1275 * password typed. 1276 */ 1277 public static final Syntax PASSWORD = new Syntax("password"); 1278 1279 /** 1280 * The <code>ENCRYPTED PASSWORD</code> attribute syntax specifies that 1281 * the attribute is of password type, will be used by UI to mask the 1282 * password typed. 1283 */ 1284 public static final Syntax ENCRYPTED_PASSWORD = new Syntax( 1285 "encrypted_password"); 1286 1287 /** 1288 * The <code>DATE</code> attribute syntax specifies that the attribute 1289 * is of date type. 1290 */ 1291 public static final Syntax DATE = new Syntax("date"); 1292 1293 /** 1294 * The <code>NUMERIC</code> attribute syntax specifies that the 1295 * attribute is numeric, i.e., can have numbers only. 1296 */ 1297 public static final Syntax NUMERIC = new Syntax("numeric"); 1298 1299 /** 1300 * The <code>NUMBER</code> attribute syntax specifies that the 1301 * attribute is a number. 1302 */ 1303 public static final Syntax NUMBER = new Syntax("number"); 1304 1305 /** 1306 * The <code>DECIMAL</code> attribute syntax specifies that the 1307 * attribute is a decimal value. 1308 */ 1309 public static final Syntax DECIMAL = new Syntax("decimal"); 1310 1311 /** 1312 * The <code>PERCENT</code> attribute syntax specifies that the 1313 * attribute is a percentage. 1314 */ 1315 public static final Syntax PERCENT = new Syntax("percent"); 1316 1317 /** 1318 * The <code>NUMBER_RANGE</code> attribute syntax specifies that the 1319 * attribute is a number within a range. 1320 */ 1321 public static final Syntax NUMBER_RANGE = new Syntax("number_range"); 1322 1323 /** 1324 * The <code>DECIMAL_RANGE</code> attribute syntax specifies that the 1325 * attribute is a decimal number within a range. 1326 */ 1327 public static final Syntax DECIMAL_RANGE = new Syntax("decimal_range"); 1328 1329 /** 1330 * The <code>DECIMAL_NUMBER</code> attribute syntax specifies that the 1331 * attribute is a floating point number, e.g., 1.5, 3.56, etc. 1332 */ 1333 public static final Syntax DECIMAL_NUMBER = 1334 new Syntax("decimal_number"); 1335 1336 /** 1337 * The <code>DN</code> attribute syntax specifies that the attribute 1338 * should be an LDAP distinguished name (DN). 1339 */ 1340 public static final Syntax DN = new Syntax("dn"); 1341 1342 private String attrSyntax; 1343 1344 private Syntax() { 1345 } 1346 1347 private Syntax(String syntax) { 1348 attrSyntax = syntax; 1349 } 1350 1351 /** 1352 * The method returns the string representation of the schema attribute 1353 * syntax. 1354 * 1355 * @return String string representation of schema attribute syntax 1356 */ 1357 public String toString() { 1358 return (attrSyntax); 1359 } 1360 1361 /** 1362 * Method to check if two schema attribute syntax are equal. 1363 * 1364 * @param schemaAttrSyntax 1365 * the reference object with which to compare 1366 * 1367 * @return <code>true</code> if the objects are same; <code> 1368 * false</code> 1369 * otherwise 1370 */ 1371 public boolean equals(Object schemaAttrSyntax) { 1372 if (schemaAttrSyntax instanceof Syntax) { 1373 Syntax s = (Syntax) schemaAttrSyntax; 1374 return (s.attrSyntax.equals(attrSyntax)); 1375 } 1376 return (false); 1377 } 1378 1379 /** 1380 * Returns a hash code value for the object. 1381 * 1382 * @return a hash code value for the object 1383 */ 1384 public int hashCode() { 1385 return attrSyntax.hashCode(); 1386 } 1387 } 1388 1389 private static final String XML_PREFIX = 1390 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 1391 1392 private static final String DEFAULT_VALUES_BEGIN = "<" 1393 + SMSUtils.ATTRIBUTE_DEFAULT_ELEMENT + ">"; 1394 1395 private static final String DEFAULT_VALUES_END = "</" 1396 + SMSUtils.ATTRIBUTE_DEFAULT_ELEMENT + ">"; 1397 1398 static final String VALUE_BEGIN = "<" + SMSUtils.ATTRIBUTE_VALUE + ">"; 1399 1400 static final String VALUE_END = "</" + SMSUtils.ATTRIBUTE_VALUE + ">"; 1401 1402 private static final String CHOICE_VALUES_BEGIN = "<" 1403 + SMSUtils.ATTRIBUTE_CHOICE_VALUES_ELEMENT + ">"; 1404 1405 private static final String CHOICE_VALUES_END = "</" 1406 + SMSUtils.ATTRIBUTE_CHOICE_VALUES_ELEMENT + ">"; 1407 1408 private static final String CHOICE_VALUE_KEY = "<" 1409 + SMSUtils.ATTRIBUTE_CHOICE_VALUE_ELEMENT + " " + SMSUtils.I18N_KEY 1410 + "=\"{0}\">{1}</" + SMSUtils.ATTRIBUTE_CHOICE_VALUE_ELEMENT + ">"; 1411 1412 private static final String CHOICE_VALUE = "<" 1413 + SMSUtils.ATTRIBUTE_CHOICE_VALUE_ELEMENT + ">{0}</" 1414 + SMSUtils.ATTRIBUTE_CHOICE_VALUE_ELEMENT + ">"; 1415 1416 private static final String BOOLEAN_VALUES_BEGIN = 1417 "<" + SMSUtils.ATTRIBUTE_BOOLEAN_VALUES_ELEMENT + ">"; 1418 1419 private static final String BOOLEAN_VALUES_END = 1420 "</" + SMSUtils.ATTRIBUTE_BOOLEAN_VALUES_ELEMENT + ">"; 1421 1422 private static final String TRUE_BOOLEAN_KEY = 1423 "<" + SMSUtils.ATTRIBUTE_TRUE_BOOLEAN_ELEMENT + 1424 " " + SMSUtils.I18N_KEY + "=\"{0}\">{1}</" + 1425 SMSUtils.ATTRIBUTE_TRUE_BOOLEAN_ELEMENT + ">"; 1426 1427 private static final String FALSE_BOOLEAN_KEY = 1428 "<" + SMSUtils.ATTRIBUTE_FALSE_BOOLEAN_ELEMENT + 1429 " " + SMSUtils.I18N_KEY + "=\"{0}\">{1}</" + 1430 SMSUtils.ATTRIBUTE_FALSE_BOOLEAN_ELEMENT + ">"; 1431}