blob: bf3df93c62190f59f1ff4c0b5a9b54dd003c159e [file] [log] [blame]
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +00001/*
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +00002 * 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;
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000023import org.osgi.framework.Bundle;
24import org.osgi.framework.InvalidSyntaxException;
25import org.osgi.service.cm.Configuration;
26import org.osgi.service.cm.ConfigurationAdmin;
27import org.osgi.service.cm.ConfigurationPermission;
Felix Meschbergerfb833e72011-10-27 06:12:37 +000028import org.osgi.service.log.LogService;
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000029
30
31/**
32 * The <code>ConfigurationAdminImpl</code> is the per-bundle frontend to the
33 * configuration manager. Instances of this class are created on-demand for
34 * each bundle trying to get hold of the <code>ConfigurationAdmin</code>
35 * service.
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000036 */
37public class ConfigurationAdminImpl implements ConfigurationAdmin
38{
39
40 // The configuration manager to which most of the tasks are delegated
41 private ConfigurationManager configurationManager;
42
43 // The bundle for which this instance has been created
44 private Bundle bundle;
45
46
47 ConfigurationAdminImpl( ConfigurationManager configurationManager, Bundle bundle )
48 {
49 this.configurationManager = configurationManager;
50 this.bundle = bundle;
51 }
52
53
54 void dispose()
55 {
Carsten Ziegelereb80d512007-08-15 11:17:41 +000056 bundle = null;
57 configurationManager = null;
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000058 }
59
60
61 Bundle getBundle()
62 {
Carsten Ziegelereb80d512007-08-15 11:17:41 +000063 return bundle;
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000064 }
65
66
67 //---------- ConfigurationAdmin interface ---------------------------------
68
69 /* (non-Javadoc)
70 * @see org.osgi.service.cm.ConfigurationAdmin#createFactoryConfiguration(java.lang.String)
71 */
72 public Configuration createFactoryConfiguration( String factoryPid ) throws IOException
73 {
Felix Meschberger274aa242012-12-31 19:46:31 +000074 final ConfigurationManager configurationManager = getConfigurationManager();
75
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +000076 configurationManager.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0})", new Object[]
77 { factoryPid } );
78
Felix Meschbergerad949872011-11-16 10:34:54 +000079 ConfigurationImpl config = configurationManager.createFactoryConfiguration( factoryPid, this.getBundle()
80 .getLocation() );
81 return this.wrap( config );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000082 }
83
84
85 /* (non-Javadoc)
86 * @see org.osgi.service.cm.ConfigurationAdmin#createFactoryConfiguration(java.lang.String, java.lang.String)
87 */
88 public Configuration createFactoryConfiguration( String factoryPid, String location ) throws IOException
89 {
Felix Meschberger274aa242012-12-31 19:46:31 +000090 final ConfigurationManager configurationManager = getConfigurationManager();
91
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +000092 configurationManager.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0}, location={1})",
93 new Object[]
94 { factoryPid, location } );
95
Felix Meschberger007c50e2011-10-20 12:39:38 +000096 // CM 1.4 / 104.13.2.3
Felix Meschberger274aa242012-12-31 19:46:31 +000097 this.checkPermission( configurationManager, ( location == null ) ? "*" : location );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000098
Felix Meschbergerad949872011-11-16 10:34:54 +000099 ConfigurationImpl config = configurationManager.createFactoryConfiguration( factoryPid, location );
100 return this.wrap( config );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000101 }
102
103
104 /* (non-Javadoc)
105 * @see org.osgi.service.cm.ConfigurationAdmin#getConfiguration(java.lang.String)
106 */
107 public Configuration getConfiguration( String pid ) throws IOException
108 {
Felix Meschberger274aa242012-12-31 19:46:31 +0000109 final ConfigurationManager configurationManager = getConfigurationManager();
110
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000111 configurationManager.log( LogService.LOG_DEBUG, "getConfiguration(pid={0})", new Object[]
112 { pid } );
113
Felix Meschbergerad949872011-11-16 10:34:54 +0000114 ConfigurationImpl config = configurationManager.getConfiguration( pid );
115 if ( config == null )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000116 {
Felix Meschbergerad949872011-11-16 10:34:54 +0000117 config = configurationManager.createConfiguration( pid, getBundle().getLocation() );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000118 }
Felix Meschbergerad949872011-11-16 10:34:54 +0000119 else
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000120 {
Felix Meschbergerad949872011-11-16 10:34:54 +0000121 if ( config.getBundleLocation() == null )
122 {
123 configurationManager.log( LogService.LOG_DEBUG, "Binding configuration {0} (isNew: {1}) to bundle {2}",
124 new Object[]
Felix Meschberger4a48e252012-01-09 08:17:55 +0000125 { config.getPid(), config.isNew() ? Boolean.TRUE : Boolean.FALSE,
126 this.getBundle().getLocation() } );
Felix Meschbergerad949872011-11-16 10:34:54 +0000127
128 config.setStaticBundleLocation( this.getBundle().getLocation() );
129 }
130 else
131 {
132 // CM 1.4 / 104.13.2.3
Felix Meschberger274aa242012-12-31 19:46:31 +0000133 this.checkPermission( configurationManager, config.getBundleLocation() );
Felix Meschbergerad949872011-11-16 10:34:54 +0000134 }
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000135 }
136
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000137 return this.wrap( config );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000138 }
139
140
141 /* (non-Javadoc)
142 * @see org.osgi.service.cm.ConfigurationAdmin#getConfiguration(java.lang.String, java.lang.String)
143 */
144 public Configuration getConfiguration( String pid, String location ) throws IOException
145 {
Felix Meschberger274aa242012-12-31 19:46:31 +0000146 final ConfigurationManager configurationManager = getConfigurationManager();
147
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000148 configurationManager.log( LogService.LOG_DEBUG, "getConfiguration(pid={0}, location={1})", new Object[]
149 { pid, location } );
150
Felix Meschberger007c50e2011-10-20 12:39:38 +0000151 // CM 1.4 / 104.13.2.3
Felix Meschberger274aa242012-12-31 19:46:31 +0000152 this.checkPermission( configurationManager, ( location == null ) ? "*" : location );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000153
Felix Meschbergerad949872011-11-16 10:34:54 +0000154 ConfigurationImpl config = configurationManager.getConfiguration( pid );
155 if ( config == null )
Felix Meschberger007c50e2011-10-20 12:39:38 +0000156 {
Felix Meschbergerad949872011-11-16 10:34:54 +0000157 config = configurationManager.createConfiguration( pid, location );
158 }
159 else
160 {
161 final String configLocation = config.getBundleLocation();
Felix Meschberger274aa242012-12-31 19:46:31 +0000162 this.checkPermission( configurationManager, ( configLocation == null ) ? "*" : configLocation );
Felix Meschberger007c50e2011-10-20 12:39:38 +0000163 }
164
165 return this.wrap( config );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000166 }
167
168
169 /* (non-Javadoc)
170 * @see org.osgi.service.cm.ConfigurationAdmin#listConfigurations(java.lang.String)
171 */
172 public Configuration[] listConfigurations( String filter ) throws IOException, InvalidSyntaxException
173 {
Felix Meschberger274aa242012-12-31 19:46:31 +0000174 final ConfigurationManager configurationManager = getConfigurationManager();
175
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000176 configurationManager.log( LogService.LOG_DEBUG, "listConfigurations(filter={0})", new Object[]
177 { filter } );
178
Carsten Ziegelereb80d512007-08-15 11:17:41 +0000179 ConfigurationImpl ci[] = configurationManager.listConfigurations( this, filter );
Felix Meschberger0c4e7042008-08-06 07:41:48 +0000180 if ( ci == null || ci.length == 0 )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000181 {
182 return null;
183 }
184
185 Configuration[] cfgs = new Configuration[ci.length];
186 for ( int i = 0; i < cfgs.length; i++ )
187 {
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000188 cfgs[i] = this.wrap( ci[i] );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000189 }
190
191 return cfgs;
192 }
193
194
195 //---------- Security checks ----------------------------------------------
196
197 private Configuration wrap( ConfigurationImpl configuration )
198 {
199 return new ConfigurationAdapter( this, configuration );
200 }
201
202
203 /**
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000204 * Returns <code>true</code> if the current access control context (call
205 * stack) has the CONFIGURE permission.
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000206 */
Felix Meschberger274aa242012-12-31 19:46:31 +0000207 boolean hasPermission( final ConfigurationManager configurationManager, String name )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000208 {
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000209 try
210 {
Felix Meschberger274aa242012-12-31 19:46:31 +0000211 checkPermission(configurationManager, name);
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000212 return true;
213 }
214 catch ( SecurityException se )
215 {
216 return false;
217 }
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000218 }
219
220
221 /**
Felix Meschberger007c50e2011-10-20 12:39:38 +0000222 * Checks whether the current access control context (call stack) has
223 * the given permission for the given bundle location and throws a
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000224 * <code>SecurityException</code> if this is not the case.
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000225 *
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000226 * @param name The bundle location to check for permission. If this
227 * is <code>null</code> or exactly matches the using bundle's
228 * location, permission is always granted.
Felix Meschberger007c50e2011-10-20 12:39:38 +0000229 *
230 * @throws SecurityException if the access control context does not
231 * have the appropriate permission
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000232 */
Felix Meschberger274aa242012-12-31 19:46:31 +0000233 void checkPermission( final ConfigurationManager configurationManager, String name )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000234 {
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000235 // the caller's permission must be checked
236 final SecurityManager sm = System.getSecurityManager();
237 if ( sm != null )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000238 {
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000239 // CM 1.4 / 104.11.1 Implicit permission
240 if ( name != null && !name.equals( getBundle().getLocation() ) )
241 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000242 try
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000243 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000244 sm.checkPermission( new ConfigurationPermission( name, ConfigurationPermission.CONFIGURE ) );
245
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000246 configurationManager.log( LogService.LOG_DEBUG,
247 "Explicit Permission; grant CONFIGURE permission on configuration bound to {0} to bundle {1}",
248 new Object[]
249 { name, getBundle().getLocation() } );
250 }
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000251 catch ( SecurityException se )
252 {
253 configurationManager
254 .log(
255 LogService.LOG_DEBUG,
256 "No Permission; denied CONFIGURE permission on configuration bound to {0} to bundle {1}; reason: {2}",
257 new Object[]
258 { name, getBundle().getLocation(), se.getMessage() } );
259 throw se;
260 }
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000261 }
262 else if ( configurationManager.isLogEnabled( LogService.LOG_DEBUG ) )
263 {
264 configurationManager.log( LogService.LOG_DEBUG,
265 "Implicit Permission; grant CONFIGURE permission on configuration bound to {0} to bundle {1}",
266 new Object[]
267 { name, getBundle().getLocation() } );
268
269 }
270 }
271 else if ( configurationManager.isLogEnabled( LogService.LOG_DEBUG ) )
272 {
273 configurationManager.log( LogService.LOG_DEBUG,
274 "No SecurityManager installed; grant CONFIGURE permission on configuration bound to {0} to bundle {1}",
275 new Object[]
276 { name, getBundle().getLocation() } );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000277 }
278 }
279
Felix Meschberger274aa242012-12-31 19:46:31 +0000280
281 /**
282 * Returns the {@link ConfigurationManager} backing this configuraiton
283 * admin instance or throws {@code IllegalStateException} if already
284 * disposed off.
285 *
286 * @return The {@link ConfigurationManager} instance if still active
287 * @throws IllegalStateException if this instance has been
288 * {@linkplain #dispose() disposed off} already.
289 */
290 private ConfigurationManager getConfigurationManager()
291 {
292 if ( this.configurationManager == null )
293 {
294 throw new IllegalStateException( "Configuration Admin service has been unregistered" );
295 }
296
297 return this.configurationManager;
298 }
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000299}