001    /*
002     * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.osgi.service.cm;
017    
018    import java.io.IOException;
019    import java.util.Dictionary;
020    
021    /**
022     * The configuration information for a <code>ManagedService</code> or
023     * <code>ManagedServiceFactory</code> object.
024     * 
025     * The Configuration Admin service uses this interface to represent the
026     * configuration information for a <code>ManagedService</code> or for a
027     * service instance of a <code>ManagedServiceFactory</code>.
028     * 
029     * <p>
030     * A <code>Configuration</code> object contains a configuration dictionary and
031     * allows the properties to be updated via this object. Bundles wishing to
032     * receive configuration dictionaries do not need to use this class - they
033     * register a <code>ManagedService</code> or
034     * <code>ManagedServiceFactory</code>. Only administrative bundles, and
035     * bundles wishing to update their own configurations need to use this class.
036     * 
037     * <p>
038     * The properties handled in this configuration have case insensitive
039     * <code>String</code> objects as keys. However, case is preserved from the
040     * last set key/value.
041     * <p>
042     * A configuration can be <i>bound </i> to a bundle location (
043     * <code>Bundle.getLocation()</code>). The purpose of binding a
044     * <code>Configuration</code> object to a location is to make it impossible
045     * for another bundle to forge a PID that would match this configuration. When a
046     * configuration is bound to a specific location, and a bundle with a different
047     * location registers a corresponding <code>ManagedService</code> object or
048     * <code>ManagedServiceFactory</code> object, then the configuration is not
049     * passed to the updated method of that object.
050     * 
051     * <p>
052     * If a configuration's location is <code>null</code>, it is not yet bound to
053     * a location. It will become bound to the location of the first bundle that
054     * registers a <code>ManagedService</code> or
055     * <code>ManagedServiceFactory</code> object with the corresponding PID.
056     * <p>
057     * The same <code>Configuration</code> object is used for configuring both a
058     * Managed Service Factory and a Managed Service. When it is important to
059     * differentiate between these two the term "factory configuration" is used.
060     * 
061     * @version $Revision: 5673 $
062     */
063    public interface Configuration {
064            /**
065             * Get the PID for this <code>Configuration</code> object.
066             * 
067             * @return the PID for this <code>Configuration</code> object.
068             * @throws IllegalStateException if this configuration has been deleted
069             */
070            public String getPid();
071    
072            /**
073             * Return the properties of this <code>Configuration</code> object.
074             * 
075             * The <code>Dictionary</code> object returned is a private copy for the
076             * caller and may be changed without influencing the stored configuration.
077             * The keys in the returned dictionary are case insensitive and are always
078             * of type <code>String</code>.
079             * 
080             * <p>
081             * If called just after the configuration is created and before update has
082             * been called, this method returns <code>null</code>.
083             * 
084             * @return A private copy of the properties for the caller or
085             *         <code>null</code>. These properties must not contain the
086             *         "service.bundleLocation" property. The value of this property may
087             *         be obtained from the <code>getBundleLocation</code> method.
088             * @throws IllegalStateException if this configuration has been deleted
089             */
090            public Dictionary getProperties();
091    
092            /**
093             * Update the properties of this <code>Configuration</code> object.
094             * 
095             * Stores the properties in persistent storage after adding or overwriting
096             * the following properties:
097             * <ul>
098             * <li>"service.pid" : is set to be the PID of this configuration.</li>
099             * <li>"service.factoryPid" : if this is a factory configuration it is set
100             * to the factory PID else it is not set.</li>
101             * </ul>
102             * These system properties are all of type <code>String</code>.
103             * 
104             * <p>
105             * If the corresponding Managed Service/Managed Service Factory is
106             * registered, its updated method must be called asynchronously. Else, this
107             * callback is delayed until aforementioned registration occurs.
108             * 
109             * <p>
110             * Also initiates an asynchronous call to all
111             * <code>ConfigurationListener</code>s with a
112             * <code>ConfigurationEvent.CM_UPDATED</code> event.
113             * 
114             * @param properties the new set of properties for this configuration
115             * @throws IOException if update cannot be made persistent
116             * @throws IllegalArgumentException if the <code>Dictionary</code> object
117             *         contains invalid configuration types or contains case variants of
118             *         the same key name.
119             * @throws IllegalStateException if this configuration has been deleted
120             */
121            public void update(Dictionary properties) throws IOException;
122    
123            /**
124             * Delete this <code>Configuration</code> object.
125             * 
126             * Removes this configuration object from the persistent store. Notify
127             * asynchronously the corresponding Managed Service or Managed Service
128             * Factory. A <code>ManagedService</code> object is notified by a call to
129             * its <code>updated</code> method with a <code>null</code> properties
130             * argument. A <code>ManagedServiceFactory</code> object is notified by a
131             * call to its <code>deleted</code> method.
132             * 
133             * <p>
134             * Also initiates an asynchronous call to all
135             * <code>ConfigurationListener</code>s with a
136             * <code>ConfigurationEvent.CM_DELETED</code> event.
137             * 
138             * @throws IOException If delete fails
139             * @throws IllegalStateException if this configuration has been deleted
140             */
141            public void delete() throws IOException;
142    
143            /**
144             * For a factory configuration return the PID of the corresponding Managed
145             * Service Factory, else return <code>null</code>.
146             * 
147             * @return factory PID or <code>null</code>
148             * @throws IllegalStateException if this configuration has been deleted
149             */
150            public String getFactoryPid();
151    
152            /**
153             * Update the <code>Configuration</code> object with the current
154             * properties.
155             * 
156             * Initiate the <code>updated</code> callback to the Managed Service or
157             * Managed Service Factory with the current properties asynchronously.
158             * 
159             * <p>
160             * This is the only way for a bundle that uses a Configuration Plugin
161             * service to initiate a callback. For example, when that bundle detects a
162             * change that requires an update of the Managed Service or Managed Service
163             * Factory via its <code>ConfigurationPlugin</code> object.
164             * 
165             * @see ConfigurationPlugin
166             * @throws IOException if update cannot access the properties in persistent
167             *         storage
168             * @throws IllegalStateException if this configuration has been deleted
169             */
170            public void update() throws IOException;
171    
172            /**
173             * Bind this <code>Configuration</code> object to the specified bundle
174             * location.
175             * 
176             * If the bundleLocation parameter is <code>null</code> then the
177             * <code>Configuration</code> object will not be bound to a location. It
178             * will be set to the bundle's location before the first time a Managed
179             * Service/Managed Service Factory receives this <code>Configuration</code>
180             * object via the updated method and before any plugins are called. The
181             * bundle location will be set persistently.
182             * 
183             * @param bundleLocation a bundle location or <code>null</code>
184             * @throws IllegalStateException If this configuration has been deleted.
185             * @throws SecurityException If the caller does not have
186             *         <code>ConfigurationPermission[*,CONFIGURE]</code>.
187             */
188            public void setBundleLocation(String bundleLocation);
189    
190            /**
191             * Get the bundle location.
192             * 
193             * Returns the bundle location to which this configuration is bound, or
194             * <code>null</code> if it is not yet bound to a bundle location.
195             * 
196             * @return location to which this configuration is bound, or
197             *         <code>null</code>.
198             * @throws IllegalStateException If this <code>Configuration</code> object
199             *         has been deleted.
200             * @throws SecurityException If the caller does not have
201             *         <code>ConfigurationPermission[*,CONFIGURE]</code>.
202             */
203            public String getBundleLocation();
204    
205            /**
206             * Equality is defined to have equal PIDs
207             * 
208             * Two Configuration objects are equal when their PIDs are equal.
209             * 
210             * @param other <code>Configuration</code> object to compare against
211             * @return <code>true</code> if equal, <code>false</code> if not a
212             *         <code>Configuration</code> object or one with a different PID.
213             */
214            public boolean equals(Object other);
215    
216            /**
217             * Hash code is based on PID.
218             * 
219             * The hashcode for two Configuration objects must be the same when the
220             * Configuration PID's are the same.
221             * 
222             * @return hash code for this Configuration object
223             */
224            public int hashCode();
225    }