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    import org.osgi.framework.InvalidSyntaxException;
022    
023    /**
024     * Service for administering configuration data.
025     * 
026     * <p>
027     * The main purpose of this interface is to store bundle configuration data
028     * persistently. This information is represented in <code>Configuration</code>
029     * objects. The actual configuration data is a <code>Dictionary</code> of
030     * properties inside a <code>Configuration</code> object.
031     * 
032     * <p>
033     * There are two principally different ways to manage configurations. First
034     * there is the concept of a Managed Service, where configuration data is
035     * uniquely associated with an object registered with the service registry.
036     * 
037     * <p>
038     * Next, there is the concept of a factory where the Configuration Admin service
039     * will maintain 0 or more <code>Configuration</code> objects for a Managed
040     * Service Factory that is registered with the Framework.
041     * 
042     * <p>
043     * The first concept is intended for configuration data about "things/services"
044     * whose existence is defined externally, e.g. a specific printer. Factories are
045     * intended for "things/services" that can be created any number of times, e.g.
046     * a configuration for a DHCP server for different networks.
047     * 
048     * <p>
049     * Bundles that require configuration should register a Managed Service or a
050     * Managed Service Factory in the service registry. A registration property
051     * named <code>service.pid</code> (persistent identifier or PID) must be used
052     * to identify this Managed Service or Managed Service Factory to the
053     * Configuration Admin service.
054     * 
055     * <p>
056     * When the ConfigurationAdmin detects the registration of a Managed Service, it
057     * checks its persistent storage for a configuration object whose PID matches
058     * the PID registration property (<code>service.pid</code>) of the Managed
059     * Service. If found, it calls {@link ManagedService#updated} method with the
060     * new properties. The implementation of a Configuration Admin service must run
061     * these call-backs asynchronously to allow proper synchronization.
062     * 
063     * <p>
064     * When the Configuration Admin service detects a Managed Service Factory
065     * registration, it checks its storage for configuration objects whose
066     * <code>factoryPid</code> matches the PID of the Managed Service Factory. For
067     * each such <code>Configuration</code> objects, it calls the
068     * <code>ManagedServiceFactory.updated</code> method asynchronously with the
069     * new properties. The calls to the <code>updated</code> method of a
070     * <code>ManagedServiceFactory</code> must be executed sequentially and not
071     * overlap in time.
072     * 
073     * <p>
074     * In general, bundles having permission to use the Configuration Admin service
075     * can only access and modify their own configuration information. Accessing or
076     * modifying the configuration of another bundle requires
077     * <code>ConfigurationPermission[*,CONFIGURE]</code>.
078     * 
079     * <p>
080     * <code>Configuration</code> objects can be <i>bound </i> to a specified
081     * bundle location. In this case, if a matching Managed Service or Managed
082     * Service Factory is registered by a bundle with a different location, then the
083     * Configuration Admin service must not do the normal callback, and it should
084     * log an error. In the case where a <code>Configuration</code> object is not
085     * bound, its location field is <code>null</code>, the Configuration Admin
086     * service will bind it to the location of the bundle that registers the first
087     * Managed Service or Managed Service Factory that has a corresponding PID
088     * property. When a <code>Configuration</code> object is bound to a bundle
089     * location in this manner, the Configuration Admin service must detect if the
090     * bundle corresponding to the location is uninstalled. If this occurs, the
091     * <code>Configuration</code> object is unbound, that is its location field is
092     * set back to <code>null</code>.
093     * 
094     * <p>
095     * The method descriptions of this class refer to a concept of "the calling
096     * bundle". This is a loose way of referring to the bundle which obtained the
097     * Configuration Admin service from the service registry. Implementations of
098     * <code>ConfigurationAdmin</code> must use a
099     * {@link org.osgi.framework.ServiceFactory} to support this concept.
100     * 
101     * @version $Revision: 5673 $
102     */
103    public interface ConfigurationAdmin {
104            /**
105             * Service property naming the Factory PID in the configuration dictionary.
106             * The property's value is of type <code>String</code>.
107             * 
108             * @since 1.1
109             */
110            public final static String      SERVICE_FACTORYPID              = "service.factoryPid";
111            /**
112             * Service property naming the location of the bundle that is associated
113             * with a a <code>Configuration</code> object. This property can be
114             * searched for but must not appear in the configuration dictionary for
115             * security reason. The property's value is of type <code>String</code>.
116             * 
117             * @since 1.1
118             */
119            public final static String      SERVICE_BUNDLELOCATION  = "service.bundleLocation";
120    
121            /**
122             * Create a new factory <code>Configuration</code> object with a new PID.
123             * 
124             * The properties of the new <code>Configuration</code> object are
125             * <code>null</code> until the first time that its
126             * {@link Configuration#update(Dictionary)} method is called.
127             * 
128             * <p>
129             * It is not required that the <code>factoryPid</code> maps to a
130             * registered Managed Service Factory.
131             * <p>
132             * The <code>Configuration</code> object is bound to the location of the
133             * calling bundle.
134             * 
135             * @param factoryPid PID of factory (not <code>null</code>).
136             * @return A new <code>Configuration</code> object.
137             * @throws IOException if access to persistent storage fails.
138             * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code> and <code>factoryPid</code> is bound to another bundle.
139             */
140            public Configuration createFactoryConfiguration(String factoryPid)
141                            throws IOException;
142    
143            /**
144             * Create a new factory <code>Configuration</code> object with a new PID.
145             * 
146             * The properties of the new <code>Configuration</code> object are
147             * <code>null</code> until the first time that its
148             * {@link Configuration#update(Dictionary)} method is called.
149             * 
150             * <p>
151             * It is not required that the <code>factoryPid</code> maps to a
152             * registered Managed Service Factory.
153             * 
154             * <p>
155             * The <code>Configuration</code> is bound to the location specified. If
156             * this location is <code>null</code> it will be bound to the location of
157             * the first bundle that registers a Managed Service Factory with a
158             * corresponding PID.
159             * 
160             * @param factoryPid PID of factory (not <code>null</code>).
161             * @param location A bundle location string, or <code>null</code>.
162             * @return a new <code>Configuration</code> object.
163             * @throws IOException if access to persistent storage fails.
164             * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
165             */
166            public Configuration createFactoryConfiguration(String factoryPid, String location)
167                            throws IOException;
168    
169            /**
170             * Get an existing <code>Configuration</code> object from the persistent
171             * store, or create a new <code>Configuration</code> object.
172             * 
173             * <p>
174             * If a <code>Configuration</code> with this PID already exists in
175             * Configuration Admin service return it. The location parameter is ignored
176             * in this case.
177             * 
178             * <p>
179             * Else, return a new <code>Configuration</code> object. This new object
180             * is bound to the location and the properties are set to <code>null</code>.
181             * If the location parameter is <code>null</code>, it will be set when a
182             * Managed Service with the corresponding PID is registered for the first
183             * time.
184             * 
185             * @param pid Persistent identifier.
186             * @param location The bundle location string, or <code>null</code>.
187             * @return An existing or new <code>Configuration</code> object.
188             * @throws IOException if access to persistent storage fails.
189             * @throws SecurityException if the caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
190             */
191            public Configuration getConfiguration(String pid, String location)
192                            throws IOException;
193    
194            /**
195             * Get an existing or new <code>Configuration</code> object from the
196             * persistent store.
197             * 
198             * If the <code>Configuration</code> object for this PID does not exist,
199             * create a new <code>Configuration</code> object for that PID, where
200             * properties are <code>null</code>. Bind its location to the calling
201             * bundle's location.
202             * 
203             * <p>
204             * Otherwise, if the location of the existing <code>Configuration</code> object
205             * is <code>null</code>, set it to the calling bundle's location.
206             * 
207             * @param pid persistent identifier.
208             * @return an existing or new <code>Configuration</code> matching the PID.
209             * @throws IOException if access to persistent storage fails.
210             * @throws SecurityException if the <code>Configuration</code> object is bound to a location different from that of the calling bundle and it has no <code>ConfigurationPermission[*,CONFIGURE]</code>.
211             */
212            public Configuration getConfiguration(String pid) throws IOException;
213    
214            /**
215             * List the current <code>Configuration</code> objects which match the
216             * filter.
217             * 
218             * <p>
219             * Only <code>Configuration</code> objects with non- <code>null</code>
220             * properties are considered current. That is,
221             * <code>Configuration.getProperties()</code> is guaranteed not to return
222             * <code>null</code> for each of the returned <code>Configuration</code>
223             * objects.
224             * 
225             * <p>
226             * Normally only <code>Configuration</code> objects that are bound to the
227             * location of the calling bundle are returned, or all if the caller has 
228             * <code>ConfigurationPermission[*,CONFIGURE]</code>.
229             * 
230             * <p>
231             * The syntax of the filter string is as defined in the {@link org.osgi.framework.Filter}
232             * class. The filter can test any configuration parameters including the
233             * following system properties:
234             * <ul>
235             * <li><code>service.pid</code>-<code>String</code>- the PID under
236             * which this is registered</li>
237             * <li><code>service.factoryPid</code>-<code>String</code>- the
238             * factory if applicable</li>
239             * <li><code>service.bundleLocation</code>-<code>String</code>- the
240             * bundle location</li>
241             * </ul>
242             * The filter can also be <code>null</code>, meaning that all
243             * <code>Configuration</code> objects should be returned.
244             * 
245             * @param filter A filter string, or <code>null</code> to
246             *        retrieve all <code>Configuration</code> objects.
247             * @return All matching <code>Configuration</code> objects, or
248             *         <code>null</code> if there aren't any.
249             * @throws IOException if access to persistent storage fails
250             * @throws InvalidSyntaxException if the filter string is invalid
251             */
252            public Configuration[] listConfigurations(String filter) throws IOException,
253                            InvalidSyntaxException;
254    }