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: ServiceConfig.java,v 1.18 2009/01/28 05:35:03 ww203982 Exp $ 026 * 027 * Portions Copyrighted 2011-2016 ForgeRock AS. 028 * Portions Copyrighted 2012 Open Source Solution Technology Corporation 029 */ 030package com.sun.identity.sm; 031 032import java.util.Collections; 033import java.util.HashSet; 034import java.util.Iterator; 035import java.util.Map; 036import java.util.Set; 037 038import org.forgerock.opendj.ldap.DN; 039 040import com.iplanet.services.util.AMEncryption; 041import com.iplanet.sso.SSOException; 042import com.iplanet.sso.SSOToken; 043import com.iplanet.ums.IUMSConstants; 044 045/** 046 * The class <code>ServiceConfig</code> provides interfaces to manage the 047 * configuration information of a service configuration. It provides methods to 048 * get and set configuration parameters for this service configuration. 049 * 050 * @supported.all.api 051 */ 052public class ServiceConfig { 053 // Instance variables 054 private SSOToken token; 055 056 private ServiceConfigImpl sc; 057 058 private ServiceSchemaImpl ss; 059 060 private ServiceConfigManager scm; 061 062 /** 063 * Default constructor. Makes it private so that it can not be instantiated. 064 */ 065 private ServiceConfig() { 066 // hence can not be instantiated 067 } 068 069 /** 070 * Protected constructor 071 */ 072 protected ServiceConfig(ServiceConfigManager scm, ServiceConfigImpl sc) 073 throws SMSException, SSOException { 074 this.scm = scm; 075 token = scm.getSSOToken(); 076 this.sc = sc; 077 this.ss = sc.getServiceSchemaImpl(); 078 } 079 080 /** 081 * Returns the name of this service configuration. 082 * 083 * @return the name of this service configuration 084 */ 085 public String getServiceName() { 086 return (scm.getName()); 087 } 088 089 /** 090 * Returns the service version 091 * 092 * @return service version 093 */ 094 public String getVersion() { 095 return (scm.getVersion()); 096 } 097 098 /** 099 * Returns the service component name. It is "/" separated and the root 100 * component name is "/". 101 * 102 * @return service component name 103 */ 104 public String getComponentName() { 105 validate(); 106 return (sc.getComponentName()); 107 } 108 109 /** 110 * Returns the service name. 111 * 112 * @return service name 113 */ 114 public String getName() { 115 validate(); 116 return sc.getName(); 117 } 118 119 /** 120 * Returns the service component's schema ID. For global and organization's 121 * root configurations it returns an empty string. 122 * 123 * @return service component's schema ID 124 */ 125 public String getSchemaID() { 126 validate(); 127 return (sc.getSchemaID()); 128 } 129 130 /** 131 * Returns the priority assigned to the service configuration. 132 * 133 * @return the priority assigned to the service configuration 134 */ 135 public int getPriority() { 136 validate(); 137 return (sc.getPriority()); 138 } 139 140 /** 141 * Sets the priority to the service configuration. 142 * 143 * @param priority 144 * the priority to be assigned to the configuration 145 * @throws SMSException 146 * if there is an error occurred while performing the operation 147 * @throws SSOException 148 * if the user's single sign-on is invalid or expired 149 */ 150 public void setPriority(int priority) throws SSOException, SMSException { 151 validateServiceConfigImpl(); 152 StringBuilder sb = new StringBuilder(8); 153 String[] priorities = { sb.append(priority).toString() }; 154 SMSEntry e = sc.getSMSEntry(); 155 e.setAttribute(SMSEntry.ATTR_PRIORITY, priorities); 156 saveSMSEntry(e); 157 } 158 159 /** 160 * Returns the labeled uri assigned to the service configuration. 161 * 162 * @return the labeled uri assigned to the service configuration 163 * @deprecated The labeledURI setting shall not be used for storing configuration data. 164 */ 165 public String getLabeledUri() { 166 validate(); 167 return (sc.getLabeledUri()); 168 } 169 170 /** 171 * Sets the labeled uri to the service configuration. 172 * 173 * @param luri the labeled uri to be assigned to the configuration 174 * @throws SMSException 175 * if there is an error occurred while performing the operation 176 * @throws SSOException 177 * if the user's single sign-on is invalid or expired 178 * @deprecated The labeledURI setting shall not be used for storing configuration data. 179 */ 180 public void setLabeledUri(String luri) throws SSOException, SMSException { 181 validateServiceConfigImpl(); 182 StringBuilder sb = new StringBuilder(8); 183 String[] lUris = { sb.append(luri).toString() }; 184 SMSEntry e = sc.getSMSEntry(); 185 e.setAttribute(SMSEntry.ATTR_LABELED_URI, lUris); 186 saveSMSEntry(e); 187 } 188 189 /** 190 * delete the labeled uri to the service configuration. 191 * 192 * @param luri the labeled uri to be assigned to the configuration 193 * @throws SMSException 194 * if there is an error occurred while performing the operation 195 * @throws SSOException 196 * if the user's single sign-on is invalid or expired 197 * @deprecated The labeledURI setting shall not be used for storing configuration data. 198 */ 199 public void deleteLabeledUri(String luri) throws SSOException, SMSException { 200 validateServiceConfigImpl(); 201 SMSEntry e = sc.getSMSEntry(); 202 sc.setLabeledUri(null); 203 e.removeAttribute(SMSEntry.ATTR_LABELED_URI, luri); 204 saveSMSEntry(e); 205 } 206 207 /** 208 * Returns the names of all service's sub-configurations. 209 * 210 * @return set of names of all service's sub-configurations 211 * @throws SMSException 212 * if there is an error accessing the data store 213 */ 214 public Set<String> getSubConfigNames() throws SMSException { 215 validateServiceConfigImpl(); 216 try { 217 return sc.getSubConfigNames(token); 218 } catch (SSOException s) { 219 SMSEntry.debug.error("ServiceConfig: Unable to " 220 + "get subConfig Names", s); 221 } 222 return (Collections.EMPTY_SET); 223 } 224 225 /** 226 * Method to get names of service's sub-configurations that match the given 227 * pattern. 228 * 229 * @param pattern 230 * pattern to match for sub-configuration names 231 * @return names of the service sub-configuration 232 * @throws SMSException 233 * if an error occurred while performing the operation. 234 */ 235 public Set<String> getSubConfigNames(String pattern) throws SMSException { 236 validateServiceConfigImpl(); 237 try { 238 return (sc.getSubConfigNames(token, pattern)); 239 } catch (SSOException s) { 240 SMSEntry.debug.error("ServiceConfigManager: Unable to " 241 + "get subConfig Names for filter: " + pattern, s); 242 } 243 return Collections.emptySet(); 244 245 } 246 247 /** 248 * Method to get names of service's sub-configurations that match the given 249 * pattern and belongs to the specified service schema name. 250 * 251 * @param pattern 252 * pattern to match for other entities. 253 * @param schemaName 254 * service schema name. 255 * @return names of the service sub-configuration 256 * @throws SMSException 257 * if an error occurred while performing the operation. 258 */ 259 public Set getSubConfigNames(String pattern, String schemaName) 260 throws SMSException { 261 validateServiceConfigImpl(); 262 try { 263 return (sc.getSubConfigNames(token, pattern, schemaName)); 264 } catch (SSOException s) { 265 SMSEntry.debug.error("ServiceConfigManager: Unable to " 266 + "get subConfig Names for filters: " + pattern + "AND" 267 + schemaName, s); 268 } 269 return (Collections.EMPTY_SET); 270 271 } 272 273 /** 274 * Returns a set of exported fully qualified sub-configuration names that 275 * can be imported used locally as service configuration 276 * 277 * @param serviceId 278 * service schema identifier 279 * @return names of fully qualified applicable service sub-configurations 280 * @throws SMSException 281 * if an error occurred while performing the operation. 282 */ 283 public Set getExportedSubConfigNames(String serviceId) throws SMSException { 284 return (null); 285 } 286 287 /** 288 * Returns the service's sub-configuration given the service's 289 * sub-configuration name. 290 * 291 * @param subConfigName 292 * The name of the service's sub-configuration to retrieve. 293 * @return The <code>ServiceConfig</code> object corresponding to the 294 * specified name of the service's sub-configuration. 295 * @throws SMSException 296 * if there is an error occurred while performing the operation 297 * @throws SSOException 298 * if the user's single sign-on is invalid or expired 299 */ 300 public ServiceConfig getSubConfig(String subConfigName) 301 throws SSOException, SMSException { 302 ServiceConfigImpl sci = sc.getSubConfig(token, subConfigName); 303 return ((sci == null) ? null : new ServiceConfig(scm, sci)); 304 } 305 306 /** 307 * Adds a service sub-configuration with configuration parameters. 308 * 309 * @param subConfigName 310 * the name of service sub-configuration to add 311 * @param subConfigId 312 * type of service sub-configuration 313 * @param priority 314 * the priority of the configuration 315 * @param attrs 316 * configuration parameters for the sub-configuration 317 * @throws SMSException 318 * if there is an error occurred while performing the operation 319 * @throws SSOException 320 * if the user's single sign-on is invalid or expired 321 */ 322 public void addSubConfig(String subConfigName, String subConfigId, 323 int priority, Map attrs) throws SMSException, SSOException { 324 validateServiceConfigImpl(); 325 // Check if this entry exists 326 if (sc.isNewEntry()) { 327 // Ideally these nodes should have been created, since they 328 // are not present we need to create them 329 scm.createOrganizationConfig(sc.getOrganizationName(), null); 330 // Check if rest of the component names are present 331 checkAndCreateComponents(sc.getDN()); 332 } 333 334 // Get service schemas 335 String subSchemaIdentifier = subConfigId == null ? subConfigName : subConfigId; 336 ServiceSchemaImpl nss = ss.getSubSchema(subSchemaIdentifier); 337 338 if (nss == null) { 339 String[] args = { subSchemaIdentifier }; 340 throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 341 "sms-invalid-add-sub-config-unknown-schema-name", args)); 342 } 343 344 if (!nss.supportsMultipleConfigurations() 345 && !getSubConfigNames().isEmpty()) { 346 String[] args = { subConfigName }; 347 throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 348 "sms-invalid-add-sub-config", args)); 349 } 350 351 // Convert priority to string 352 StringBuilder sb = new StringBuilder(8); 353 sb.append(priority); 354 355 // Create the entry 356 CreateServiceConfig.createSubConfigEntry(token, ("ou=" + subConfigName 357 + "," + sc.getDN()), nss, subConfigId, sb.toString(), 358 SMSUtils.copyAttributes(attrs), sc.getOrganizationName()); 359 } 360 361 /** 362 * Removes the service sub-configuration. 363 * 364 * @param subConfigName 365 * name of service sub-configuration to remove 366 * @throws SMSException 367 * if there is an error occurred while performing the operation 368 * @throws SSOException 369 * if the user's single sign-on is invalid or expired 370 */ 371 public void removeSubConfig(String subConfigName) throws SMSException, 372 SSOException { 373 validateServiceConfigImpl(); 374 // Obtain the SMSEntry for the subconfig and delete it 375 // unescape in case users provide such a subConfigName for deletion. 376 // "http:&#47;&#47;abc.east.sun.com:58080" 377 378 subConfigName = SMSSchema.unescapeName(subConfigName); 379 380 // First remove the entry from ServiceConfigImpl Cache. 381 382 // Construct subconfig DN 383 String sdn = "ou=" + subConfigName + "," + sc.getDN(); 384 385 // Construct ServiceConfigManagerImpl 386 ServiceConfigManagerImpl scmImpl = ServiceConfigManagerImpl. 387 getInstance(token, getServiceName(), getVersion()); 388 389 // Construct ServiceConfigImpl of the removed subconfig. 390 ServiceConfigImpl sConfigImpl = 391 sc.getSubConfig(token, subConfigName); 392 393 // Call ServiceConfigImpl's deleteInstance() to remove from cache. 394 if (sConfigImpl != null) { 395 ServiceConfigImpl.deleteInstance(token, scmImpl, null, sdn, "/", 396 sConfigImpl.getGroupName(), (getComponentName() + "/" 397 + SMSSchema.escapeSpecialCharacters(subConfigName)), false, 398 ss); 399 } 400 // Remove this entry from smsentry. 401 CachedSMSEntry cEntry = CachedSMSEntry.getInstance(token, sdn); 402 if (cEntry.isDirty()) { 403 cEntry.refresh(); 404 } 405 SMSEntry entry = cEntry.getClonedSMSEntry(); 406 entry.delete(token); 407 cEntry.refresh(entry); 408 409 // Remove the entry from CachedSubEntries 410 CachedSubEntries cse = CachedSubEntries.getInstance(token, sc.getDN()); 411 cse.remove(subConfigName); 412 } 413 414 /** 415 * Imports a service sub-configuration to the list of localy defined 416 * sub-configuration. The imported sub-configuration name must be fully 417 * qualified, as obtained from <code>getExportedSubConfigNames</code>. 418 * 419 * @param subConfigName 420 * the name of service sub-configuration to add locally 421 * @param exportedSubConfigName 422 * the fully qualified name of the exported sub-configuration 423 * name 424 * @throws SMSException 425 * if there is an error occurred while performing the operation 426 * @throws SSOException 427 * if the user's single sign-on is invalid or expired 428 */ 429 public void importSubConfig(String subConfigName, 430 String exportedSubConfigName) throws SMSException, SSOException { 431 } 432 433 /** 434 * Returns the service configuration parameters. The keys in the 435 * <code>Map</code> contains the attribute names and their corresponding 436 * values in the <code>Map</code> is a <code>Set</code> that contains 437 * the values for the attribute. This method picks up the default values for 438 * any attributes not defined in the <code>ServiceConfig</code>. The 439 * default values for these attributes are picked up from the Service 440 * Schema. If there is no default value defined, then this method will still 441 * return the attribute-value pair, except that the Set will be a 442 * Collections.EMPTY_SET. This is distinct from an empty Set with no entries 443 * in it. AN empty set represents an attribute whose value has been set to 444 * an empty value by the application using the <code>setAttributes()</code> 445 * method. 446 * 447 * @return the <code>Map</code> where key is the attribute name and value 448 * is the <code>Set</code> of attribute values 449 */ 450 public Map getAttributes() { 451 validate(); 452 return (sc.getAttributes()); 453 } 454 455 /** 456 * Returns the service configuration parameters for read only. 457 * The keys in the <code>Map</code> contains the attribute names and 458 * their corresponding values in the <code>Map</code> is a 459 * <code>Set</code> that contains the values for the attribute. 460 */ 461 462 /** 463 * Returns the service configuration parameters without inheriting the 464 * default values from service's schema. The keys in the <code>Map</code> 465 * contains the attribute names and their corresponding values in the 466 * <code>Map</code> is a <code>Set</code> that contains the values for 467 * the attribute. 468 */ 469 public Map getAttributesWithoutDefaults() { 470 validate(); 471 return (sc.getAttributesWithoutDefaults()); 472 } 473 474 /** 475 * Returns the service configuration parameters for read only, 476 * modification cannot be performed on the return <code>Map</code>. 477 * The keys in the 478 * <code>Map</code> contains the attribute names and their 479 * corresponding values in the <code>Map</code> is a 480 * <code>Set</code> that contains the values for the attribute. 481 * This method picks up the default values for any attributes 482 * not defined in the <code>ServiceConfig</code>. The default values for 483 * these attributes are picked up from the Service Schema. 484 * If there is no default value defined, then this method 485 * will still return the attribute-value pair, except that 486 * the Set will be a Collections.EMPTY_SET. 487 * This is distinct from an empty Set with no entries in it. 488 * AN empty set represents an attribute whose value has 489 * been set to an empty value by the application using 490 * the <code>setAttributes()</code> method. 491 * 492 * @return the <code>Map</code> where key is the attribute name 493 * and value is the <code>Set</code> of attribute values 494 */ 495 public Map getAttributesForRead() { 496 validate(); 497 return (sc.getAttributesForRead()); 498 } 499 500 /** 501 * Returns the service configuration parameters for read only without 502 * inheriting the default values from service's schema. The keys 503 * in the <code>Map</code> contains the attribute names and their 504 * corresponding values in the <code>Map</code> is a 505 * <code>Set</code> that contains the values for the attribute. 506 */ 507 public Map getAttributesWithoutDefaultsForRead() { 508 validate(); 509 return (sc.getAttributesWithoutDefaultsForRead()); 510 } 511 512 /** 513 * Sets the service configuration parameters. The keys in the 514 * <code>Map</code> contains the attribute names and their corresponding 515 * values in the <code>Map</code> is a <code>Set</code> that contains 516 * the values for the attribute. This method will replace the existing 517 * attribute values with the given one. For attributes that are not 518 * specified in <code>attrs</code>, it will not be modified. 519 * 520 * @param attrs 521 * the <code>Map</code> where key is the attribute name and 522 * value is the <code>Set</code> of attribute values 523 * @throws SMSException 524 * if there is an error occurred while performing the operation 525 * @throws SSOException 526 * if the user's single sign-on is invalid or expired 527 */ 528 public void setAttributes(Map attrs) throws SMSException, SSOException { 529 validateServiceConfigImpl(); 530 Map oldAttrs = sc.getAttributesWithoutDefaults(); 531 Iterator it = oldAttrs.keySet().iterator(); 532 Map newAttrs = SMSUtils.copyAttributes(attrs); 533 while (it.hasNext()) { 534 String s = (String) it.next(); 535 if (!newAttrs.containsKey(s)) { 536 newAttrs.put(s, oldAttrs.get(s)); 537 } 538 } 539 /* 540 * For validation using ChoiceValues plugin we need to pass in 541 * OrganizationName, since the plugins use organization names to compute 542 * the choice values 543 */ 544 ss.validateAttributes(token, newAttrs, true, sc.getOrganizationName()); 545 SMSEntry e = sc.getSMSEntry(); 546 SMSUtils.setAttributeValuePairs(e, newAttrs, ss 547 .getSearchableAttributeNames()); 548 saveSMSEntry(e); 549 } 550 551 /** 552 * Adds a configuration parameter to the service configuration. 553 * 554 * @param attrName 555 * the name of the attribute to add 556 * @param values 557 * the set of values to add 558 * @throws SMSException 559 * if there is an error occurred while performing the operation 560 * @throws SSOException 561 * if the user's single sign-on is invalid or expired 562 */ 563 public void addAttribute(String attrName, Set values) throws SMSException, 564 SSOException { 565 validateServiceConfigImpl(); 566 // Get current attributes 567 Map attributes = getAttributes(); 568 // Validate attribute values 569 Set newVals = values; 570 Set oldVals = (Set) attributes.get(attrName); 571 if (oldVals != null) { 572 newVals = new HashSet(); 573 newVals.addAll(values); 574 newVals.addAll(oldVals); 575 } 576 ss 577 .validateAttrValues(token, attrName, newVals, true, sc 578 .getOrganizationName()); 579 // Store the entry 580 SMSEntry e = sc.getSMSEntry(); 581 SMSUtils.addAttribute(e, attrName, values, ss 582 .getSearchableAttributeNames()); 583 saveSMSEntry(e); 584 } 585 586 /** 587 * Removes a configuration parameter from the service configuration. 588 * 589 * @param attrName 590 * the name of the attribute to remove 591 * @throws SMSException 592 * if there is an error occurred while performing the operation 593 * @throws SSOException 594 * if the user's single sign-on is invalid or expired 595 */ 596 public void removeAttribute(String attrName) throws SMSException, 597 SSOException { 598 validateServiceConfigImpl(); 599 SMSEntry e = sc.getSMSEntry(); 600 SMSUtils.removeAttribute(e, attrName); 601 saveSMSEntry(e); 602 } 603 604 /** 605 * Removes a configuration parameters from the service configuration. 606 * 607 * @param attrNames 608 * <code>Set</code> of attribute names to remove 609 * @throws SMSException 610 * if there is an error occurred while performing the operation 611 * @throws SSOException 612 * if the user's single sign-on is invalid or expired 613 */ 614 public void removeAttributes(Set attrNames) throws SMSException, 615 SSOException { 616 validateServiceConfigImpl(); 617 SMSEntry e = sc.getSMSEntry(); 618 if (attrNames != null && !attrNames.isEmpty()) { 619 for (Iterator items = attrNames.iterator(); items.hasNext();) { 620 SMSUtils.removeAttribute(e, (String) items.next()); 621 } 622 saveSMSEntry(e); 623 } 624 } 625 626 /** 627 * Removes the specific values for the given configuration parameter. 628 * 629 * @param attrName 630 * the name of the attribute 631 * @param values 632 * set of attribute values to remove from the given attribute 633 * @throws SMSException 634 * if there is an error occurred while performing the operation 635 * @throws SSOException 636 * if the user's single sign-on is invalid or expired 637 */ 638 public void removeAttributeValues(String attrName, Set values) 639 throws SMSException, SSOException { 640 validateServiceConfigImpl(); 641 SMSEntry e = sc.getSMSEntry(); 642 SMSUtils.removeAttributeValues(e, attrName, values, ss 643 .getSearchableAttributeNames()); 644 saveSMSEntry(e); 645 } 646 647 /** 648 * Replaces old value of the configuration parameter with new value. 649 * 650 * @param attrName 651 * the name of the attribute 652 * @param oldValue 653 * the old value to remove from the attribute 654 * @param newValue 655 * the new value to add to the attribute 656 * @throws SMSException 657 * if there is an error occurred while performing the operation 658 * @throws SSOException 659 * if the user's single sign-on is invalid or expired 660 */ 661 public void replaceAttributeValue(String attrName, String oldValue, 662 String newValue) throws SMSException, SSOException { 663 validateServiceConfigImpl(); 664 // Get current attributes 665 Map attributes = getAttributes(); 666 // Validate values 667 668 Set currentValues = (Set) attributes.get(attrName); 669 if (currentValues != null && !currentValues.contains(oldValue)) { 670 throw (new SMSException("Current value doesn't match supplied value", 671 "sms-INVALID_PARAMETERS")); 672 } 673 674 Set newVals = new HashSet(); 675 Set oldVals = (Set) attributes.get(attrName); 676 if (oldVals != null) { 677 newVals.addAll(oldVals); 678 newVals.remove(oldValue); 679 } 680 newVals.add(newValue); 681 ss 682 .validateAttrValues(token, attrName, newVals, true, sc 683 .getOrganizationName()); 684 // Store the entry 685 SMSEntry e = sc.getSMSEntry(); 686 SMSUtils.replaceAttributeValue(e, attrName, oldValue, newValue, ss 687 .getSearchableAttributeNames()); 688 saveSMSEntry(e); 689 } 690 691 /** 692 * Replaces the old values of the configuration parameter with the new 693 * values. 694 * 695 * @param attrName 696 * the name of the attribute 697 * @param oldValues 698 * the set of old values to remove from the attribute 699 * @param newValues 700 * the set of new values to add to the attribute 701 * @throws SMSException 702 * if there is an error occurred while performing the operation 703 * @throws SSOException 704 * if the user's single sign-on is invalid or expired 705 */ 706 public void replaceAttributeValues(String attrName, Set oldValues, 707 Set newValues) throws SMSException, SSOException { 708 validateServiceConfigImpl(); 709 // Get current attributes 710 Map attributes = getAttributes(); 711 // Validate values 712 Set newVals = new HashSet(); 713 Set oldVals = (Set) attributes.get(attrName); 714 if (oldVals != null) { 715 newVals.addAll(oldVals); 716 newVals.removeAll(oldValues); 717 } 718 newVals.addAll(newValues); 719 ss.validateAttrValues(token, attrName, newVals, true, 720 sc.getOrganizationName()); 721 // Store the entry 722 SMSEntry e = sc.getSMSEntry(); 723 SMSUtils.replaceAttributeValues(e, attrName, oldValues, newValues, ss 724 .getSearchableAttributeNames()); 725 saveSMSEntry(e); 726 } 727 728 /** 729 * Returns the LDAP DN represented by this <code>ServiceConfig</code> 730 * object. 731 * 732 * @return the LDAP DN represented by this <code>ServiceConfig</code> 733 * object. 734 */ 735 public String getDN() { 736 validate(); 737 return (sc.getDN()); 738 } 739 740 /** 741 * Returns the last modified time stamp of this configuration This method is 742 * expensive because it does not cache the modified time stamp but goes 743 * directly to the data store to obtain the value of this entry 744 * 745 * @return The last modified time stamp as a string with the format of 746 * <code> yyyyMMddhhmmss </code> 747 * @throws SMSException 748 * if there is an error trying to read from the data store 749 * @throws SSOException 750 * if the single sign-on token of the user is invalid. 751 */ 752 753 public String getLastModifiedTime() throws SMSException, SSOException { 754 validateServiceConfigImpl(); 755 SMSEntry e = sc.getSMSEntry(); 756 String vals[] = e.getAttributeValues(SMSEntry.ATTR_MODIFY_TIMESTAMP, 757 true); 758 String mTS = null; 759 if (vals != null) { 760 mTS = vals[0]; 761 } 762 return mTS; 763 } 764 765 /** 766 * Returns the organization names to which the service configuration is 767 * being exported. The organization names would be fully qualified starting 768 * with a forward slash "/". To specify an entire sub-tree that can use the 769 * service configuration, a "*" would have to be appended after the final 770 * forward slash. For example "/a/b/c/*" would imply all sub-organization 771 * under "/a/b/c" can use this service configuration. Exporting implies 772 * privileges to read the service configuration data, but not to modify or 773 * delete. 774 * 775 * @return names of organizations to which service configuration 776 * configuration is exported 777 */ 778 public Set getExportedOrganizationNames() { 779 return (null); 780 } 781 782 /** 783 * Sets the organization names that can import the service configuration. 784 * The organization names must be fully qualified, starting with a forward 785 * slash "/". To specify an entire sub-tree that can use the service 786 * configuration, a "*" would have to be appended after the final forward 787 * slash. For example "/a/b/c/*" would imply all sub-organization under 788 * "/a/b/c" can use this service configuration. Exporting implies privileges 789 * to read the service configuration data and not to modify or delete. 790 * 791 * @param names 792 * names of the organizations that can import the service 793 * configuration 794 */ 795 public void setExportedOrganizationNames(Set names) throws SMSException, 796 SSOException { 797 } 798 799 /** 800 * Adds the organization names to the list of organization names that can 801 * import this service configutation. If one does not exist it will be 802 * created. The organization names must be fully qualified, starting with a 803 * forward slash "/". To specify an entire sub-tree that can use the service 804 * configuration, a "*" would have to be appended after the final forward 805 * slash. For example "/a/b/c/*" would imply all sub-organization under 806 * "/a/b/c" can use this service configuration. Exporting implies privileges 807 * to read the service configuration data and not to modify or delete. 808 * 809 * @param names 810 * names of the organizations that can import the service 811 * configuration 812 */ 813 public void addExportedOrganizationNames(Set names) throws SMSException, 814 SSOException { 815 } 816 817 /** 818 * Removes the organization names from the list of organization names that 819 * can import the service configuration. If the organization has already 820 * imported the service configutation, it would have to be undone before the 821 * organization name can be removed from the list. The organization names 822 * must be fully qualified, starting with a forward slash "/". To specify an 823 * entire sub-tree that can use the service configuration, a "*" would have 824 * to be appended after the final forward slash. For example "/a/b/c/*" 825 * would imply all sub-organization under "/a/b/c" can use this service 826 * configuration. 827 * 828 * @param names 829 * names of the organizations that will be removed from the list 830 * of organization names that can import the service 831 * configutation 832 */ 833 public void removeSharedOrganizationNames(Set names) throws SMSException, 834 SSOException { 835 } 836 837 /** 838 * Returns String representation of the <code>ServiceConfig</code> object. 839 * It returns attributes defined and sub configurations. 840 * 841 * @return String representation of the <code>ServiceConfig</code> object. 842 */ 843 public String toString() { 844 StringBuilder sb = new StringBuilder(); 845 // Print the attributes 846 sb.append("Service Component name: " + getComponentName()); 847 sb.append("\n\tAttributes: " + getAttributes()).append("\n"); 848 849 // Try sub-configs 850 try { 851 Iterator subConfigNames = getSubConfigNames().iterator(); 852 while (subConfigNames.hasNext()) { 853 ServiceConfig ssc = getSubConfig((String)subConfigNames.next()); 854 sb.append(ssc); 855 } 856 } catch (Exception e) { 857 sb.append(e.getMessage()); 858 } 859 return (sb.toString()); 860 } 861 862 // Protected methods 863 void saveSMSEntry(SMSEntry e) throws SMSException, SSOException { 864 if (e.isNewEntry()) { 865 // Check if base nodes exists 866 CreateServiceConfig.checkBaseNodesForOrg(token, DNMapper 867 .orgNameToDN(sc.getOrganizationName()), getServiceName(), 868 getVersion()); 869 // Check if parent DN is present 870 String parentDN = DN.valueOf(e.getDN()).parent().toString(); 871 checkAndCreateComponents(parentDN); 872 // Add object classses to this entry 873 e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_TOP); 874 e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_SERVICE_COMP); 875 } 876 e.save(token); 877 sc.refresh(e); 878 } 879 880 public void checkAndCreateGroup(String dn, String groupName) 881 throws SMSException, SSOException { 882 883 CachedSMSEntry entry = CachedSMSEntry.getInstance(token, dn); 884 if (entry.isDirty()) { 885 entry.refresh(); 886 } 887 if (entry.isNewEntry()) { 888 // Check if parent exisits 889 String pDN = DN.valueOf(dn).parent().toString(); 890 CachedSMSEntry pEntry = CachedSMSEntry.getInstance(token, pDN); 891 if (pEntry.isDirty()) { 892 pEntry.refresh(); 893 } 894 if (pEntry.isNewEntry()) { 895 checkAndCreateComponents(pDN); 896 } 897 // Create this entry 898 SMSEntry e = entry.getClonedSMSEntry(); 899 e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_TOP); 900 e.addAttribute(SMSEntry.ATTR_OBJECTCLASS,SMSEntry.OC_SERVICE_COMP); 901 e.addAttribute(SMSEntry.ATTR_SERVICE_ID, groupName); 902 e.save(token); 903 entry.refresh(e); 904 } 905 } 906 907 void checkAndCreateComponents(String dn) throws SMSException, SSOException { 908 CachedSMSEntry entry = CachedSMSEntry.getInstance(token, dn); 909 if (entry.isDirty()) { 910 entry.refresh(); 911 } 912 if (entry.isNewEntry()) { 913 // Check if parent exisits 914 String pDN = DN.valueOf(dn).parent().toString(); 915 CachedSMSEntry pEntry = CachedSMSEntry.getInstance(token, pDN); 916 if (pEntry.isDirty()) { 917 pEntry.refresh(); 918 } 919 if (pEntry.isNewEntry()) { 920 checkAndCreateComponents(pDN); 921 } 922 // Create this entry 923 SMSEntry e = entry.getClonedSMSEntry(); 924 e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_TOP); 925 e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_SERVICE_COMP); 926 e.save(token); 927 entry.refresh(e); 928 } 929 } 930 931 private void validate() { 932 try { 933 validateServiceConfigImpl(); 934 } catch (SMSException e) { 935 // Ignore the exception 936 } 937 } 938 939 private void validateServiceConfigImpl() throws SMSException { 940 if (!sc.isValid()) { 941 throw (new SMSException("service-config: " + sc.getDN() + 942 " No longer valid. Cache has been cleared. Recreate from" + 943 "ServiceConfigManager")); 944 } 945 } 946 947 /** 948 * Returns the status of this Service Configuration Object. 949 * Must be used by classes that cache ServiceConfig. 950 * 951 * @return <code>true</code> if this object is still valid. 952 */ 953 public boolean isValid() { 954 return (sc.isValid()); 955 } 956 957 /** 958 * Returns <code>true</code> if the entry exist 959 */ 960 public boolean exists() { 961 return (!sc.isNewEntry()); 962 } 963 964 public String toXML(String NodeTag, AMEncryption encryptObj) 965 throws SMSException, SSOException { 966 validateServiceConfigImpl(); 967 return sc.toXML(token, NodeTag, encryptObj); 968 } 969 970 public String toXML(String NodeTag, AMEncryption encryptObj, String orgName) 971 throws SMSException, SSOException { 972 validateServiceConfigImpl(); 973 return sc.toXML(token, NodeTag, encryptObj, orgName); 974 } 975}