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 * "com.acme.serialportfactory" );
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("port");
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 }