You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2013/04/04 11:43:37 UTC
svn commit: r1464402 [9/11] - in /ace/trunk: org.apache.ace.deployment.api/
org.apache.ace.deployment.deploymentadmin/ org.apache.ace.deployment.itest/
org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/
org.apache.ace.deployment.provider...
Added: ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/SecureAction.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/SecureAction.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/SecureAction.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/SecureAction.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,1676 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.security.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.zip.ZipFile;
+import org.osgi.framework.Bundle;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.hooks.resolver.ResolverHook;
+import org.osgi.framework.hooks.service.ListenerHook;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * <p>
+ * This is a utility class to centralize all action that should be performed
+ * in a <tt>doPrivileged()</tt> block. To perform a secure action, simply
+ * create an instance of this class and use the specific method to perform
+ * the desired action. When an instance is created, this class will capture
+ * the security context and will then use that context when checking for
+ * permission to perform the action. Instances of this class should not be
+ * passed around since they may grant the receiver a capability to perform
+ * privileged actions.
+ * </p>
+**/
+public class SecureAction
+{
+ private static final ThreadLocal m_actions = new ThreadLocal()
+ {
+ public Object initialValue()
+ {
+ return new Actions();
+ }
+ };
+
+ protected static transient int BUFSIZE = 4096;
+
+ private AccessControlContext m_acc = null;
+
+ public SecureAction()
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INITIALIZE_CONTEXT_ACTION, null);
+ m_acc = (AccessControlContext) AccessController.doPrivileged(actions);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ m_acc = AccessController.getContext();
+ }
+ }
+
+ public String getSystemProperty(String name, String def)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_PROPERTY_ACTION, name, def);
+ return (String) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return System.getProperty(name, def);
+ }
+ }
+
+ public ClassLoader getParentClassLoader(ClassLoader loader)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_PARENT_CLASS_LOADER_ACTION, loader);
+ return (ClassLoader) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return loader.getParent();
+ }
+ }
+
+ public ClassLoader getSystemClassLoader()
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_SYSTEM_CLASS_LOADER_ACTION);
+ return (ClassLoader) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return ClassLoader.getSystemClassLoader();
+ }
+ }
+
+ public ClassLoader getClassLoader(Class clazz)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_CLASS_LOADER_ACTION, clazz);
+ return (ClassLoader) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return clazz.getClassLoader();
+ }
+ }
+
+ public Class forName(String name) throws ClassNotFoundException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.FOR_NAME_ACTION, name);
+ return (Class) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof ClassNotFoundException)
+ {
+ throw (ClassNotFoundException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return Class.forName(name);
+ }
+ }
+
+ public URL createURL(String protocol, String host,
+ int port, String path, URLStreamHandler handler)
+ throws MalformedURLException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.CREATE_URL_ACTION, protocol, host,
+ new Integer(port), path, handler);
+ return (URL) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof MalformedURLException)
+ {
+ throw (MalformedURLException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return new URL(protocol, host, port, path, handler);
+ }
+ }
+
+ public URL createURL(URL context, String spec, URLStreamHandler handler)
+ throws MalformedURLException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.CREATE_URL_WITH_CONTEXT_ACTION, context,
+ spec, handler);
+ return (URL) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof MalformedURLException)
+ {
+ throw (MalformedURLException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return new URL(context, spec, handler);
+ }
+ }
+
+ public Process exec(String command) throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.EXEC_ACTION, command);
+ return (Process) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return Runtime.getRuntime().exec(command);
+ }
+ }
+
+ public String getAbsolutePath(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_ABSOLUTE_PATH_ACTION, file);
+ return (String) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.getAbsolutePath();
+ }
+ }
+
+ public boolean fileExists(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.FILE_EXISTS_ACTION, file);
+ return ((Boolean) AccessController.doPrivileged(actions, m_acc))
+ .booleanValue();
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.exists();
+ }
+ }
+
+ public boolean isFileDirectory(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.FILE_IS_DIRECTORY_ACTION, file);
+ return ((Boolean) AccessController.doPrivileged(actions, m_acc))
+ .booleanValue();
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.isDirectory();
+ }
+ }
+
+ public boolean mkdir(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.MAKE_DIRECTORY_ACTION, file);
+ return ((Boolean) AccessController.doPrivileged(actions, m_acc))
+ .booleanValue();
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.mkdir();
+ }
+ }
+
+ public boolean mkdirs(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.MAKE_DIRECTORIES_ACTION, file);
+ return ((Boolean) AccessController.doPrivileged(actions, m_acc))
+ .booleanValue();
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.mkdirs();
+ }
+ }
+
+ public File[] listDirectory(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.LIST_DIRECTORY_ACTION, file);
+ return (File[]) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.listFiles();
+ }
+ }
+
+ public boolean renameFile(File oldFile, File newFile)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.RENAME_FILE_ACTION, oldFile, newFile);
+ return ((Boolean) AccessController.doPrivileged(actions, m_acc))
+ .booleanValue();
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return oldFile.renameTo(newFile);
+ }
+ }
+
+ public FileInputStream getFileInputStream(File file) throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_FILE_INPUT_ACTION, file);
+ return (FileInputStream) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof IOException)
+ {
+ throw (IOException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return new FileInputStream(file);
+ }
+ }
+
+ public FileOutputStream getFileOutputStream(File file) throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_FILE_OUTPUT_ACTION, file);
+ return (FileOutputStream) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof IOException)
+ {
+ throw (IOException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return new FileOutputStream(file);
+ }
+ }
+
+ public URI toURI(File file)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.TO_URI_ACTION, file);
+ return (URI) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return file.toURI();
+ }
+ }
+
+ public InputStream getURLConnectionInputStream(URLConnection conn)
+ throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_URL_INPUT_ACTION, conn);
+ return (InputStream) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof IOException)
+ {
+ throw (IOException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return conn.getInputStream();
+ }
+ }
+
+ public boolean deleteFile(File target)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.DELETE_FILE_ACTION, target);
+ return ((Boolean) AccessController.doPrivileged(actions, m_acc))
+ .booleanValue();
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return target.delete();
+ }
+ }
+
+ public File createTempFile(String prefix, String suffix, File dir)
+ throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.CREATE_TMPFILE_ACTION, prefix, suffix, dir);
+ return (File) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof IOException)
+ {
+ throw (IOException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return File.createTempFile(prefix, suffix, dir);
+ }
+ }
+
+ public URLConnection openURLConnection(URL url) throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.OPEN_URLCONNECTION_ACTION, url);
+ return (URLConnection) AccessController.doPrivileged(actions,
+ m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof IOException)
+ {
+ throw (IOException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return url.openConnection();
+ }
+ }
+
+ public ZipFile openZipFile(File file) throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.OPEN_ZIPFILE_ACTION, file);
+ return (ZipFile) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ if (ex.getException() instanceof IOException)
+ {
+ throw (IOException) ex.getException();
+ }
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return new ZipFile(file);
+ }
+ }
+
+ public void startActivator(BundleActivator activator, BundleContext context)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.START_ACTIVATOR_ACTION, activator, context);
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw ex.getException();
+ }
+ }
+ else
+ {
+ activator.start(context);
+ }
+ }
+
+ public void stopActivator(BundleActivator activator, BundleContext context)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.STOP_ACTIVATOR_ACTION, activator, context);
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw ex.getException();
+ }
+ }
+ else
+ {
+ activator.stop(context);
+ }
+ }
+
+ public Policy getPolicy()
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_POLICY_ACTION, null);
+ return (Policy) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return Policy.getPolicy();
+ }
+ }
+
+ public void addURLToURLClassLoader(URL extension, ClassLoader loader) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.ADD_EXTENSION_URL_ACTION, extension, loader);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ Method addURL =
+ URLClassLoader.class.getDeclaredMethod("addURL",
+ new Class[] {URL.class});
+ addURL.setAccessible(true);
+ addURL.invoke(loader, new Object[]{extension});
+ }
+ }
+
+ public Constructor getConstructor(Class target, Class[] types) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_CONSTRUCTOR_ACTION, target, types);
+ try
+ {
+ return (Constructor) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return target.getConstructor(types);
+ }
+ }
+
+ public Constructor getDeclaredConstructor(Class target, Class[] types) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_DECLARED_CONSTRUCTOR_ACTION, target, types);
+ try
+ {
+ return (Constructor) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return target.getDeclaredConstructor(types);
+ }
+ }
+
+ public Method getMethod(Class target, String method, Class[] types) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_METHOD_ACTION, target, method, types);
+ try
+ {
+ return (Method) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return target.getMethod(method, types);
+ }
+ }
+
+ public Method getDeclaredMethod(Class target, String method, Class[] types) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_DECLARED_METHOD_ACTION, target, method, types);
+ try
+ {
+ return (Method) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return target.getDeclaredMethod(method, types);
+ }
+ }
+
+ public void setAccesssible(AccessibleObject ao)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.SET_ACCESSIBLE_ACTION, ao);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw (RuntimeException) e.getException();
+ }
+ }
+ else
+ {
+ ao.setAccessible(true);
+ }
+ }
+
+ public Object invoke(Method method, Object target, Object[] params) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_METHOD_ACTION, method, target, params);
+ try
+ {
+ return AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ method.setAccessible(true);
+ return method.invoke(target, params);
+ }
+ }
+
+ public Object invokeDirect(Method method, Object target, Object[] params) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_DIRECTMETHOD_ACTION, method, target, params);
+ try
+ {
+ return AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return method.invoke(target, params);
+ }
+ }
+
+ public Object invoke(Constructor constructor, Object[] params) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_CONSTRUCTOR_ACTION, constructor, params);
+ try
+ {
+ return AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return constructor.newInstance(params);
+ }
+ }
+
+ public Object getDeclaredField(Class targetClass, String name, Object target)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.GET_FIELD_ACTION, targetClass, name, target);
+ try
+ {
+ return AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ Field field = targetClass.getDeclaredField(name);
+ field.setAccessible(true);
+
+ return field.get(target);
+ }
+ }
+
+ public Object swapStaticFieldIfNotClass(Class targetClazz,
+ Class targetType, Class condition, String lockName) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.SWAP_FIELD_ACTION, targetClazz, targetType,
+ condition, lockName);
+ try
+ {
+ return AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return _swapStaticFieldIfNotClass(targetClazz, targetType,
+ condition, lockName);
+ }
+ }
+
+ private static Object _swapStaticFieldIfNotClass(Class targetClazz,
+ Class targetType, Class condition, String lockName) throws Exception
+ {
+ Object lock = null;
+ if (lockName != null)
+ {
+ try
+ {
+ Field lockField =
+ targetClazz.getDeclaredField(lockName);
+ lockField.setAccessible(true);
+ lock = lockField.get(null);
+ }
+ catch (NoSuchFieldException ex)
+ {
+ }
+ }
+ if (lock == null)
+ {
+ lock = targetClazz;
+ }
+ synchronized (lock)
+ {
+ Field[] fields = targetClazz.getDeclaredFields();
+
+ Object result = null;
+ for (int i = 0; (i < fields.length) && (result == null); i++)
+ {
+ if (Modifier.isStatic(fields[i].getModifiers()) &&
+ (fields[i].getType() == targetType))
+ {
+ fields[i].setAccessible(true);
+
+ result = fields[i].get(null);
+
+ if (result != null)
+ {
+ if ((condition == null) ||
+ !result.getClass().getName().equals(condition.getName()))
+ {
+ fields[i].set(null, null);
+ }
+ }
+ }
+ }
+ if (result != null)
+ {
+ if ((condition == null) || !result.getClass().getName().equals(condition.getName()))
+ {
+ // reset cache
+ for (int i = 0; i < fields.length; i++)
+ {
+ if (Modifier.isStatic(fields[i].getModifiers()) &&
+ (fields[i].getType() == Hashtable.class))
+ {
+ fields[i].setAccessible(true);
+ Hashtable cache = (Hashtable) fields[i].get(null);
+ if (cache != null)
+ {
+ cache.clear();
+ }
+ }
+ }
+ }
+ return result;
+ }
+ }
+ return null;
+ }
+
+ public void flush(Class targetClazz, Object lock) throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.FLUSH_FIELD_ACTION, targetClazz, lock);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ _flush(targetClazz, lock);
+ }
+ }
+
+ private static void _flush(Class targetClazz, Object lock) throws Exception
+ {
+ synchronized (lock)
+ {
+ Field[] fields = targetClazz.getDeclaredFields();
+ // reset cache
+ for (int i = 0; i < fields.length; i++)
+ {
+ if (Modifier.isStatic(fields[i].getModifiers()) &&
+ ((fields[i].getType() == Hashtable.class) || (fields[i].getType() == HashMap.class)))
+ {
+ fields[i].setAccessible(true);
+ if (fields[i].getType() == Hashtable.class)
+ {
+ Hashtable cache = (Hashtable) fields[i].get(null);
+ if (cache != null)
+ {
+ cache.clear();
+ }
+ }
+ else
+ {
+ HashMap cache = (HashMap) fields[i].get(null);
+ if (cache != null)
+ {
+ cache.clear();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* public void invokeBundleFindHook(
+ org.osgi.framework.hooks.bundle.FindHook fh,
+ BundleContext bc, Collection<Bundle> bundles)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_BUNDLE_FIND_HOOK, fh, bc, bundles);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ fh.find(bc, bundles);
+ }
+ }
+
+ public void invokeBundleEventHook(
+ org.osgi.framework.hooks.bundle.EventHook eh,
+ BundleEvent event, Collection<BundleContext> contexts)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_BUNDLE_EVENT_HOOK, eh, contexts);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ eh.event(event, contexts);
+ }
+ }
+
+ public void invokeWeavingHook(
+ org.osgi.framework.hooks.weaving.WeavingHook wh,
+ org.osgi.framework.hooks.weaving.WovenClass wc)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_WEAVING_HOOK, wh, wc);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ wh.weave(wc);
+ }
+ }
+
+ public void invokeServiceEventHook(
+ org.osgi.framework.hooks.service.EventHook eh,
+ ServiceEvent event, Collection<BundleContext> contexts)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_SERVICE_EVENT_HOOK, eh, contexts);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ eh.event(event, contexts);
+ }
+ }
+
+ public void invokeServiceFindHook(
+ org.osgi.framework.hooks.service.FindHook fh,
+ BundleContext context, String name, String filter,
+ boolean allServices, Collection<ServiceReference<?>> references)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(
+ Actions.INVOKE_SERVICE_EVENT_HOOK, fh, context, name, filter,
+ (allServices) ? Boolean.TRUE : Boolean.FALSE, references);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ fh.find(context, name, filter, allServices, references);
+ }
+ }
+
+ public void invokeServiceListenerHookAdded(
+ org.osgi.framework.hooks.service.ListenerHook lh,
+ Collection<ListenerHook.ListenerInfo> listeners)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_SERVICE_LISTENER_HOOK_ADDED, lh, listeners);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ lh.added(listeners);
+ }
+ }
+
+ public void invokeServiceListenerHookRemoved(
+ org.osgi.framework.hooks.service.ListenerHook lh,
+ Collection<ListenerHook.ListenerInfo> listeners)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_SERVICE_LISTENER_HOOK_REMOVED, lh, listeners);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ lh.removed(listeners);
+ }
+ }
+
+ public void invokeServiceEventListenerHook(
+ org.osgi.framework.hooks.service.EventListenerHook elh,
+ ServiceEvent event,
+ Map<BundleContext, Collection<ListenerHook.ListenerInfo>> listeners)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_SERVICE_EVENT_LISTENER_HOOK, elh, listeners);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ elh.event(event, listeners);
+ }
+ }
+
+ public ResolverHook invokeResolverHookFactory(
+ org.osgi.framework.hooks.resolver.ResolverHookFactory rhf,
+ Collection<BundleRevision> triggers)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_RESOLVER_HOOK_FACTORY, rhf, triggers);
+ try
+ {
+ return (ResolverHook) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ return rhf.begin(triggers);
+ }
+ }
+
+ public void invokeResolverHookResolvable(
+ org.osgi.framework.hooks.resolver.ResolverHook rh,
+ Collection<BundleRevision> candidates)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_RESOLVER_HOOK_RESOLVABLE, rh, candidates);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ rh.filterResolvable(candidates);
+ }
+ }
+
+ public void invokeResolverHookSingleton(
+ org.osgi.framework.hooks.resolver.ResolverHook rh,
+ BundleCapability singleton,
+ Collection<BundleCapability> collisions)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_RESOLVER_HOOK_SINGLETON, rh, singleton, collisions);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ rh.filterSingletonCollisions(singleton, collisions);
+ }
+ }
+
+ public void invokeResolverHookMatches(
+ org.osgi.framework.hooks.resolver.ResolverHook rh,
+ BundleRequirement req,
+ Collection<BundleCapability> candidates)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_RESOLVER_HOOK_MATCHES, rh, req, candidates);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ rh.filterMatches(req, candidates);
+ }
+ }
+
+ public void invokeResolverHookEnd(
+ org.osgi.framework.hooks.resolver.ResolverHook rh)
+ throws Exception
+ {
+ if (System.getSecurityManager() != null)
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.INVOKE_RESOLVER_HOOK_END, rh);
+ try
+ {
+ AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ }
+ else
+ {
+ rh.end();
+ }
+ }
+*/
+ private static class Actions implements PrivilegedExceptionAction
+ {
+ public static final int INITIALIZE_CONTEXT_ACTION = 0;
+ public static final int ADD_EXTENSION_URL_ACTION = 1;
+ public static final int CREATE_TMPFILE_ACTION = 2;
+ public static final int CREATE_URL_ACTION = 3;
+ public static final int CREATE_URL_WITH_CONTEXT_ACTION = 4;
+ public static final int DELETE_FILE_ACTION = 5;
+ public static final int EXEC_ACTION = 6;
+ public static final int FILE_EXISTS_ACTION = 7;
+ public static final int FILE_IS_DIRECTORY_ACTION = 8;
+ public static final int FOR_NAME_ACTION = 9;
+ public static final int GET_ABSOLUTE_PATH_ACTION = 10;
+ public static final int GET_CONSTRUCTOR_ACTION = 11;
+ public static final int GET_DECLARED_CONSTRUCTOR_ACTION = 12;
+ public static final int GET_DECLARED_METHOD_ACTION = 13;
+ public static final int GET_FIELD_ACTION = 14;
+ public static final int GET_FILE_INPUT_ACTION = 15;
+ public static final int GET_FILE_OUTPUT_ACTION = 16;
+ public static final int TO_URI_ACTION = 17;
+ public static final int GET_METHOD_ACTION = 18;
+ public static final int GET_POLICY_ACTION = 19;
+ public static final int GET_PROPERTY_ACTION = 20;
+ public static final int GET_PARENT_CLASS_LOADER_ACTION = 21;
+ public static final int GET_SYSTEM_CLASS_LOADER_ACTION = 22;
+ public static final int GET_URL_INPUT_ACTION = 23;
+ public static final int INVOKE_CONSTRUCTOR_ACTION = 24;
+ public static final int INVOKE_DIRECTMETHOD_ACTION = 25;
+ public static final int INVOKE_METHOD_ACTION = 26;
+ public static final int LIST_DIRECTORY_ACTION = 27;
+ public static final int MAKE_DIRECTORIES_ACTION = 28;
+ public static final int MAKE_DIRECTORY_ACTION = 29;
+ public static final int OPEN_ZIPFILE_ACTION = 30;
+ public static final int OPEN_URLCONNECTION_ACTION = 31;
+ public static final int RENAME_FILE_ACTION = 32;
+ public static final int SET_ACCESSIBLE_ACTION = 33;
+ public static final int START_ACTIVATOR_ACTION = 34;
+ public static final int STOP_ACTIVATOR_ACTION = 35;
+ public static final int SWAP_FIELD_ACTION = 36;
+ public static final int SYSTEM_EXIT_ACTION = 37;
+ public static final int FLUSH_FIELD_ACTION = 38;
+ public static final int GET_CLASS_LOADER_ACTION = 39;
+ public static final int INVOKE_BUNDLE_FIND_HOOK = 40;
+ public static final int INVOKE_BUNDLE_EVENT_HOOK = 41;
+ public static final int INVOKE_WEAVING_HOOK = 42;
+ public static final int INVOKE_SERVICE_EVENT_HOOK = 43;
+ public static final int INVOKE_SERVICE_FIND_HOOK = 44;
+ public static final int INVOKE_SERVICE_LISTENER_HOOK_ADDED = 45;
+ public static final int INVOKE_SERVICE_LISTENER_HOOK_REMOVED = 46;
+ public static final int INVOKE_SERVICE_EVENT_LISTENER_HOOK = 47;
+ public static final int INVOKE_RESOLVER_HOOK_FACTORY = 48;
+ public static final int INVOKE_RESOLVER_HOOK_RESOLVABLE = 49;
+ public static final int INVOKE_RESOLVER_HOOK_SINGLETON = 50;
+ public static final int INVOKE_RESOLVER_HOOK_MATCHES = 51;
+ public static final int INVOKE_RESOLVER_HOOK_END = 52;
+
+ private int m_action = -1;
+ private Object m_arg1 = null;
+ private Object m_arg2 = null;
+ private Object m_arg3 = null;
+ private Object m_arg4 = null;
+ private Object m_arg5 = null;
+ private Object m_arg6 = null;
+
+ public void set(int action)
+ {
+ m_action = action;
+ }
+
+ public void set(int action, Object arg1)
+ {
+ m_action = action;
+ m_arg1 = arg1;
+ }
+
+ public void set(int action, Object arg1, Object arg2)
+ {
+ m_action = action;
+ m_arg1 = arg1;
+ m_arg2 = arg2;
+ }
+
+ public void set(int action, Object arg1, Object arg2, Object arg3)
+ {
+ m_action = action;
+ m_arg1 = arg1;
+ m_arg2 = arg2;
+ m_arg3 = arg3;
+ }
+
+ public void set(int action, Object arg1, Object arg2, Object arg3,
+ Object arg4)
+ {
+ m_action = action;
+ m_arg1 = arg1;
+ m_arg2 = arg2;
+ m_arg3 = arg3;
+ m_arg4 = arg4;
+ }
+
+ public void set(int action, Object arg1, Object arg2, Object arg3,
+ Object arg4, Object arg5)
+ {
+ m_action = action;
+ m_arg1 = arg1;
+ m_arg2 = arg2;
+ m_arg3 = arg3;
+ m_arg4 = arg4;
+ m_arg5 = arg5;
+ }
+
+ public void set(int action, Object arg1, Object arg2, Object arg3,
+ Object arg4, Object arg5, Object arg6)
+ {
+ m_action = action;
+ m_arg1 = arg1;
+ m_arg2 = arg2;
+ m_arg3 = arg3;
+ m_arg4 = arg4;
+ m_arg5 = arg5;
+ m_arg6 = arg6;
+ }
+
+ private void unset()
+ {
+ m_action = -1;
+ m_arg1 = null;
+ m_arg2 = null;
+ m_arg3 = null;
+ m_arg4 = null;
+ m_arg5 = null;
+ m_arg6 = null;
+ }
+
+ public Object run() throws Exception
+ {
+ int action = m_action;
+ Object arg1 = m_arg1;
+ Object arg2 = m_arg2;
+ Object arg3 = m_arg3;
+ Object arg4 = m_arg4;
+ Object arg5 = m_arg5;
+ Object arg6 = m_arg6;
+
+ unset();
+
+ switch (action)
+ {
+ case INITIALIZE_CONTEXT_ACTION:
+ return AccessController.getContext();
+ case ADD_EXTENSION_URL_ACTION:
+ Method addURL =
+ URLClassLoader.class.getDeclaredMethod("addURL",
+ new Class[] {URL.class});
+ addURL.setAccessible(true);
+ addURL.invoke(arg2, new Object[]{arg1});
+ return null;
+ case CREATE_TMPFILE_ACTION:
+ return File.createTempFile((String) arg1, (String) arg2, (File) arg3);
+ case CREATE_URL_ACTION:
+ return new URL((String) arg1, (String) arg2,
+ ((Integer) arg3).intValue(), (String) arg4,
+ (URLStreamHandler) arg5);
+ case CREATE_URL_WITH_CONTEXT_ACTION:
+ return new URL((URL) arg1, (String) arg2, (URLStreamHandler) arg3);
+ case DELETE_FILE_ACTION:
+ return ((File) arg1).delete() ? Boolean.TRUE : Boolean.FALSE;
+ case EXEC_ACTION:
+ return Runtime.getRuntime().exec((String) arg1);
+ case FILE_EXISTS_ACTION:
+ return ((File) arg1).exists() ? Boolean.TRUE : Boolean.FALSE;
+ case FILE_IS_DIRECTORY_ACTION:
+ return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE;
+ case FOR_NAME_ACTION:
+ return Class.forName((String) arg1);
+ case GET_ABSOLUTE_PATH_ACTION:
+ return ((File) arg1).getAbsolutePath();
+ case GET_CONSTRUCTOR_ACTION:
+ return ((Class) arg1).getConstructor((Class[]) arg2);
+ case GET_DECLARED_CONSTRUCTOR_ACTION:
+ return ((Class) arg1).getDeclaredConstructor((Class[]) arg2);
+ case GET_DECLARED_METHOD_ACTION:
+ return ((Class) arg1).getDeclaredMethod((String) arg2, (Class[]) arg3);
+ case GET_FIELD_ACTION:
+ Field field = ((Class) arg1).getDeclaredField((String) arg2);
+ field.setAccessible(true);
+ return field.get(arg3);
+ case GET_FILE_INPUT_ACTION:
+ return new FileInputStream((File) arg1);
+ case GET_FILE_OUTPUT_ACTION:
+ return new FileOutputStream((File) arg1);
+ case TO_URI_ACTION:
+ return ((File) arg1).toURI();
+ case GET_METHOD_ACTION:
+ return ((Class) arg1).getMethod((String) arg2, (Class[]) arg3);
+ case GET_POLICY_ACTION:
+ return Policy.getPolicy();
+ case GET_PROPERTY_ACTION:
+ return System.getProperty((String) arg1, (String) arg2);
+ case GET_PARENT_CLASS_LOADER_ACTION:
+ return ((ClassLoader) arg1).getParent();
+ case GET_SYSTEM_CLASS_LOADER_ACTION:
+ return ClassLoader.getSystemClassLoader();
+ case GET_URL_INPUT_ACTION:
+ return ((URLConnection) arg1).getInputStream();
+ case INVOKE_CONSTRUCTOR_ACTION:
+ return ((Constructor) arg1).newInstance((Object[]) arg2);
+ case INVOKE_DIRECTMETHOD_ACTION:
+ return ((Method) arg1).invoke(arg2, (Object[]) arg3);
+ case INVOKE_METHOD_ACTION:
+ ((Method) arg1).setAccessible(true);
+ return ((Method) arg1).invoke(arg2, (Object[]) arg3);
+ case LIST_DIRECTORY_ACTION:
+ return ((File) arg1).listFiles();
+ case MAKE_DIRECTORIES_ACTION:
+ return ((File) arg1).mkdirs() ? Boolean.TRUE : Boolean.FALSE;
+ case MAKE_DIRECTORY_ACTION:
+ return ((File) arg1).mkdir() ? Boolean.TRUE : Boolean.FALSE;
+ case OPEN_ZIPFILE_ACTION:
+ return new ZipFile((File) arg1);
+ case OPEN_URLCONNECTION_ACTION:
+ return ((URL) arg1).openConnection();
+ case RENAME_FILE_ACTION:
+ return ((File) arg1).renameTo((File) arg2) ? Boolean.TRUE : Boolean.FALSE;
+ case SET_ACCESSIBLE_ACTION:
+ ((AccessibleObject) arg1).setAccessible(true);
+ return null;
+ case START_ACTIVATOR_ACTION:
+ ((BundleActivator) arg1).start((BundleContext) arg2);
+ return null;
+ case STOP_ACTIVATOR_ACTION:
+ ((BundleActivator) arg1).stop((BundleContext) arg2);
+ return null;
+ case SWAP_FIELD_ACTION:
+ return _swapStaticFieldIfNotClass((Class) arg1,
+ (Class) arg2, (Class) arg3, (String) arg4);
+ case SYSTEM_EXIT_ACTION:
+ System.exit(((Integer) arg1).intValue());
+ case FLUSH_FIELD_ACTION:
+ _flush(((Class) arg1), arg2);
+ return null;
+ case GET_CLASS_LOADER_ACTION:
+ return ((Class) arg1).getClassLoader();
+ /* case INVOKE_BUNDLE_FIND_HOOK:
+ ((org.osgi.framework.hooks.bundle.FindHook) arg1).find(
+ (BundleContext) arg2, (Collection<Bundle>) arg3);
+ return null;
+ case INVOKE_BUNDLE_EVENT_HOOK:
+ ((org.osgi.framework.hooks.bundle.EventHook) arg1).event(
+ (BundleEvent) arg2, (Collection<BundleContext>) arg3);
+ return null;
+ case INVOKE_WEAVING_HOOK:
+ ((org.osgi.framework.hooks.weaving.WeavingHook) arg1).weave(
+ (org.osgi.framework.hooks.weaving.WovenClass) arg2);
+ return null;
+ case INVOKE_SERVICE_EVENT_HOOK:
+ ((org.osgi.framework.hooks.service.EventHook) arg1).event(
+ (ServiceEvent) arg2, (Collection<BundleContext>) arg3);
+ return null;
+ case INVOKE_SERVICE_FIND_HOOK:
+ ((org.osgi.framework.hooks.service.FindHook) arg1).find(
+ (BundleContext) arg2, (String) arg3, (String) arg4,
+ ((Boolean) arg5).booleanValue(),
+ (Collection<ServiceReference<?>>) arg6);
+ return null;
+ case INVOKE_SERVICE_LISTENER_HOOK_ADDED:
+ ((org.osgi.framework.hooks.service.ListenerHook) arg1).added(
+ (Collection<ListenerHook.ListenerInfo>) arg2);
+ return null;
+ case INVOKE_SERVICE_LISTENER_HOOK_REMOVED:
+ ((org.osgi.framework.hooks.service.ListenerHook) arg1).removed(
+ (Collection<ListenerHook.ListenerInfo>) arg2);
+ return null;
+ case INVOKE_SERVICE_EVENT_LISTENER_HOOK:
+ ((org.osgi.framework.hooks.service.EventListenerHook) arg1).event(
+ (ServiceEvent) arg2,
+ (Map<BundleContext, Collection<ListenerHook.ListenerInfo>>) arg3);
+ return null;
+ case INVOKE_RESOLVER_HOOK_FACTORY:
+ return ((org.osgi.framework.hooks.resolver.ResolverHookFactory) arg1).begin(
+ (Collection<BundleRevision>) arg2);
+ case INVOKE_RESOLVER_HOOK_RESOLVABLE:
+ ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).filterResolvable(
+ (Collection<BundleRevision>) arg2);
+ return null;
+ case INVOKE_RESOLVER_HOOK_SINGLETON:
+ ((org.osgi.framework.hooks.resolver.ResolverHook) arg1)
+ .filterSingletonCollisions(
+ (BundleCapability) arg2,
+ (Collection<BundleCapability>) arg3);
+ return null;
+ case INVOKE_RESOLVER_HOOK_MATCHES:
+ ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).filterMatches(
+ (BundleRequirement) arg2,
+ (Collection<BundleCapability>) arg3);
+ return null;
+ case INVOKE_RESOLVER_HOOK_END:
+ ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).end();
+ return null;*/
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
Added: ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/StringComparator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/StringComparator.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/StringComparator.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/StringComparator.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util;
+
+import java.util.Comparator;
+
+public class StringComparator implements Comparator
+{
+ private final boolean m_isCaseSensitive;
+
+ public StringComparator(boolean b)
+ {
+ m_isCaseSensitive = b;
+ }
+
+ public int compare(Object o1, Object o2)
+ {
+ if (m_isCaseSensitive)
+ {
+ return o1.toString().compareTo(o2.toString());
+ }
+ else
+ {
+ return o1.toString().compareToIgnoreCase(o2.toString());
+ }
+ }
+
+ public boolean isCaseSensitive()
+ {
+ return m_isCaseSensitive;
+ }
+}
\ No newline at end of file
Added: ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/Util.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/Util.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/Util.java (added)
+++ ace/trunk/org.apache.ace.verifier/src/org/apache/felix/framework/util/Util.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,649 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util;
+
+import java.io.*;
+import java.net.URL;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class Util
+{
+ /**
+ * The default name used for the default configuration properties file.
+ **/
+ private static final String DEFAULT_PROPERTIES_FILE = "default.properties";
+
+ public static String getDefaultProperty(Logger logger, String name)
+ {
+ String value = null;
+
+ URL propURL = Util.class.getClassLoader().getResource(DEFAULT_PROPERTIES_FILE);
+ if (propURL != null)
+ {
+ InputStream is = null;
+ try
+ {
+ // Load properties from URL.
+ is = propURL.openConnection().getInputStream();
+ Properties props = new Properties();
+ props.load(is);
+ is.close();
+ // Perform variable substitution for property.
+ value = props.getProperty(name);
+ value = (value != null)
+ ? Util.substVars(value, name, null, props)
+ : null;
+ }
+ catch (Exception ex)
+ {
+ // Try to close input stream if we have one.
+ try
+ {
+ if (is != null) is.close();
+ }
+ catch (IOException ex2)
+ {
+ // Nothing we can do.
+ }
+
+ logger.log(
+ Logger.LOG_ERROR, "Unable to load any configuration properties.", ex);
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Converts a revision identifier to a bundle identifier. Revision IDs
+ * are typically <tt><bundle-id>.<revision></tt>; this
+ * method returns only the portion corresponding to the bundle ID.
+ **/
+ public static long getBundleIdFromRevisionId(String id)
+ {
+ try
+ {
+ String bundleId = (id.indexOf('.') >= 0)
+ ? id.substring(0, id.indexOf('.')) : id;
+ return Long.parseLong(bundleId);
+ }
+ catch (NumberFormatException ex)
+ {
+ return -1;
+ }
+ }
+
+ /**
+ * Converts a module identifier to a bundle identifier. Module IDs
+ * are typically <tt><bundle-id>.<revision></tt>; this
+ * method returns only the portion corresponding to the revision.
+ **/
+ public static int getModuleRevisionFromModuleId(String id)
+ {
+ try
+ {
+ int index = id.indexOf('.');
+ if (index >= 0)
+ {
+ return Integer.parseInt(id.substring(index + 1));
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ }
+ return -1;
+ }
+
+ public static String getClassName(String className)
+ {
+ if (className == null)
+ {
+ className = "";
+ }
+ return (className.lastIndexOf('.') < 0)
+ ? "" : className.substring(className.lastIndexOf('.') + 1);
+ }
+
+ public static String getClassPackage(String className)
+ {
+ if (className == null)
+ {
+ className = "";
+ }
+ return (className.lastIndexOf('.') < 0)
+ ? "" : className.substring(0, className.lastIndexOf('.'));
+ }
+
+ public static String getResourcePackage(String resource)
+ {
+ if (resource == null)
+ {
+ resource = "";
+ }
+ // NOTE: The package of a resource is tricky to determine since
+ // resources do not follow the same naming conventions as classes.
+ // This code is pessimistic and assumes that the package of a
+ // resource is everything up to the last '/' character. By making
+ // this choice, it will not be possible to load resources from
+ // imports using relative resource names. For example, if a
+ // bundle exports "foo" and an importer of "foo" tries to load
+ // "/foo/bar/myresource.txt", this will not be found in the exporter
+ // because the following algorithm assumes the package name is
+ // "foo.bar", not just "foo". This only affects imported resources,
+ // local resources will work as expected.
+ String pkgName = (resource.startsWith("/")) ? resource.substring(1) : resource;
+ pkgName = (pkgName.lastIndexOf('/') < 0)
+ ? "" : pkgName.substring(0, pkgName.lastIndexOf('/'));
+ pkgName = pkgName.replace('/', '.');
+ return pkgName;
+ }
+
+ /**
+ * <p>
+ * This is a simple utility class that attempts to load the named
+ * class using the class loader of the supplied class or
+ * the class loader of one of its super classes or their implemented
+ * interfaces. This is necessary during service registration to test
+ * whether a given service object implements its declared service
+ * interfaces.
+ * </p>
+ * <p>
+ * To perform this test, the framework must try to load
+ * the classes associated with the declared service interfaces, so
+ * it must choose a class loader. The class loader of the registering
+ * bundle cannot be used, since this disallows third parties to
+ * register service on behalf of another bundle. Consequently, the
+ * class loader of the service object must be used. However, this is
+ * also not sufficient since the class loader of the service object
+ * may not have direct access to the class in question.
+ * </p>
+ * <p>
+ * The service object's class loader may not have direct access to
+ * its service interface if it extends a super class from another
+ * bundle which implements the service interface from an imported
+ * bundle or if it implements an extension of the service interface
+ * from another bundle which imports the base interface from another
+ * bundle. In these cases, the service object's class loader only has
+ * access to the super class's class or the extended service interface,
+ * respectively, but not to the actual service interface.
+ * </p>
+ * <p>
+ * Thus, it is necessary to not only try to load the service interface
+ * class from the service object's class loader, but from the class
+ * loaders of any interfaces it implements and the class loaders of
+ * all super classes.
+ * </p>
+ * @param svcObj the class that is the root of the search.
+ * @param name the name of the class to load.
+ * @return the loaded class or <tt>null</tt> if it could not be
+ * loaded.
+ **/
+ public static Class loadClassUsingClass(Class clazz, String name, SecureAction action)
+ {
+ Class loadedClass = null;
+
+ while (clazz != null)
+ {
+ // Get the class loader of the current class object.
+ ClassLoader loader = action.getClassLoader(clazz);
+ // A null class loader represents the system class loader.
+ loader = (loader == null) ? action.getSystemClassLoader() : loader;
+ try
+ {
+ return loader.loadClass(name);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ // Ignore and try interface class loaders.
+ }
+
+ // Try to see if we can load the class from
+ // one of the class's implemented interface
+ // class loaders.
+ Class[] ifcs = clazz.getInterfaces();
+ for (int i = 0; i < ifcs.length; i++)
+ {
+ loadedClass = loadClassUsingClass(ifcs[i], name, action);
+ if (loadedClass != null)
+ {
+ return loadedClass;
+ }
+ }
+
+ // Try to see if we can load the class from
+ // the super class class loader.
+ clazz = clazz.getSuperclass();
+ }
+
+ return null;
+ }
+
+ /**
+ * This method determines if the requesting bundle is able to cast
+ * the specified service reference based on class visibility rules
+ * of the underlying modules.
+ * @param requester The bundle requesting the service.
+ * @param ref The service in question.
+ * @return <tt>true</tt> if the requesting bundle is able to case
+ * the service object to a known type.
+ **/
+ public static boolean isServiceAssignable(Bundle requester, ServiceReference ref)
+ {
+ // Boolean flag.
+ boolean allow = true;
+ // Get the service's objectClass property.
+ String[] objectClass = (String[]) ref.getProperty(FelixConstants.OBJECTCLASS);
+
+ // The the service reference is not assignable when the requesting
+ // bundle is wired to a different version of the service object.
+ // NOTE: We are pessimistic here, if any class in the service's
+ // objectClass is not usable by the requesting bundle, then we
+ // disallow the service reference.
+ for (int classIdx = 0; (allow) && (classIdx < objectClass.length); classIdx++)
+ {
+ if (!ref.isAssignableTo(requester, objectClass[classIdx]))
+ {
+ allow = false;
+ }
+ }
+ return allow;
+ }
+
+ public static BundleCapability getSatisfyingCapability(
+ BundleRevision br, BundleRequirementImpl req)
+ {
+ List<BundleCapability> caps = (br.getWiring() != null)
+ ? br.getWiring().getCapabilities(null)
+ : br.getDeclaredCapabilities(null);
+ if (caps != null)
+ {
+ for (BundleCapability cap : caps)
+ {
+ if (cap.getNamespace().equals(req.getNamespace())
+ && CapabilitySet.matches((BundleCapabilityImpl) cap, req.getFilter()))
+ {
+ return cap;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns all the capabilities from a module that has a specified namespace.
+ *
+ * @param br module providing capabilities
+ * @param namespace capability namespace
+ * @return array of matching capabilities or empty if none found
+ */
+ public static List<BundleCapability> getCapabilityByNamespace(
+ BundleRevision br, String namespace)
+ {
+ final List<BundleCapability> matching = new ArrayList();
+ final List<BundleCapability> caps = (br.getWiring() != null)
+ ? br.getWiring().getCapabilities(null)
+ : br.getDeclaredCapabilities(null);
+ if (caps != null)
+ {
+ for (BundleCapability cap : caps)
+ {
+ if (cap.getNamespace().equals(namespace))
+ {
+ matching.add(cap);
+ }
+ }
+ }
+ return matching;
+ }
+
+ public static List<BundleRequirement> getDynamicRequirements(
+ List<BundleRequirement> reqs)
+ {
+ List<BundleRequirement> result = new ArrayList<BundleRequirement>();
+ if (reqs != null)
+ {
+ for (BundleRequirement req : reqs)
+ {
+ String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+ if ((resolution != null) && resolution.equals("dynamic"))
+ {
+ result.add(req);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static BundleWire getWire(BundleRevision br, String name)
+ {
+ if (br.getWiring() != null)
+ {
+ List<BundleWire> wires = br.getWiring().getRequiredWires(null);
+ if (wires != null)
+ {
+ for (BundleWire w : wires)
+ {
+ if (w.getCapability().getNamespace()
+ .equals(BundleRevision.PACKAGE_NAMESPACE) &&
+ w.getCapability().getAttributes()
+ .get(BundleRevision.PACKAGE_NAMESPACE).equals(name))
+ {
+ return w;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private static final byte encTab[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
+ 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
+ 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f };
+
+ private static final byte decTab[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1,
+ -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1,
+ -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, -1, -1, -1, -1, -1 };
+
+ public static String base64Encode(String s) throws IOException
+ {
+ return encode(s.getBytes(), 0);
+ }
+
+ /**
+ * Encode a raw byte array to a Base64 String.
+ *
+ * @param in Byte array to encode.
+ * @param len Length of Base64 lines. 0 means no line breaks.
+ **/
+ public static String encode(byte[] in, int len) throws IOException
+ {
+ ByteArrayOutputStream baos = null;
+ ByteArrayInputStream bais = null;
+ try
+ {
+ baos = new ByteArrayOutputStream();
+ bais = new ByteArrayInputStream(in);
+ encode(bais, baos, len);
+ // ASCII byte array to String
+ return (new String(baos.toByteArray()));
+ }
+ finally
+ {
+ if (baos != null)
+ {
+ baos.close();
+ }
+ if (bais != null)
+ {
+ bais.close();
+ }
+ }
+ }
+
+ public static void encode(InputStream in, OutputStream out, int len)
+ throws IOException
+ {
+
+ // Check that length is a multiple of 4 bytes
+ if (len % 4 != 0)
+ {
+ throw new IllegalArgumentException("Length must be a multiple of 4");
+ }
+
+ // Read input stream until end of file
+ int bits = 0;
+ int nbits = 0;
+ int nbytes = 0;
+ int b;
+
+ while ((b = in.read()) != -1)
+ {
+ bits = (bits << 8) | b;
+ nbits += 8;
+ while (nbits >= 6)
+ {
+ nbits -= 6;
+ out.write(encTab[0x3f & (bits >> nbits)]);
+ nbytes++;
+ // New line
+ if (len != 0 && nbytes >= len)
+ {
+ out.write(0x0d);
+ out.write(0x0a);
+ nbytes -= len;
+ }
+ }
+ }
+
+ switch (nbits)
+ {
+ case 2:
+ out.write(encTab[0x3f & (bits << 4)]);
+ out.write(0x3d); // 0x3d = '='
+ out.write(0x3d);
+ break;
+ case 4:
+ out.write(encTab[0x3f & (bits << 2)]);
+ out.write(0x3d);
+ break;
+ }
+
+ if (len != 0)
+ {
+ if (nbytes != 0)
+ {
+ out.write(0x0d);
+ out.write(0x0a);
+ }
+ out.write(0x0d);
+ out.write(0x0a);
+ }
+ }
+
+
+ private static final String DELIM_START = "${";
+ private static final String DELIM_STOP = "}";
+
+ /**
+ * <p>
+ * This method performs property variable substitution on the
+ * specified value. If the specified value contains the syntax
+ * <tt>${<prop-name>}</tt>, where <tt><prop-name></tt>
+ * refers to either a configuration property or a system property,
+ * then the corresponding property value is substituted for the variable
+ * placeholder. Multiple variable placeholders may exist in the
+ * specified value as well as nested variable placeholders, which
+ * are substituted from inner most to outer most. Configuration
+ * properties override system properties.
+ * </p>
+ * @param val The string on which to perform property substitution.
+ * @param currentKey The key of the property being evaluated used to
+ * detect cycles.
+ * @param cycleMap Map of variable references used to detect nested cycles.
+ * @param configProps Set of configuration properties.
+ * @return The value of the specified string after system property substitution.
+ * @throws IllegalArgumentException If there was a syntax error in the
+ * property placeholder syntax or a recursive variable reference.
+ **/
+ public static String substVars(String val, String currentKey,
+ Map cycleMap, Properties configProps)
+ throws IllegalArgumentException
+ {
+ // If there is currently no cycle map, then create
+ // one for detecting cycles for this invocation.
+ if (cycleMap == null)
+ {
+ cycleMap = new HashMap();
+ }
+
+ // Put the current key in the cycle map.
+ cycleMap.put(currentKey, currentKey);
+
+ // Assume we have a value that is something like:
+ // "leading ${foo.${bar}} middle ${baz} trailing"
+
+ // Find the first ending '}' variable delimiter, which
+ // will correspond to the first deepest nested variable
+ // placeholder.
+ int stopDelim = -1;
+ int startDelim = -1;
+
+ do
+ {
+ stopDelim = val.indexOf(DELIM_STOP, stopDelim + 1);
+ // If there is no stopping delimiter, then just return
+ // the value since there is no variable declared.
+ if (stopDelim < 0)
+ {
+ return val;
+ }
+ // Try to find the matching start delimiter by
+ // looping until we find a start delimiter that is
+ // greater than the stop delimiter we have found.
+ startDelim = val.indexOf(DELIM_START);
+ // If there is no starting delimiter, then just return
+ // the value since there is no variable declared.
+ if (startDelim < 0)
+ {
+ return val;
+ }
+ while (stopDelim >= 0)
+ {
+ int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
+ if ((idx < 0) || (idx > stopDelim))
+ {
+ break;
+ }
+ else if (idx < stopDelim)
+ {
+ startDelim = idx;
+ }
+ }
+ }
+ while ((startDelim > stopDelim) && (stopDelim >= 0));
+
+ // At this point, we have found a variable placeholder so
+ // we must perform a variable substitution on it.
+ // Using the start and stop delimiter indices, extract
+ // the first, deepest nested variable placeholder.
+ String variable =
+ val.substring(startDelim + DELIM_START.length(), stopDelim);
+
+ // Verify that this is not a recursive variable reference.
+ if (cycleMap.get(variable) != null)
+ {
+ throw new IllegalArgumentException(
+ "recursive variable reference: " + variable);
+ }
+
+ // Get the value of the deepest nested variable placeholder.
+ // Try to configuration properties first.
+ String substValue = (configProps != null)
+ ? configProps.getProperty(variable, null)
+ : null;
+ if (substValue == null)
+ {
+ // Ignore unknown property values.
+ substValue = System.getProperty(variable, "");
+ }
+
+ // Remove the found variable from the cycle map, since
+ // it may appear more than once in the value and we don't
+ // want such situations to appear as a recursive reference.
+ cycleMap.remove(variable);
+
+ // Append the leading characters, the substituted value of
+ // the variable, and the trailing characters to get the new
+ // value.
+ val = val.substring(0, startDelim)
+ + substValue
+ + val.substring(stopDelim + DELIM_STOP.length(), val.length());
+
+ // Now perform substitution again, since there could still
+ // be substitutions to make.
+ val = substVars(val, currentKey, cycleMap, configProps);
+
+ // Return the value.
+ return val;
+ }
+
+ /**
+ * Checks if the provided module definition declares a fragment host.
+ *
+ * @param module the module to check
+ * @return <code>true</code> if the module declares a fragment host, <code>false</code>
+ * otherwise.
+ */
+ public static boolean isFragment(BundleRevision revision)
+ {
+ return ((revision.getTypes() & BundleRevision.TYPE_FRAGMENT) > 0);
+ }
+
+ public static List<BundleRevision> getFragments(BundleWiring wiring)
+ {
+ List<BundleRevision> fragments = Collections.EMPTY_LIST;
+ if (wiring != null)
+ {
+ List<BundleWire> wires = wiring.getProvidedWires(null);
+ if (wires != null)
+ {
+ for (BundleWire w : wires)
+ {
+ if (w.getCapability().getNamespace()
+ .equals(BundleRevision.HOST_NAMESPACE))
+ {
+ // Create array list if needed.
+ if (fragments.isEmpty())
+ {
+ fragments = new ArrayList<BundleRevision>();
+ }
+ fragments.add(w.getRequirerWiring().getRevision());
+ }
+ }
+ }
+ }
+ return fragments;
+ }
+}
\ No newline at end of file