blob: 3385c3c99fc63ecbc44965c98bef0da8be9d79ce [file] [log] [blame]
Felix Meschbergeref470042009-08-19 05:52:41 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.cm.impl;
20
21
22import java.io.IOException;
23import java.util.Dictionary;
24import org.apache.felix.cm.PersistenceManager;
25import org.osgi.framework.ServiceReference;
26import org.osgi.service.cm.ConfigurationAdmin;
27import org.osgi.service.log.LogService;
28
29
30abstract class ConfigurationBase
31{
32
33 /**
34 * The {@link ConfigurationManager configuration manager} instance which
35 * caused this configuration object to be created.
36 */
37 private final ConfigurationManager configurationManager;
38
39 // the persistence manager storing this factory mapping
40 private final PersistenceManager persistenceManager;
41
42 // the basic ID of this instance
43 private final String baseId;
44
45 /**
46 * The statically bound bundle location, which is set explicitly by calling
47 * the Configuration.setBundleLocation(String) method.
48 */
49 private volatile String staticBundleLocation;
50
51 /**
52 * The bundle location from dynamic binding. This value is set as the
53 * configuration or factory is assigned to a ManagedService[Factory].
54 */
55 private volatile String dynamicBundleLocation;
56
57 /**
58 * The <code>ServiceReference</code> of the serviceReference which first
59 * asked for this instance. This field is <code>null</code> if the instance
60 * has not been handed to a serviceReference by way of the
61 * <code>ManagedService.update(Dictionary)</code> or
62 * <code>ManagedServiceFactory.updated(String, Dictionary)</code> method.
63 */
64 private volatile ServiceReference serviceReference;
65
66
67 protected ConfigurationBase( final ConfigurationManager configurationManager,
68 final PersistenceManager persistenceManager, final String baseId, final Dictionary props )
69 {
70 if ( configurationManager == null )
71 {
72 throw new IllegalArgumentException( "ConfigurationManager must not be null" );
73 }
74
75 if ( persistenceManager == null )
76 {
77 throw new IllegalArgumentException( "PersistenceManager must not be null" );
78 }
79
80 this.configurationManager = configurationManager;
81 this.persistenceManager = persistenceManager;
82 this.baseId = baseId;
83
84 // set bundle location from persistence and/or check for dynamic binding
85 if ( props != null )
86 {
87 this.staticBundleLocation = ( String ) props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION );
88 }
89
90 this.dynamicBundleLocation = configurationManager.getDynamicBundleLocation( baseId );
91 }
92
93
94 ConfigurationManager getConfigurationManager()
95 {
96 return configurationManager;
97 }
98
99
100 PersistenceManager getPersistenceManager()
101 {
102 return persistenceManager;
103 }
104
105
106 String getBaseId()
107 {
108 return baseId;
109 }
110
111
112 String getBundleLocation()
113 {
114 if ( dynamicBundleLocation != null )
115 {
116 return dynamicBundleLocation;
117 }
118
119 return staticBundleLocation;
120 }
121
122
123 String getDynamicBundleLocation()
124 {
125 return dynamicBundleLocation;
126 }
127
128
129 String getStaticBundleLocation()
130 {
131 return staticBundleLocation;
132 }
133
134
135 boolean isStaticallyBound()
136 {
137 // TODO: consider static location too ? to indicate whether we are
138 // actually bound ?
139 return dynamicBundleLocation == null;
140 }
141
142
143 void setServiceReference( ServiceReference serviceReference )
144 {
145 this.serviceReference = serviceReference;
146 }
147
148
149 ServiceReference getServiceReference()
150 {
151 return serviceReference;
152 }
153
154
155 void setStaticBundleLocation( final String bundleLocation )
156 {
157 // 104.15.2.8 The bundle location will be set persistently
158 this.staticBundleLocation = bundleLocation;
159 storeSilently();
160 }
161
162
163 void setDynamicBundleLocation( final String bundleLocation )
164 {
165 this.dynamicBundleLocation = bundleLocation;
166 this.configurationManager.setDynamicBundleLocation( this.getBaseId(), bundleLocation );
167 }
168
169
170 /**
171 * Tries to bind this configuration or factory to the given bundle location:
172 * <ul>
173 * <li>If already dynamically bound, <code>true</code> is returned if the
174 * dynamic binding equals the desired binding. Otherwise <code>false</code>
175 * is returned.</li>
176 * <li>If not dynamically bound but statically bound and the static binding
177 * is not equal to the desired binding, <code>false</code> is returned.</li>
178 * <li>Otherwise this configuration or factory is dynamically bound to the
179 * desired location and <code>true</code> is returned.</li>
180 * </ul>
181 *
182 * @param bundleLocation
183 * The desired bundle location to which this configuration or
184 * factory should be dynamically bound.
185 * @return <code>true</code> if this configuration or factory is dynamically
186 * bound to the desired location.
187 */
188 boolean tryBindLocation( final String bundleLocation )
189 {
190 if ( this.dynamicBundleLocation != null )
191 {
192 return this.dynamicBundleLocation.equals( bundleLocation );
193 }
194 else if ( this.staticBundleLocation != null && !this.staticBundleLocation.equals( bundleLocation ) )
195 {
196 return false;
197 }
198
199 setDynamicBundleLocation( bundleLocation );
200 return true;
201 }
202
203
204 abstract void store() throws IOException;
205
206
207 void storeSilently()
208 {
209 try
210 {
211 this.store();
212 }
213 catch ( IOException ioe )
214 {
215 configurationManager.log( LogService.LOG_ERROR, "Persisting new bundle location failed", ioe );
216 }
217 }
218
219
220 static protected void replaceProperty( Dictionary properties, String key, String value )
221 {
222 if ( value == null )
223 {
224 properties.remove( key );
225 }
226 else
227 {
228 properties.put( key, value );
229 }
230 }
231
232}