org.apache.cxf.bus.extension.ExtensionManagerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-minimal Show documentation
Show all versions of cxf-bundle-minimal Show documentation
Apache CXF Minimal Bundle Jar
The newest version!
/**
* 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.cxf.bus.extension;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.cxf.Bus;
import org.apache.cxf.common.injection.ResourceInjector;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.configuration.ConfiguredBeanLocator;
import org.apache.cxf.configuration.Configurer;
import org.apache.cxf.resource.ObjectTypeResolver;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.resource.ResourceResolver;
import org.apache.cxf.resource.SinglePropertyResolver;
public class ExtensionManagerImpl implements ExtensionManager, ConfiguredBeanLocator {
public static final Logger LOG = LogUtils.getL7dLogger(ExtensionManagerImpl.class);
public static final String EXTENSIONMANAGER_PROPERTY_NAME = "extensionManager";
public static final String ACTIVATION_NAMESPACES_PROPERTY_NAME = "activationNamespaces";
public static final String ACTIVATION_NAMESPACES_SETTER_METHOD_NAME = "setActivationNamespaces";
public static final String BUS_EXTENSION_RESOURCE_XML = "META-INF/cxf/bus-extensions.xml";
public static final String BUS_EXTENSION_RESOURCE_OLD_XML = "bus-extensions.xml";
public static final String BUS_EXTENSION_RESOURCE = "META-INF/cxf/bus-extensions.txt";
private final ClassLoader loader;
private ResourceManager resourceManager;
private Map all = new ConcurrentHashMap();
private final Map, Object> activated;
private final Bus bus;
public ExtensionManagerImpl(ClassLoader cl, Map, Object> initialExtensions,
ResourceManager rm, Bus b) {
this(new String[] {BUS_EXTENSION_RESOURCE, BUS_EXTENSION_RESOURCE_XML,
BUS_EXTENSION_RESOURCE_OLD_XML},
cl, initialExtensions, rm, b);
}
public ExtensionManagerImpl(String resource,
ClassLoader cl,
Map, Object> initialExtensions,
ResourceManager rm,
Bus b) {
this(new String[] {resource}, cl, initialExtensions, rm, b);
}
public ExtensionManagerImpl(String resources[],
ClassLoader cl,
Map, Object> initialExtensions,
ResourceManager rm,
Bus b) {
loader = cl;
bus = b;
activated = initialExtensions;
resourceManager = rm;
ResourceResolver extensionManagerResolver =
new SinglePropertyResolver(EXTENSIONMANAGER_PROPERTY_NAME, this);
resourceManager.addResourceResolver(extensionManagerResolver);
resourceManager.addResourceResolver(new ObjectTypeResolver(this));
load(resources);
for (Map.Entry ext : ExtensionRegistry.getRegisteredExtensions().entrySet()) {
if (!all.containsKey(ext.getKey())) {
all.put(ext.getKey(), ext.getValue());
}
}
}
final void load(String resources[]) {
if (resources == null) {
return;
}
try {
for (String resource : resources) {
load(resource);
}
} catch (IOException ex) {
throw new ExtensionException(ex);
}
}
public void add(Extension ex) {
all.put(ex.getName(), ex);
}
public void initialize() {
for (Extension e : all.values()) {
if (!e.isDeferred() && e.getLoadedObject() == null) {
loadAndRegister(e);
}
}
}
public void removeBeansOfNames(List names) {
for (String s : names) {
all.remove(s);
}
}
public void activateAll() {
for (Extension e : all.values()) {
if (e.getLoadedObject() == null) {
loadAndRegister(e);
}
}
}
public void activateAllByType(Class type) {
for (Extension e : all.values()) {
if (e.getLoadedObject() == null) {
Class> cls = e.getClassObject(loader);
if (cls != null && type.isAssignableFrom(cls)) {
synchronized (e) {
loadAndRegister(e);
}
}
}
}
}
public boolean hasBeanOfName(String name) {
return all.containsKey(name);
}
final void load(String resource) throws IOException {
if (loader != getClass().getClassLoader()) {
load(resource, getClass().getClassLoader());
}
load(resource, loader);
}
@SuppressWarnings("deprecation")
final synchronized void load(String resource, ClassLoader l) throws IOException {
Enumeration urls = l.getResources(resource);
while (urls.hasMoreElements()) {
final URL url = urls.nextElement();
InputStream is;
try {
is = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public InputStream run() throws Exception {
return url.openStream();
}
});
} catch (PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
try {
List exts;
if (resource.endsWith("xml")) {
LOG.log(Level.WARNING, "DEPRECATED_EXTENSIONS",
new Object[] {resource, url, BUS_EXTENSION_RESOURCE});
exts = new XmlExtensionFragmentParser().getExtensions(is);
} else {
exts = new TextExtensionFragmentParser(loader).getExtensions(is);
}
for (Extension e : exts) {
if (loader != l) {
e.classloader = l;
}
if (!all.containsKey(e.getName())) {
all.put(e.getName(), e);
}
}
} finally {
try {
is.close();
} catch (IOException ex) {
//ignore
}
}
}
}
final void loadAndRegister(Extension e) {
Class> cls = null;
if (null != e.getInterfaceName() && !"".equals(e.getInterfaceName())) {
cls = e.loadInterface(loader);
} else {
cls = e.getClassObject(loader);
}
if (null != activated && null != cls && null != activated.get(cls)) {
return;
}
synchronized (e) {
Object obj = e.load(loader, bus);
if (obj == null) {
return;
}
if (null != activated) {
Configurer configurer = (Configurer)(activated.get(Configurer.class));
if (null != configurer) {
configurer.configureBean(obj);
}
}
// let the object know for which namespaces it has been activated
ResourceResolver namespacesResolver = null;
if (null != e.getNamespaces()) {
namespacesResolver = new SinglePropertyResolver(ACTIVATION_NAMESPACES_PROPERTY_NAME,
e.getNamespaces());
resourceManager.addResourceResolver(namespacesResolver);
}
// Since we need to support spring2.5 by removing @Resource("activationNamespaces")
// Now we call the setActivationNamespaces method directly here
if (e.getNamespaces() != null && !e.getNamespaces().isEmpty()) {
invokeSetterActivationNSMethod(obj, e.getNamespaces());
}
ResourceInjector injector = new ResourceInjector(resourceManager);
try {
injector.inject(obj);
injector.construct(obj);
} finally {
if (null != namespacesResolver) {
resourceManager.removeResourceResolver(namespacesResolver);
}
}
if (null != activated) {
if (cls == null) {
cls = obj.getClass();
}
activated.put(cls, obj);
}
}
}
public T getExtension(String name, Class type) {
if (name == null) {
return null;
}
Extension e = all.get(name);
if (e != null) {
Class> cls = e.getClassObject(loader);
if (cls != null && type.isAssignableFrom(cls)) {
synchronized (e) {
if (e.getLoadedObject() == null) {
loadAndRegister(e);
}
return type.cast(e.getLoadedObject());
}
}
}
return null;
}
private void invokeSetterActivationNSMethod(Object target, Object value) {
Class> clazz = target.getClass();
String methodName = ACTIVATION_NAMESPACES_SETTER_METHOD_NAME;
while (clazz != Object.class) {
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
Class> params[] = method.getParameterTypes();
if (method.getName().equals(methodName) && params.length == 1) {
Class> paramType = params[0];
if (paramType.isInstance(value)) {
try {
method.invoke(target, new Object[] {value});
} catch (Exception e) {
// do nothing here
}
return;
}
}
}
clazz = clazz.getSuperclass();
}
}
public List getBeanNamesOfType(Class> type) {
List ret = new LinkedList();
for (Extension ex : all.values()) {
Class> cls = ex.getClassObject(loader);
if (cls != null && type.isAssignableFrom(cls)) {
synchronized (ex) {
ret.add(ex.getName());
}
}
}
return ret;
}
public T getBeanOfType(String name, Class type) {
if (name == null) {
return null;
}
Extension ex = all.get(name);
if (ex != null) {
if (ex.getLoadedObject() == null) {
loadAndRegister(ex);
}
return type.cast(ex.getLoadedObject());
}
return null;
}
public Collection extends T> getBeansOfType(Class type) {
List ret = new LinkedList();
Extension ext = all.get(type.getName());
if (ext != null) {
Class> cls = ext.getClassObject(loader);
if (cls != null && type.isAssignableFrom(cls)) {
synchronized (ext) {
if (ext.getLoadedObject() == null) {
loadAndRegister(ext);
}
ret.add(type.cast(ext.getLoadedObject()));
}
}
}
for (Extension ex : all.values()) {
if (ex != ext) {
Class> cls = ex.getClassObject(loader);
if (cls != null && type.isAssignableFrom(cls)) {
synchronized (ex) {
if (ex.getLoadedObject() == null) {
loadAndRegister(ex);
}
ret.add(type.cast(ex.getLoadedObject()));
}
}
}
}
return ret;
}
public boolean loadBeansOfType(Class type, BeanLoaderListener listener) {
boolean loaded = false;
for (Extension ex : all.values()) {
Class> cls = ex.getClassObject(loader);
if (cls != null
&& ex.getLoadedObject() == null
&& type.isAssignableFrom(cls)) {
synchronized (ex) {
if (listener.loadBean(ex.getName(), cls.asSubclass(type))) {
loadAndRegister(ex);
if (listener.beanLoaded(ex.getName(), type.cast(ex.getLoadedObject()))) {
return true;
}
}
}
}
}
return loaded;
}
public boolean hasConfiguredPropertyValue(String beanName, String propertyName, String value) {
if (beanName == null) {
return false;
}
Extension ex = all.get(beanName);
return ex != null && ex.getNamespaces() != null
&& ex.getNamespaces().contains(value);
}
public void destroyBeans() {
for (Extension ex : all.values()) {
if (ex.getLoadedObject() != null) {
ResourceInjector injector = new ResourceInjector(resourceManager);
injector.destroy(ex.getLoadedObject());
}
}
}
}