blob: 63babbe09cd52d8558c3493f580fc3bb9bb66975 [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 Meschbergerf0c5a3d2011-11-04 10:47:58 +000074 configurationManager.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0})", new Object[]
75 { factoryPid } );
76
Carsten Ziegelereb80d512007-08-15 11:17:41 +000077 return this.wrap( configurationManager.createFactoryConfiguration( this, factoryPid ) );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000078 }
79
80
81 /* (non-Javadoc)
82 * @see org.osgi.service.cm.ConfigurationAdmin#createFactoryConfiguration(java.lang.String, java.lang.String)
83 */
84 public Configuration createFactoryConfiguration( String factoryPid, String location ) throws IOException
85 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +000086 configurationManager.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0}, location={1})",
87 new Object[]
88 { factoryPid, location } );
89
Felix Meschberger007c50e2011-10-20 12:39:38 +000090 // CM 1.4 / 104.13.2.3
91 this.checkPermission( location );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000092
Carsten Ziegelereb80d512007-08-15 11:17:41 +000093 return this.wrap( configurationManager.createFactoryConfiguration( factoryPid, location ) );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +000094 }
95
96
97 /* (non-Javadoc)
98 * @see org.osgi.service.cm.ConfigurationAdmin#getConfiguration(java.lang.String)
99 */
100 public Configuration getConfiguration( String pid ) throws IOException
101 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000102 configurationManager.log( LogService.LOG_DEBUG, "getConfiguration(pid={0})", new Object[]
103 { pid } );
104
Felix Meschberger2941ef92007-08-20 13:15:16 +0000105 ConfigurationImpl config = configurationManager.getConfiguration( pid, getBundle().getLocation() );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000106
Felix Meschbergerca3cd982009-08-19 19:27:58 +0000107 if ( config.getBundleLocation() == null )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000108 {
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000109 configurationManager.log( LogService.LOG_DEBUG, "Binding configuration {0} (isNew: {1}) to bundle {2}",
110 new Object[]
111 { config.getPid(), Boolean.valueOf( config.isNew() ), getBundle().getLocation() } );
112
Felix Meschbergeref470042009-08-19 05:52:41 +0000113 config.setStaticBundleLocation( this.getBundle().getLocation() );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000114 }
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000115 else if ( !config.getBundleLocation().equals( this.getBundle().getLocation() ) )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000116 {
Felix Meschberger007c50e2011-10-20 12:39:38 +0000117 // CM 1.4 / 104.13.2.3
118 this.checkPermission( config.getBundleLocation() );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000119 }
120
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000121 return this.wrap( config );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000122 }
123
124
125 /* (non-Javadoc)
126 * @see org.osgi.service.cm.ConfigurationAdmin#getConfiguration(java.lang.String, java.lang.String)
127 */
128 public Configuration getConfiguration( String pid, String location ) throws IOException
129 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000130 configurationManager.log( LogService.LOG_DEBUG, "getConfiguration(pid={0}, location={1})", new Object[]
131 { pid, location } );
132
Felix Meschberger007c50e2011-10-20 12:39:38 +0000133 // CM 1.4 / 104.13.2.3
134 this.checkPermission( location );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000135
Felix Meschberger007c50e2011-10-20 12:39:38 +0000136 ConfigurationImpl config = configurationManager.getConfiguration( pid, location );
137 if ( config.getBundleLocation() != null )
138 {
139 // CM 1.4 / 104.13.2.3
140 this.checkPermission( config.getBundleLocation() );
141 }
142
143 return this.wrap( config );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000144 }
145
146
147 /* (non-Javadoc)
148 * @see org.osgi.service.cm.ConfigurationAdmin#listConfigurations(java.lang.String)
149 */
150 public Configuration[] listConfigurations( String filter ) throws IOException, InvalidSyntaxException
151 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000152 configurationManager.log( LogService.LOG_DEBUG, "listConfigurations(filter={0})", new Object[]
153 { filter } );
154
Carsten Ziegelereb80d512007-08-15 11:17:41 +0000155 ConfigurationImpl ci[] = configurationManager.listConfigurations( this, filter );
Felix Meschberger0c4e7042008-08-06 07:41:48 +0000156 if ( ci == null || ci.length == 0 )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000157 {
158 return null;
159 }
160
161 Configuration[] cfgs = new Configuration[ci.length];
162 for ( int i = 0; i < cfgs.length; i++ )
163 {
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000164 cfgs[i] = this.wrap( ci[i] );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000165 }
166
167 return cfgs;
168 }
169
170
171 //---------- Security checks ----------------------------------------------
172
173 private Configuration wrap( ConfigurationImpl configuration )
174 {
175 return new ConfigurationAdapter( this, configuration );
176 }
177
178
179 /**
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000180 * Returns <code>true</code> if the current access control context (call
181 * stack) has the CONFIGURE permission.
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000182 */
Felix Meschberger007c50e2011-10-20 12:39:38 +0000183 boolean hasPermission(String name)
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000184 {
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000185 try
186 {
Felix Meschberger007c50e2011-10-20 12:39:38 +0000187 checkPermission(name);
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000188 return true;
189 }
190 catch ( SecurityException se )
191 {
192 return false;
193 }
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000194 }
195
196
197 /**
Felix Meschberger007c50e2011-10-20 12:39:38 +0000198 * Checks whether the current access control context (call stack) has
199 * the given permission for the given bundle location and throws a
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000200 * <code>SecurityException</code> if this is not the case.
Carsten Ziegeler6c6f25b2007-08-15 10:04:02 +0000201 *
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000202 * @param name The bundle location to check for permission. If this
203 * is <code>null</code> or exactly matches the using bundle's
204 * location, permission is always granted.
Felix Meschberger007c50e2011-10-20 12:39:38 +0000205 *
206 * @throws SecurityException if the access control context does not
207 * have the appropriate permission
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000208 */
Felix Meschberger007c50e2011-10-20 12:39:38 +0000209 void checkPermission( String name )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000210 {
Felix Meschberger35ab36a2009-08-27 20:11:12 +0000211 // the caller's permission must be checked
212 final SecurityManager sm = System.getSecurityManager();
213 if ( sm != null )
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000214 {
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000215 // CM 1.4 / 104.11.1 Implicit permission
216 if ( name != null && !name.equals( getBundle().getLocation() ) )
217 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000218 try
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000219 {
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000220 sm.checkPermission( new ConfigurationPermission( name, ConfigurationPermission.CONFIGURE ) );
221
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000222 configurationManager.log( LogService.LOG_DEBUG,
223 "Explicit Permission; grant CONFIGURE permission on configuration bound to {0} to bundle {1}",
224 new Object[]
225 { name, getBundle().getLocation() } );
226 }
Felix Meschbergerf0c5a3d2011-11-04 10:47:58 +0000227 catch ( SecurityException se )
228 {
229 configurationManager
230 .log(
231 LogService.LOG_DEBUG,
232 "No Permission; denied CONFIGURE permission on configuration bound to {0} to bundle {1}; reason: {2}",
233 new Object[]
234 { name, getBundle().getLocation(), se.getMessage() } );
235 throw se;
236 }
Felix Meschbergerfb833e72011-10-27 06:12:37 +0000237 }
238 else if ( configurationManager.isLogEnabled( LogService.LOG_DEBUG ) )
239 {
240 configurationManager.log( LogService.LOG_DEBUG,
241 "Implicit Permission; grant CONFIGURE permission on configuration bound to {0} to bundle {1}",
242 new Object[]
243 { name, getBundle().getLocation() } );
244
245 }
246 }
247 else if ( configurationManager.isLogEnabled( LogService.LOG_DEBUG ) )
248 {
249 configurationManager.log( LogService.LOG_DEBUG,
250 "No SecurityManager installed; grant CONFIGURE permission on configuration bound to {0} to bundle {1}",
251 new Object[]
252 { name, getBundle().getLocation() } );
Felix Meschbergeradd2b4a2007-04-11 18:12:33 +0000253 }
254 }
255
256}