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-2014 ForgeRock AS
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.List;
043import java.util.Map;
044import java.util.Set;
045import com.sun.identity.shared.ldap.util.DN;
046
047/**
048 * The class <code>ServiceConfig</code> provides interfaces to manage the
049 * configuration information of a service configuration. It provides methods to
050 * get and set configuration parameters for this service configuration.
051 *
052 * @supported.all.api
053 */
054public class ServiceConfig {
055    // Instance variables
056    private SSOToken token;
057
058    private ServiceConfigImpl sc;
059
060    private ServiceSchemaImpl ss;
061
062    private ServiceConfigManager scm;
063
064    /**
065     * Default constructor. Makes it private so that it can not be instantiated.
066     */
067    private ServiceConfig() {
068        // hence can not be instantiated
069    }
070
071    /**
072     * Protected constructor
073     */
074    protected ServiceConfig(ServiceConfigManager scm, ServiceConfigImpl sc)
075            throws SMSException, SSOException {
076        this.scm = scm;
077        token = scm.getSSOToken();
078        this.sc = sc;
079        this.ss = sc.getServiceSchemaImpl();
080    }
081
082    /**
083     * Returns the name of this service configuration.
084     * 
085     * @return the name of this service configuration
086     */
087    public String getServiceName() {
088        return (scm.getName());
089    }
090
091    /**
092     * Returns the service version
093     * 
094     * @return service version
095     */
096    public String getVersion() {
097        return (scm.getVersion());
098    }
099
100    /**
101     * Returns the service component name. It is "/" separated and the root
102     * component name is "/".
103     * 
104     * @return service component name
105     */
106    public String getComponentName() {
107        validate();
108        return (sc.getComponentName());
109    }
110
111    /**
112     * Returns the service component's schema ID. For global and organization's
113     * root configurations it returns an empty string.
114     * 
115     * @return service component's schema ID
116     */
117    public String getSchemaID() {
118        validate();
119        return (sc.getSchemaID());
120    }
121
122    /**
123     * Returns the priority assigned to the service configuration.
124     * 
125     * @return the priority assigned to the service configuration
126     */
127    public int getPriority() {
128        validate();
129        return (sc.getPriority());
130    }
131
132    /**
133     * Sets the priority to the service configuration.
134     * 
135     * @param priority
136     *            the priority to be assigned to the configuration
137     * @throws SMSException
138     *             if there is an error occurred while performing the operation
139     * @throws SSOException
140     *             if the user's single sign-on is invalid or expired
141     */
142    public void setPriority(int priority) throws SSOException, SMSException {
143        validateServiceConfigImpl();
144        StringBuilder sb = new StringBuilder(8);
145        String[] priorities = { sb.append(priority).toString() };
146        SMSEntry e = sc.getSMSEntry();
147        e.setAttribute(SMSEntry.ATTR_PRIORITY, priorities);
148        saveSMSEntry(e);
149    }
150
151    /**
152     * Returns the labeled uri assigned to the service configuration.
153     * 
154     * @return the labeled uri assigned to the service configuration
155     */
156    public String getLabeledUri() {
157        validate();
158        return (sc.getLabeledUri());
159    }
160
161    /**
162     * Sets the labeled uri to the service configuration.
163     * 
164     * @param luri the labeled uri to be assigned to the configuration
165     * @throws SMSException
166     *             if there is an error occurred while performing the operation
167     * @throws SSOException
168     *             if the user's single sign-on is invalid or expired
169     */
170    public void setLabeledUri(String luri) throws SSOException, SMSException {
171        validateServiceConfigImpl();
172        StringBuilder sb = new StringBuilder(8);
173        String[] lUris = { sb.append(luri).toString() };
174        SMSEntry e = sc.getSMSEntry();
175        e.setAttribute(SMSEntry.ATTR_LABELED_URI, lUris);
176        saveSMSEntry(e);
177    }
178
179    /**
180     * delete the labeled uri to the service configuration.
181     * 
182     * @param luri the labeled uri to be assigned to the configuration
183     * @throws SMSException
184     *             if there is an error occurred while performing the operation
185     * @throws SSOException
186     *             if the user's single sign-on is invalid or expired
187     */
188    public void deleteLabeledUri(String luri) throws SSOException, SMSException {
189        validateServiceConfigImpl();
190        SMSEntry e = sc.getSMSEntry();
191        sc.setLabeledUri(null);
192        e.removeAttribute(SMSEntry.ATTR_LABELED_URI, luri);
193        saveSMSEntry(e);
194    }
195
196    /**
197     * Returns the names of all service's sub-configurations.
198     * 
199     * @return set of names of all service's sub-configurations
200     * @throws SMSException
201     *             if there is an error accessing the data store
202     */
203    public Set getSubConfigNames() throws SMSException {
204        validateServiceConfigImpl();
205        try {
206            return (sc.getSubConfigNames(token));
207        } catch (SSOException s) {
208            SMSEntry.debug.error("ServiceConfig: Unable to "
209                    + "get subConfig Names", s);
210        }
211        return (Collections.EMPTY_SET);
212    }
213
214    /**
215     * Method to get names of service's sub-configurations that match the given
216     * pattern.
217     * 
218     * @param pattern
219     *            pattern to match for sub-configuration names
220     * @return names of the service sub-configuration
221     * @throws SMSException
222     *             if an error occurred while performing the operation.
223     */
224    public Set getSubConfigNames(String pattern) throws SMSException {
225        validateServiceConfigImpl();
226        try {
227            return (sc.getSubConfigNames(token, pattern));
228        } catch (SSOException s) {
229            SMSEntry.debug.error("ServiceConfigManager: Unable to "
230                    + "get subConfig Names for filter: " + pattern, s);
231        }
232        return (Collections.EMPTY_SET);
233
234    }
235
236    /**
237     * Method to get names of service's sub-configurations that match the given
238     * pattern and belongs to the specified service schema name.
239     * 
240     * @param pattern
241     *            pattern to match for other entities.
242     * @param schemaName
243     *            service schema name.
244     * @return names of the service sub-configuration
245     * @throws SMSException
246     *             if an error occurred while performing the operation.
247     */
248    public Set getSubConfigNames(String pattern, String schemaName)
249            throws SMSException {
250        validateServiceConfigImpl();
251        try {
252            return (sc.getSubConfigNames(token, pattern, schemaName));
253        } catch (SSOException s) {
254            SMSEntry.debug.error("ServiceConfigManager: Unable to "
255                    + "get subConfig Names for filters: " + pattern + "AND"
256                    + schemaName, s);
257        }
258        return (Collections.EMPTY_SET);
259
260    }
261
262    /**
263     * Returns a set of exported fully qualified sub-configuration names that
264     * can be imported used locally as service configuration
265     * 
266     * @param serviceId
267     *            service schema identifier
268     * @return names of fully qualified applicable service sub-configurations
269     * @throws SMSException
270     *             if an error occurred while performing the operation.
271     */
272    public Set getExportedSubConfigNames(String serviceId) throws SMSException {
273        return (null);
274    }
275
276    /**
277     * Returns the service's sub-configuration given the service's
278     * sub-configuration name.
279     * 
280     * @param subConfigName
281     *            The name of the service's sub-configuration to retrieve.
282     * @return The <code>ServiceConfig</code> object corresponding to the
283     *         specified name of the service's sub-configuration.
284     * @throws SMSException
285     *             if there is an error occurred while performing the operation
286     * @throws SSOException
287     *             if the user's single sign-on is invalid or expired
288     */
289    public ServiceConfig getSubConfig(String subConfigName)
290            throws SSOException, SMSException {
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:&amp;#47;&amp;#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     * Retrieve a list of dynamic validators for a specific attribute from the {@link ServiceSchemaImpl}.
580     *
581     * @param attributeName The name of the attribute for which the validators were specified.
582     * @return A list of {@link DynamicAttributeValidator}s associated with the given attribute or
583     * an empty list if none were found.
584     * @throws SMSException If the validator class can not be instantiated.
585     * @throws InvalidAttributeNameException If the attribute is null or can not be found.
586     */
587    public List<DynamicAttributeValidator> getDynamicValidators(String attributeName) throws SMSException {
588        return ss.getDynamicPluginValidators(attributeName);
589    }
590
591    /**
592     * Removes a configuration parameter from the service configuration.
593     * 
594     * @param attrName
595     *            the name of the attribute to remove
596     * @throws SMSException
597     *             if there is an error occurred while performing the operation
598     * @throws SSOException
599     *             if the user's single sign-on is invalid or expired
600     */
601    public void removeAttribute(String attrName) throws SMSException,
602            SSOException {
603        validateServiceConfigImpl();
604        SMSEntry e = sc.getSMSEntry();
605        SMSUtils.removeAttribute(e, attrName);
606        saveSMSEntry(e);
607    }
608
609    /**
610     * Removes a configuration parameters from the service configuration.
611     * 
612     * @param attrNames
613     *            <code>Set</code> of attribute names to remove
614     * @throws SMSException
615     *             if there is an error occurred while performing the operation
616     * @throws SSOException
617     *             if the user's single sign-on is invalid or expired
618     */
619    public void removeAttributes(Set attrNames) throws SMSException,
620            SSOException {
621        validateServiceConfigImpl();
622        SMSEntry e = sc.getSMSEntry();
623        if (attrNames != null && !attrNames.isEmpty()) {
624            for (Iterator items = attrNames.iterator(); items.hasNext();) {
625                SMSUtils.removeAttribute(e, (String) items.next());
626            }
627            saveSMSEntry(e);
628        }
629    }
630
631    /**
632     * Removes the specific values for the given configuration parameter.
633     * 
634     * @param attrName
635     *            the name of the attribute
636     * @param values
637     *            set of attribute values to remove from the given attribute
638     * @throws SMSException
639     *             if there is an error occurred while performing the operation
640     * @throws SSOException
641     *             if the user's single sign-on is invalid or expired
642     */
643    public void removeAttributeValues(String attrName, Set values)
644            throws SMSException, SSOException {
645        validateServiceConfigImpl();
646        SMSEntry e = sc.getSMSEntry();
647        SMSUtils.removeAttributeValues(e, attrName, values, ss
648                .getSearchableAttributeNames());
649        saveSMSEntry(e);
650    }
651
652    /**
653     * Replaces old value of the configuration parameter with new value.
654     * 
655     * @param attrName
656     *            the name of the attribute
657     * @param oldValue
658     *            the old value to remove from the attribute
659     * @param newValue
660     *            the new value to add to the attribute
661     * @throws SMSException
662     *             if there is an error occurred while performing the operation
663     * @throws SSOException
664     *             if the user's single sign-on is invalid or expired
665     */
666    public void replaceAttributeValue(String attrName, String oldValue,
667            String newValue) throws SMSException, SSOException {
668        validateServiceConfigImpl();
669        // Get current attributes
670        Map attributes = getAttributes();
671        // Validate values
672
673        Set currentValues = (Set) attributes.get(attrName);
674        if (currentValues != null && !currentValues.contains(oldValue)) {
675            throw (new SMSException("Current value doesn't match supplied value",
676                    "sms-INVALID_PARAMETERS"));
677        }
678
679        Set newVals = new HashSet();
680        Set oldVals = (Set) attributes.get(attrName);
681        if (oldVals != null) {
682            newVals.addAll(oldVals);
683            newVals.remove(oldValue);
684        }
685        newVals.add(newValue);
686        ss
687                .validateAttrValues(token, attrName, newVals, true, sc
688                        .getOrganizationName());
689        // Store the entry
690        SMSEntry e = sc.getSMSEntry();
691        SMSUtils.replaceAttributeValue(e, attrName, oldValue, newValue, ss
692                .getSearchableAttributeNames());
693        saveSMSEntry(e);
694    }
695
696    /**
697     * Replaces the old values of the configuration parameter with the new
698     * values.
699     * 
700     * @param attrName
701     *            the name of the attribute
702     * @param oldValues
703     *            the set of old values to remove from the attribute
704     * @param newValues
705     *            the set of new values to add to the attribute
706     * @throws SMSException
707     *             if there is an error occurred while performing the operation
708     * @throws SSOException
709     *             if the user's single sign-on is invalid or expired
710     */
711    public void replaceAttributeValues(String attrName, Set oldValues,
712            Set newValues) throws SMSException, SSOException {
713        validateServiceConfigImpl();
714        // Get current attributes
715        Map attributes = getAttributes();
716        // Validate values
717        Set newVals = new HashSet();
718        Set oldVals = (Set) attributes.get(attrName);
719        if (oldVals != null) {
720            newVals.addAll(oldVals);
721            newVals.removeAll(oldValues);
722        }
723        newVals.addAll(newValues);
724        ss.validateAttrValues(token, attrName, newVals, true,
725            sc.getOrganizationName());
726        // Store the entry
727        SMSEntry e = sc.getSMSEntry();
728        SMSUtils.replaceAttributeValues(e, attrName, oldValues, newValues, ss
729                .getSearchableAttributeNames());
730        saveSMSEntry(e);
731    }
732
733    /**
734     * Returns the LDAP DN represented by this <code>ServiceConfig</code>
735     * object.
736     * 
737     * @return the LDAP DN represented by this <code>ServiceConfig</code>
738     *         object.
739     */
740    public String getDN() {
741        validate();
742        return (sc.getDN());
743    }
744
745    /**
746     * Returns the last modified time stamp of this configuration This method is
747     * expensive because it does not cache the modified time stamp but goes
748     * directly to the data store to obtain the value of this entry
749     * 
750     * @return The last modified time stamp as a string with the format of
751     *         <code> yyyyMMddhhmmss </code>
752     * @throws SMSException
753     *             if there is an error trying to read from the data store
754     * @throws SSOException
755     *             if the single sign-on token of the user is invalid.
756     */
757
758    public String getLastModifiedTime() throws SMSException, SSOException {
759        validateServiceConfigImpl();
760        SMSEntry e = sc.getSMSEntry();
761        String vals[] = e.getAttributeValues(SMSEntry.ATTR_MODIFY_TIMESTAMP,
762                true);
763        String mTS = null;
764        if (vals != null) {
765            mTS = vals[0];
766        }
767        return mTS;
768    }
769
770    /**
771     * Returns the organization names to which the service configuration is
772     * being exported. The organization names would be fully qualified starting
773     * with a forward slash "/". To specify an entire sub-tree that can use the
774     * service configuration, a "*" would have to be appended after the final
775     * forward slash. For example "/a/b/c/*" would imply all sub-organization
776     * under "/a/b/c" can use this service configuration. Exporting implies
777     * privileges to read the service configuration data, but not to modify or
778     * delete.
779     * 
780     * @return names of organizations to which service configuration
781     *         configuration is exported
782     */
783    public Set getExportedOrganizationNames() {
784        return (null);
785    }
786
787    /**
788     * Sets the organization names that can import the service configuration.
789     * The organization names must be fully qualified, starting with a forward
790     * slash "/". To specify an entire sub-tree that can use the service
791     * configuration, a "*" would have to be appended after the final forward
792     * slash. For example "/a/b/c/*" would imply all sub-organization under
793     * "/a/b/c" can use this service configuration. Exporting implies privileges
794     * to read the service configuration data and not to modify or delete.
795     * 
796     * @param names
797     *            names of the organizations that can import the service
798     *            configuration
799     */
800    public void setExportedOrganizationNames(Set names) throws SMSException,
801            SSOException {
802    }
803
804    /**
805     * Adds the organization names to the list of organization names that can
806     * import this service configutation. If one does not exist it will be
807     * created. The organization names must be fully qualified, starting with a
808     * forward slash "/". To specify an entire sub-tree that can use the service
809     * configuration, a "*" would have to be appended after the final forward
810     * slash. For example "/a/b/c/*" would imply all sub-organization under
811     * "/a/b/c" can use this service configuration. Exporting implies privileges
812     * to read the service configuration data and not to modify or delete.
813     * 
814     * @param names
815     *            names of the organizations that can import the service
816     *            configuration
817     */
818    public void addExportedOrganizationNames(Set names) throws SMSException,
819            SSOException {
820    }
821
822    /**
823     * Removes the organization names from the list of organization names that
824     * can import the service configuration. If the organization has already
825     * imported the service configutation, it would have to be undone before the
826     * organization name can be removed from the list. The organization names
827     * must be fully qualified, starting with a forward slash "/". To specify an
828     * entire sub-tree that can use the service configuration, a "*" would have
829     * to be appended after the final forward slash. For example "/a/b/c/*"
830     * would imply all sub-organization under "/a/b/c" can use this service
831     * configuration.
832     * 
833     * @param names
834     *            names of the organizations that will be removed from the list
835     *            of organization names that can import the service
836     *            configutation
837     */
838    public void removeSharedOrganizationNames(Set names) throws SMSException,
839            SSOException {
840    }
841
842    /**
843     * Returns String representation of the <code>ServiceConfig</code> object.
844     * It returns attributes defined and sub configurations.
845     * 
846     * @return String representation of the <code>ServiceConfig</code> object.
847     */
848    public String toString() {
849        StringBuilder sb = new StringBuilder();
850        // Print the attributes
851        sb.append("Service Component name: " + getComponentName());
852        sb.append("\n\tAttributes: " + getAttributes()).append("\n");
853
854        // Try sub-configs
855        try {
856            Iterator subConfigNames = getSubConfigNames().iterator();
857            while (subConfigNames.hasNext()) {
858                ServiceConfig ssc = getSubConfig((String)subConfigNames.next());
859                sb.append(ssc);
860            }
861        } catch (Exception e) {
862            sb.append(e.getMessage());
863        }
864        return (sb.toString());
865    }
866
867    // Protected methods
868    void saveSMSEntry(SMSEntry e) throws SMSException, SSOException {
869        if (e.isNewEntry()) {
870            // Check if base nodes exists
871            CreateServiceConfig.checkBaseNodesForOrg(token, DNMapper
872                    .orgNameToDN(sc.getOrganizationName()), getServiceName(),
873                    getVersion());
874            // Check if parent DN is present
875            String parentDN = (new DN(e.getDN())).getParent().toString();
876            checkAndCreateComponents(parentDN);
877            // Add object classses to this entry
878            e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_TOP);
879            e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_SERVICE_COMP);
880        }
881        e.save(token);
882        sc.refresh(e);
883    }
884
885    public void checkAndCreateGroup(String dn, String groupName) 
886        throws SMSException, SSOException {
887
888        CachedSMSEntry entry = CachedSMSEntry.getInstance(token, dn);
889        if (entry.isDirty()) {
890            entry.refresh();
891        }
892        if (entry.isNewEntry()) {
893            // Check if parent exisits
894            String pDN = (new DN(dn)).getParent().toString();
895            CachedSMSEntry pEntry = CachedSMSEntry.getInstance(token, pDN);
896            if (pEntry.isDirty()) {
897                pEntry.refresh();
898            }
899            if (pEntry.isNewEntry()) {
900                checkAndCreateComponents(pDN);
901            }
902            // Create this entry
903            SMSEntry e = entry.getClonedSMSEntry();
904            e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_TOP);
905            e.addAttribute(SMSEntry.ATTR_OBJECTCLASS,SMSEntry.OC_SERVICE_COMP);
906            e.addAttribute(SMSEntry.ATTR_SERVICE_ID, groupName);
907            e.save(token);
908            entry.refresh(e);
909        }
910    }
911
912    void checkAndCreateComponents(String dn) throws SMSException, SSOException {
913        CachedSMSEntry entry = CachedSMSEntry.getInstance(token, dn);
914        if (entry.isDirty()) {
915            entry.refresh();
916        }
917        if (entry.isNewEntry()) {
918            // Check if parent exisits
919            String pDN = (new DN(dn)).getParent().toString();
920            CachedSMSEntry pEntry = CachedSMSEntry.getInstance(token, pDN);
921            if (pEntry.isDirty()) {
922                pEntry.refresh();
923            }
924            if (pEntry.isNewEntry()) {
925                checkAndCreateComponents(pDN);
926            }
927            // Create this entry
928            SMSEntry e = entry.getClonedSMSEntry();
929            e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_TOP);
930            e.addAttribute(SMSEntry.ATTR_OBJECTCLASS, SMSEntry.OC_SERVICE_COMP);
931            e.save(token);
932            entry.refresh(e);
933        }
934    }
935    
936    private void validate() {
937        try {
938            validateServiceConfigImpl();
939        } catch (SMSException e) {
940            // Ignore the exception
941        }
942    }
943    
944    private void validateServiceConfigImpl() throws SMSException {
945        if (!sc.isValid()) {
946            throw (new SMSException("service-config: " + sc.getDN() +
947                " No loger valid. Cache has been cleared. Recreate from" +
948                "ServiceConfigManager"));
949        }
950    }
951    
952    /**
953     * Returns the status of this Service Configuration Object.
954     * Must be used by classes that cache ServiceConfig.
955     * 
956     * @return <code>true</code> if this object is still valid.
957     */
958    public boolean isValid() {
959        return (sc.isValid());
960    }
961    
962    /**
963     * Returns <code>true</code> if the entry exist
964     */
965    public boolean exists() {
966        return (!sc.isNewEntry());
967    }
968    
969    public String toXML(String NodeTag, AMEncryption encryptObj)
970        throws SMSException, SSOException {
971        validateServiceConfigImpl();
972        return sc.toXML(token, NodeTag, encryptObj);
973    }
974
975    public String toXML(String NodeTag, AMEncryption encryptObj, String orgName)
976        throws SMSException, SSOException {
977        validateServiceConfigImpl();
978        return sc.toXML(token, NodeTag, encryptObj, orgName);
979    }
980}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.