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.util.Dictionary;
019    
020    /**
021     * Manage multiple service instances.
022     * 
023     * Bundles registering this interface are giving the Configuration Admin service
024     * the ability to create and configure a number of instances of a service that
025     * the implementing bundle can provide. For example, a bundle implementing a
026     * DHCP server could be instantiated multiple times for different interfaces
027     * using a factory.
028     * 
029     * <p>
030     * Each of these <i>service instances </i> is represented, in the persistent
031     * storage of the Configuration Admin service, by a factory
032     * <code>Configuration</code> object that has a PID. When such a
033     * <code>Configuration</code> is updated, the Configuration Admin service
034     * calls the <code>ManagedServiceFactory</code> updated method with the new
035     * properties. When <code>updated</code> is called with a new PID, the Managed
036     * Service Factory should create a new factory instance based on these
037     * configuration properties. When called with a PID that it has seen before, it
038     * should update that existing service instance with the new configuration
039     * information.
040     * 
041     * <p>
042     * In general it is expected that the implementation of this interface will
043     * maintain a data structure that maps PIDs to the factory instances that it has
044     * created. The semantics of a factory instance are defined by the Managed
045     * Service Factory. However, if the factory instance is registered as a service
046     * object with the service registry, its PID should match the PID of the
047     * corresponding <code>Configuration</code> object (but it should <b>not </b>
048     * be registered as a Managed Service!).
049     * 
050     * <p>
051     * An example that demonstrates the use of a factory. It will create serial
052     * ports under command of the Configuration Admin service.
053     * 
054     * <pre>
055     *  
056     *   class SerialPortFactory
057     *     implements ManagedServiceFactory {
058     *     ServiceRegistration registration;
059     *     Hashtable ports;
060     *     void start(BundleContext context) {
061     *       Hashtable properties = new Hashtable();
062     *       properties.put( Constants.SERVICE_PID,
063     *         &quot;com.acme.serialportfactory&quot; );
064     *       registration = context.registerService(
065     *         ManagedServiceFactory.class.getName(),
066     *         this,
067     *         properties
068     *       );
069     *     }
070     *     public void updated( String pid,
071     *       Dictionary properties  ) {
072     *       String portName = (String) properties.get(&quot;port&quot;);
073     *       SerialPortService port =
074     *         (SerialPort) ports.get( pid );
075     *       if ( port == null ) {
076     *         port = new SerialPortService();
077     *         ports.put( pid, port );
078     *         port.open();
079     *       }
080     *       if ( port.getPortName().equals(portName) )
081     *         return;
082     *       port.setPortName( portName );
083     *     }
084     *     public void deleted( String pid ) {
085     *       SerialPortService port =
086     *         (SerialPort) ports.get( pid );
087     *       port.close();
088     *       ports.remove( pid );
089     *     }
090     *     ...
091     *   }
092     *   
093     * </pre>
094     * 
095     * @version $Revision: 5673 $
096     */
097    public interface ManagedServiceFactory {
098            /**
099             * Return a descriptive name of this factory.
100             * 
101             * @return the name for the factory, which might be localized
102             */
103            public String getName();
104    
105            /**
106             * Create a new instance, or update the configuration of an existing
107             * instance.
108             * 
109             * If the PID of the <code>Configuration</code> object is new for the
110             * Managed Service Factory, then create a new factory instance, using the
111             * configuration <code>properties</code> provided. Else, update the
112             * service instance with the provided <code>properties</code>.
113             * 
114             * <p>
115             * If the factory instance is registered with the Framework, then the
116             * configuration <code>properties</code> should be copied to its registry
117             * properties. This is not mandatory and security sensitive properties
118             * should obviously not be copied.
119             * 
120             * <p>
121             * If this method throws any <code>Exception</code>, the Configuration
122             * Admin service must catch it and should log it.
123             * 
124             * <p>
125             * When the implementation of updated detects any kind of error in the
126             * configuration properties, it should create a new
127             * {@link ConfigurationException} which describes the problem.
128             * 
129             * <p>
130             * The Configuration Admin service must call this method asynchronously.
131             * This implies that implementors of the <code>ManagedServiceFactory</code>
132             * class can be assured that the callback will not take place during
133             * registration when they execute the registration in a synchronized method.
134             * 
135             * @param pid The PID for this configuration.
136             * @param properties A copy of the configuration properties. This argument
137             *        must not contain the service.bundleLocation" property. The value
138             *        of this property may be obtained from the
139             *        <code>Configuration.getBundleLocation</code> method.
140             * @throws ConfigurationException when the configuration properties are
141             *         invalid.
142             */
143            public void updated(String pid, Dictionary properties)
144                            throws ConfigurationException;
145    
146            /**
147             * Remove a factory instance.
148             * 
149             * Remove the factory instance associated with the PID. If the instance was
150             * registered with the service registry, it should be unregistered.
151             * <p>
152             * If this method throws any <code>Exception</code>, the Configuration
153             * Admin service must catch it and should log it.
154             * <p>
155             * The Configuration Admin service must call this method asynchronously.
156             * 
157             * @param pid the PID of the service to be removed
158             */
159            public void deleted(String pid);
160    }