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