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