cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dk...@apache.org
Subject [3/9] Experiment with pulling spring out of core
Date Thu, 01 May 2014 15:49:41 GMT
http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusDefinitionParser.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusDefinitionParser.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusDefinitionParser.java
new file mode 100644
index 0000000..d3f200d
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusDefinitionParser.java
@@ -0,0 +1,299 @@
+/**
+ * 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.spring;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.apache.cxf.configuration.spring.BusWiringType;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.AbstractBasicInterceptorProvider;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.message.Message;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class BusDefinitionParser extends AbstractBeanDefinitionParser {
+    private static AtomicInteger counter = new AtomicInteger(0);
+
+    public BusDefinitionParser() {
+        super();
+        setBeanClass(BusConfig.class);
+    }
+
+    protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder bean) {
+        String bus = element.getAttribute("bus");        
+        if (StringUtils.isEmpty(bus)) {
+            bus = element.getAttribute("name");
+            if (StringUtils.isEmpty(bus)) {
+                element.setAttribute("bus", bus);
+            }
+        }
+        element.removeAttribute("name");
+        if (StringUtils.isEmpty(bus)) {
+            bus = "cxf";
+        }
+        String id = element.getAttribute("id");
+        if (!StringUtils.isEmpty(id)) {
+            bean.addPropertyValue("id", id);
+        }
+
+        super.doParse(element, ctx, bean);
+        
+        if (ctx.getRegistry().containsBeanDefinition(bus)) {
+            BeanDefinition def = ctx.getRegistry().getBeanDefinition(bus);
+            copyProps(bean, def);
+            bean.addConstructorArgValue(bus);
+        } else if (!"cxf".equals(bus)) {
+            bean.getRawBeanDefinition().setBeanClass(SpringBus.class);
+            bean.setDestroyMethodName("shutdown");
+            try {
+                element.setUserData("ID", bus, null);
+                bean.getRawBeanDefinition().getPropertyValues().removePropertyValue("bus");
+            } catch (Throwable t) {
+                //likely not DOM level 3, ignore
+            }
+        } else {
+            addBusWiringAttribute(bean, BusWiringType.PROPERTY, bus, ctx);
+            bean.getRawBeanDefinition().setAttribute(WIRE_BUS_CREATE, 
+                                                     resolveId(element, null, ctx));
+            bean.addConstructorArgValue(bus);
+        }
+    }
+    protected boolean processBusAttribute(Element element, ParserContext ctx, 
+                                          BeanDefinitionBuilder bean,
+                                          String val) {
+        return false;
+    }
+    private void copyProps(BeanDefinitionBuilder src, BeanDefinition def) {
+        for (PropertyValue v : src.getBeanDefinition().getPropertyValues().getPropertyValues()) {
+            if (!"bus".equals(v.getName())) {
+                def.getPropertyValues().addPropertyValue(v.getName(), v.getValue());
+            }
+            src.getBeanDefinition().getPropertyValues().removePropertyValue(v);
+        }
+        
+    }
+
+    @Override
+    protected void mapElement(ParserContext ctx, 
+                              BeanDefinitionBuilder bean, 
+                              Element e, 
+                              String name) {
+        if ("inInterceptors".equals(name) || "inFaultInterceptors".equals(name)
+            || "outInterceptors".equals(name) || "outFaultInterceptors".equals(name)
+            || "features".equals(name)) {
+            List<?> list = ctx.getDelegate().parseListElement(e, bean.getBeanDefinition());
+            bean.addPropertyValue(name, list);
+        } else if ("properties".equals(name)) {
+            Map<?, ?> map = ctx.getDelegate().parseMapElement(e, bean.getBeanDefinition());
+            bean.addPropertyValue("properties", map);
+        }
+    }
+    @Override
+    protected String resolveId(Element element, AbstractBeanDefinition definition, 
+                               ParserContext ctx) {
+        String bus = null;
+        try {
+            bus = (String)element.getUserData("ID");
+        } catch (Throwable t) {
+            //ignore
+        }
+        if (bus == null) {
+            bus = element.getAttribute("bus");        
+            if (StringUtils.isEmpty(bus)) {
+                bus = element.getAttribute("name");
+            }
+            if (StringUtils.isEmpty(bus)) {
+                bus = Bus.DEFAULT_BUS_ID + ".config" + counter.getAndIncrement();
+            } else {
+                bus = bus + ".config";
+            }
+            try {
+                element.setUserData("ID", bus, null);
+            } catch (Throwable t) {
+                //maybe no DOM level 3, ignore, but, may have issues with the counter 
+            }
+        }
+        return bus;
+    }
+    
+    @NoJSR250Annotations
+    public static class BusConfig extends AbstractBasicInterceptorProvider
+        implements ApplicationContextAware {
+        
+        Bus bus;
+        String busName;
+        String id;
+        Collection<Feature> features;
+        Map<String, Object> properties;
+        
+        public BusConfig(String busName) {
+            this.busName = busName;
+        }
+        
+        public void setBus(Bus bb) {
+            if (bus == bb) {
+                return;
+            }
+            bus = bb;
+            if (properties != null) {
+                bus.setProperties(properties);
+                properties = null;
+            }
+            if (!getInInterceptors().isEmpty()) {
+                bus.getInInterceptors().addAll(getInInterceptors());
+            }
+            if (!getOutInterceptors().isEmpty()) {
+                bus.getOutInterceptors().addAll(getOutInterceptors());
+            }
+            if (!getInFaultInterceptors().isEmpty()) {
+                bus.getInFaultInterceptors().addAll(getInFaultInterceptors());
+            }
+            if (!getOutFaultInterceptors().isEmpty()) {
+                bus.getOutFaultInterceptors().addAll(getOutFaultInterceptors());
+            }
+            if (!StringUtils.isEmpty(id)) {
+                bus.setId(id);
+            }
+            if (features != null) {
+                bus.setFeatures(features);
+                features = null;
+            }
+        }
+
+        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+            if (bus != null) {
+                return;
+            }             
+        }
+        
+        public List<Interceptor<? extends Message>> getOutFaultInterceptors() {
+            if (bus != null) {
+                return bus.getOutFaultInterceptors();
+            }
+            return super.getOutFaultInterceptors();
+        }
+
+        public List<Interceptor<? extends Message>> getInFaultInterceptors() {
+            if (bus != null) {
+                return bus.getInFaultInterceptors();
+            }
+            return super.getInFaultInterceptors();
+        }
+
+        public List<Interceptor<? extends Message>> getInInterceptors() {
+            if (bus != null) {
+                return bus.getInInterceptors();
+            }
+            return super.getInInterceptors();
+        }
+
+        public List<Interceptor<? extends Message>> getOutInterceptors() {
+            if (bus != null) {
+                return bus.getOutInterceptors();
+            }
+            return super.getOutInterceptors();
+        }
+
+        public void setInInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getInInterceptors().addAll(interceptors);
+            } else {
+                super.setInInterceptors(interceptors);
+            }
+        }
+
+        public void setInFaultInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getInFaultInterceptors().addAll(interceptors);
+            } else {
+                super.setInFaultInterceptors(interceptors);
+            }
+        }
+
+        public void setOutInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getOutInterceptors().addAll(interceptors);
+            } else {
+                super.setOutInterceptors(interceptors);
+            }
+        }
+
+        public void setOutFaultInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getOutFaultInterceptors().addAll(interceptors);
+            } else {
+                super.setOutFaultInterceptors(interceptors);
+            }
+        }
+        
+        public Collection<Feature> getFeatures() {
+            if (bus != null) {
+                return bus.getFeatures();
+            }
+            return features;
+        }
+
+        public void setFeatures(Collection<? extends Feature> features) {
+            if (bus != null) {
+                bus.setFeatures(features);
+            } else {
+                this.features = CastUtils.cast(features);
+            }
+            
+        }
+        
+        public Map<String, Object> getProperties() {
+            if (bus != null) {
+                return bus.getProperties();
+            } 
+            return properties;
+        }
+        public void setProperties(Map<String, Object> s) {
+            if (bus != null) {
+                bus.setProperties(s);
+            } else {
+                this.properties = s;
+            }
+        }
+        
+        public void setId(String s) {
+            id = s;
+        }
+
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusEntityResolver.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusEntityResolver.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusEntityResolver.java
new file mode 100644
index 0000000..65d3ffc
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusEntityResolver.java
@@ -0,0 +1,89 @@
+/**
+ * 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.spring;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.springframework.beans.factory.xml.DelegatingEntityResolver;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PropertiesLoaderUtils;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * 
+ */
+public class BusEntityResolver extends DelegatingEntityResolver  {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(BusEntityResolver.class);
+    
+    private EntityResolver dtdResolver;
+    private EntityResolver schemaResolver;
+    private Map<String, String> schemaMappings;
+    private ClassLoader classLoader;
+    
+    public BusEntityResolver(ClassLoader loader, EntityResolver dr, EntityResolver sr) {
+        super(dr, sr);
+        classLoader = loader;
+        dtdResolver = dr;
+        schemaResolver = sr;
+        
+        try {
+            Properties mappings = PropertiesLoaderUtils.loadAllProperties("META-INF/spring.schemas", 
+                                                                          classLoader);
+            schemaMappings = new ConcurrentHashMap<String, String>(mappings.size());
+            CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
+        } catch (IOException e) {
+            //ignore
+        }
+    }
+
+    @Override
+    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+        InputSource source = super.resolveEntity(publicId, systemId);
+        if (null == source && null != systemId) {
+            // try the schema and dtd resolver in turn, ignoring the suffix in publicId
+            LOG.log(Level.FINE, "Attempting to resolve systemId {0}", systemId);
+            source = schemaResolver.resolveEntity(publicId, systemId);                
+            if (null == source) {
+                source = dtdResolver.resolveEntity(publicId, systemId); 
+            }
+        }
+        String resourceLocation = schemaMappings.get(systemId);
+        if (resourceLocation != null && publicId == null) {
+            Resource resource = new ClassPathResource(resourceLocation, classLoader);
+            if (resource != null && resource.exists()) {
+                source.setPublicId(systemId);    
+                source.setSystemId(resource.getURL().toString());
+            }
+        }
+        return source;
+    }    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java
new file mode 100644
index 0000000..3c6369d
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java
@@ -0,0 +1,71 @@
+/**
+ * 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.spring;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.extension.BusExtension;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+
+@NoJSR250Annotations
+public class BusExtensionPostProcessor implements BeanPostProcessor, ApplicationContextAware, Ordered {
+
+    private Bus bus;
+    private ApplicationContext context;
+
+    public void setApplicationContext(ApplicationContext ctx) {
+        context = ctx;
+    } 
+    
+    public int getOrder() {
+        return 1001;
+    }
+    
+        
+    public Object postProcessAfterInitialization(Object bean, String beanId) throws BeansException {
+        return bean;
+    }
+
+    public Object postProcessBeforeInitialization(Object bean, String beanId) throws BeansException {
+        if (bean instanceof BusExtension && null != getBus()) {
+            Class<? extends Object> cls = ((BusExtension)bean).getRegistrationType();
+            registerExt(bean, cls);
+        } else if (bean instanceof Bus && Bus.DEFAULT_BUS_ID.equals(beanId)) {
+            bus = (Bus)bean;
+        }
+        return bean;
+    }
+    private <T> void registerExt(Object bean, Class<T> cls) {
+        getBus().setExtension(cls.cast(bean), cls);
+    }
+    
+    private Bus getBus() {
+        if (bus == null) {
+            bus = (Bus)context.getBean(Bus.DEFAULT_BUS_ID);
+        }
+        return bus;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusWiringBeanFactoryPostProcessor.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusWiringBeanFactoryPostProcessor.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusWiringBeanFactoryPostProcessor.java
new file mode 100644
index 0000000..e24da64
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/BusWiringBeanFactoryPostProcessor.java
@@ -0,0 +1,174 @@
+/**
+ * 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.spring;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.apache.cxf.configuration.spring.BusWiringType;
+import org.apache.cxf.helpers.CastUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * BeanFactoryPostProcessor that looks for any bean definitions that have the
+ * {@link AbstractBeanDefinitionParser#WIRE_BUS_ATTRIBUTE} attribute set. If the attribute has the value
+ * {@link BusWiringType#PROPERTY} then it attaches their "bus" property to the bean called "cxf". If the
+ * attribute has the value {@link BusWiringType#CONSTRUCTOR} then it shifts any existing indexed constructor
+ * arguments one place to the right and adds a reference to "cxf" as the first constructor argument. This
+ * processor is intended to operate on beans defined via Spring namespace support which require a reference to
+ * the CXF bus.
+ */
+public class BusWiringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
+
+    Bus bus;
+    String busName;
+    
+    public BusWiringBeanFactoryPostProcessor() {
+    }
+
+    public BusWiringBeanFactoryPostProcessor(Bus b) {
+        bus = b;
+    }
+    public BusWiringBeanFactoryPostProcessor(String n) {
+        busName = n;
+    }
+    private static Bus getBusForName(String name,
+                                     ApplicationContext context,
+                                     boolean create) {
+        if (!context.containsBean(name) && (create || Bus.DEFAULT_BUS_ID.equals(name))) {
+            SpringBus b = new SpringBus();
+            ConfigurableApplicationContext cctx = (ConfigurableApplicationContext)context;
+            cctx.getBeanFactory().registerSingleton(name, b);
+            b.setApplicationContext(context);
+        }
+        return (Bus)context.getBean(name, Bus.class);
+    }
+    private Object getBusForName(String name,
+                                 ConfigurableListableBeanFactory factory,
+                                 boolean create,
+                                 String cn) {
+        if (!factory.containsBeanDefinition(name) && (create || Bus.DEFAULT_BUS_ID.equals(name))) {
+            DefaultListableBeanFactory df = (DefaultListableBeanFactory)factory;
+            RootBeanDefinition rbd = new RootBeanDefinition(SpringBus.class);
+            if (cn != null) {
+                rbd.setAttribute("busConfig", new RuntimeBeanReference(cn));
+            }
+            df.registerBeanDefinition(name, rbd);
+        } else if (cn != null) {
+            BeanDefinition bd = factory.getBeanDefinition(name);
+            bd.getPropertyValues().addPropertyValue("busConfig", new RuntimeBeanReference(cn));
+        }
+        return new RuntimeBeanReference(name);        
+    }
+    
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
+        Object inject = bus;
+        if (inject == null) {
+            inject = getBusForName(Bus.DEFAULT_BUS_ID, factory, true, null);
+        } else {
+            if (!factory.containsBeanDefinition(Bus.DEFAULT_BUS_ID)
+                && !factory.containsSingleton(Bus.DEFAULT_BUS_ID)) {
+                factory.registerSingleton(Bus.DEFAULT_BUS_ID, bus);
+            }
+        }
+        for (String beanName : factory.getBeanDefinitionNames()) {
+            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
+            BusWiringType type 
+                = (BusWiringType)beanDefinition.getAttribute(AbstractBeanDefinitionParser.WIRE_BUS_ATTRIBUTE);
+            if (type == null) {
+                continue;
+            }
+            String busname = (String)beanDefinition.getAttribute(AbstractBeanDefinitionParser.WIRE_BUS_NAME);
+            String create = (String)beanDefinition
+                .getAttribute(AbstractBeanDefinitionParser.WIRE_BUS_CREATE);
+            Object inj = inject;
+            if (busname != null) {
+                if (bus != null) {
+                    continue;
+                }
+                inj = getBusForName(busname, factory, create != null, create);
+            }
+            beanDefinition.removeAttribute(AbstractBeanDefinitionParser.WIRE_BUS_NAME);
+            beanDefinition.removeAttribute(AbstractBeanDefinitionParser.WIRE_BUS_ATTRIBUTE);
+            beanDefinition.removeAttribute(AbstractBeanDefinitionParser.WIRE_BUS_CREATE);
+            if (create == null) {
+                if (BusWiringType.PROPERTY == type) {
+                    beanDefinition.getPropertyValues()
+                        .addPropertyValue("bus", inj);
+                } else if (BusWiringType.CONSTRUCTOR == type) {
+                    ConstructorArgumentValues constructorArgs = beanDefinition.getConstructorArgumentValues();
+                    insertConstructorArg(constructorArgs, inj);
+                }
+            }
+        }
+    }
+
+    /**
+     * Insert the given value as the first constructor argument in the given set. To do this, we clear the
+     * argument set, then re-insert all its generic arguments, then re-insert all its indexed arguments with
+     * their indices incremented by 1, and finally set the first indexed argument (at index 0) to the given
+     * value.
+     * 
+     * @param constructorArgs the argument definition to modify.
+     * @param valueToInsert the value to insert as the first argument.
+     */
+    private void insertConstructorArg(ConstructorArgumentValues constructorArgs, Object valueToInsert) {
+        List<ValueHolder> genericArgs = new ArrayList<ValueHolder>(CastUtils
+            .<ValueHolder> cast(constructorArgs.getGenericArgumentValues()));
+        Map<Integer, ValueHolder> indexedArgs = new HashMap<Integer, ValueHolder>(CastUtils
+            .<Integer, ValueHolder> cast(constructorArgs.getIndexedArgumentValues()));
+
+        constructorArgs.clear();
+        for (ValueHolder genericValue : genericArgs) {
+            constructorArgs.addGenericArgumentValue(genericValue);
+        }
+        for (Map.Entry<Integer, ValueHolder> entry : indexedArgs.entrySet()) {
+            constructorArgs.addIndexedArgumentValue(entry.getKey() + 1, entry.getValue());
+        }
+        constructorArgs.addIndexedArgumentValue(0, valueToInsert);
+    }
+    
+    public static Bus addDefaultBus(ApplicationContext ctx) {
+        if (!ctx.containsBean(Bus.DEFAULT_BUS_ID)) {
+            Bus b = getBusForName(Bus.DEFAULT_BUS_ID, ctx, true);
+            if (ctx instanceof ConfigurableApplicationContext) {
+                ConfigurableApplicationContext cctx = (ConfigurableApplicationContext)ctx;
+                new BusWiringBeanFactoryPostProcessor(b).postProcessBeanFactory(cctx.getBeanFactory());
+            }
+        }
+        return Bus.class.cast(ctx.getBean(Bus.DEFAULT_BUS_ID, Bus.class));
+    }
+    public static Bus addBus(ApplicationContext ctx, String name) {
+        return getBusForName(name, ctx, true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java
new file mode 100644
index 0000000..007ce70
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java
@@ -0,0 +1,197 @@
+/**
+ * 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.spring;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+
+import org.w3c.dom.Document;
+
+import org.xml.sax.InputSource;
+
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.core.io.support.EncodedResource;
+
+/**
+ * CXF reads a series of Spring XML files as part of initialization.
+ * The time it takes to parse them, especially if validating, builds up.
+ * The XML files shipped in a release in the JARs are valid and invariant.
+ * To speed things up, this class implements two levels of optimization.
+ * When a CXF distribution is fully-packaged, each of the Spring XML 
+ * bus extension .xml files is accompanied by a FastInfoset '.fixml' file.
+ * These read much more rapidly. When one of those is present, this classs
+ * reads it instead of reading the XML text file. 
+ * 
+ * Absent a .fixml file, this class uses WoodStox instead of Xerces (or
+ * whatever the JDK is providing).
+ * 
+ * The Woodstox optimization also applies to user cxf.xml or cxf-servlet.xml files
+ * if the user has disabled XML validation of Spring files with
+ * the org.apache.cxf.spring.validation.mode system property.
+ * 
+ * Note that the fastInfoset optimization is only applied for the 
+ * methods here that start from a Resource. If this is called with an InputSource,
+ * that optimization is not applied, since we can't reliably know the
+ * location of the XML. 
+ */
+public class ControlledValidationXmlBeanDefinitionReader extends XmlBeanDefinitionReader {
+
+    /**
+     * Exception class used to avoid reading old FastInfoset files.
+     */
+    private static class StaleFastinfosetException extends Exception {
+
+        private static final long serialVersionUID = -3594973504794187383L;
+
+    }
+
+    // the following flag allows performance comparisons with and 
+    // without fast infoset processing.
+    private boolean noFastinfoset;
+    // Spring has no 'getter' for this, so we need our own copy.
+    private int visibleValidationMode = VALIDATION_AUTO;
+    // We need a reference to the subclass.
+    private TunedDocumentLoader tunedDocumentLoader;
+    /**
+     * @param beanFactory
+     */
+    public ControlledValidationXmlBeanDefinitionReader(BeanDefinitionRegistry beanFactory) {
+        super(beanFactory);
+        tunedDocumentLoader = new TunedDocumentLoader();
+        this.setDocumentLoader(tunedDocumentLoader);
+        noFastinfoset = SystemPropertyAction.getPropertyOrNull("org.apache.cxf.nofastinfoset") != null 
+            || !TunedDocumentLoader.hasFastInfoSet();
+    }
+
+    @Override
+    protected int doLoadBeanDefinitions(InputSource inputSource, 
+                                        Resource resource) throws BeanDefinitionStoreException {
+        // sadly, the Spring class we are extending has the critical function
+        // getValidationModeForResource
+        // marked private instead of protected, so trickery is called for here.
+        boolean suppressValidation = false;
+        try {
+            URL url = resource.getURL();
+            if (url.getFile().contains("META-INF/cxf/")) {
+                suppressValidation = true;
+            }
+        } catch (IOException e) {
+            // this space intentionally left blank.
+        }
+        
+        int savedValidation = visibleValidationMode;
+        if (suppressValidation) {
+            setValidationMode(VALIDATION_NONE);
+        }
+        int r = super.doLoadBeanDefinitions(inputSource, resource);
+        setValidationMode(savedValidation);
+        return r;
+    }
+
+    @Override
+    public void setValidationMode(int validationMode) {
+        visibleValidationMode = validationMode;
+        super.setValidationMode(validationMode);
+    }
+
+    @Override
+    public int loadBeanDefinitions(final EncodedResource encodedResource)
+        throws BeanDefinitionStoreException {
+        if (!noFastinfoset) {
+            try {
+                return fastInfosetLoadBeanDefinitions(encodedResource);
+            } catch (BeanDefinitionStoreException bdse) {
+                throw bdse;
+            } catch (Throwable e) {
+                //ignore - just call the super to load them
+            }
+        }
+        try {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<Integer>() {
+                public Integer run() throws Exception {
+                    return internalLoadBeanDefinitions(encodedResource);
+                }
+                
+            });
+        } catch (PrivilegedActionException e) {
+            if (e.getException() instanceof RuntimeException) {
+                throw (RuntimeException)e.getException();
+            }
+            throw (BeanDefinitionStoreException)e.getException();
+        }
+    }
+    
+    private int internalLoadBeanDefinitions(EncodedResource encodedResource) {
+        return super.loadBeanDefinitions(encodedResource);
+    }
+    
+    private int fastInfosetLoadBeanDefinitions(EncodedResource encodedResource)
+        throws IOException, StaleFastinfosetException, 
+        ParserConfigurationException, XMLStreamException {
+        
+        URL resUrl = encodedResource.getResource().getURL();
+        // There are XML files scampering around that don't end in .xml.
+        // We don't apply the optimization to them.
+        if (!resUrl.getPath().endsWith(".xml")) {
+            throw new StaleFastinfosetException();
+        }
+        String fixmlPath = resUrl.getPath().replaceFirst("\\.xml$", ".fixml");
+        String protocol = resUrl.getProtocol();
+        // beware of the relative URL rules for jar:, which are surprising.
+        if ("jar".equals(protocol)) {
+            fixmlPath = fixmlPath.replaceFirst("^.*!", "");
+        }
+        
+        URL fixmlUrl = new URL(resUrl, fixmlPath);
+
+        // if we are in unpacked files, we take some extra time
+        // to ensure that we aren't using a stale Fastinfoset file.
+        if ("file".equals(protocol)) {
+            URLConnection resCon = null;
+            URLConnection fixCon = null;
+            resCon = resUrl.openConnection();
+            fixCon = fixmlUrl.openConnection();
+            if (resCon.getLastModified() > fixCon.getLastModified()) {
+                throw new StaleFastinfosetException();
+            }
+        }
+        
+        Resource newResource = new UrlResource(fixmlUrl); 
+        Document doc = TunedDocumentLoader.loadFastinfosetDocument(fixmlUrl);
+        if (doc == null) {
+            //something caused FastinfoSet to not be able to read the doc
+            throw new StaleFastinfosetException();
+        }
+        return registerBeanDefinitions(doc, newResource);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java
new file mode 100644
index 0000000..25748bf
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java
@@ -0,0 +1,157 @@
+/**
+ * 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.spring;
+
+
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.ResourceInjector;
+import org.apache.cxf.resource.ResourceManager;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+
+public class Jsr250BeanPostProcessor 
+    implements DestructionAwareBeanPostProcessor, Ordered, ApplicationContextAware {
+
+    private ResourceManager resourceManager;
+    private ApplicationContext context;
+
+    private boolean isProcessing = true;
+    //private int count;
+    //private int count2;
+
+    Jsr250BeanPostProcessor() {
+    }
+    
+    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
+        context = arg0;  
+        try {
+            Class<?> cls = Class
+                .forName("org.springframework.context.annotation.CommonAnnotationBeanPostProcessor");
+            isProcessing = context.getBeanNamesForType(cls, true, false).length == 0;
+        } catch (ClassNotFoundException e) {
+            isProcessing = true;
+        }
+    }
+    
+    public int getOrder() {
+        return 1010;
+    }
+        
+    private boolean injectable(Object bean, String beanId) {
+        return !"cxf".equals(beanId) && ResourceInjector.processable(bean.getClass(), bean);
+    }
+    private ResourceManager getResourceManager(Object bean) {
+        if (resourceManager == null) {
+            boolean temp = isProcessing;
+            isProcessing = false;
+            if (bean instanceof ResourceManager) {
+                resourceManager = (ResourceManager)bean;
+                resourceManager.addResourceResolver(new BusApplicationContextResourceResolver(context));
+            } else if (bean instanceof Bus) {
+                Bus b = (Bus)bean;
+                ResourceManager m = b.getExtension(ResourceManager.class);
+                if (m != null) {
+                    resourceManager = m;
+                    if (!(b instanceof SpringBus)) {
+                        resourceManager
+                            .addResourceResolver(new BusApplicationContextResourceResolver(context));
+                    }
+                }
+            } else {
+                ResourceManager m = null;
+                Bus b = null;
+                try {
+                    m = (ResourceManager)context.getBean(ResourceManager.class.getName());
+                } catch (NoSuchBeanDefinitionException t) {
+                    //ignore - no resource manager
+                }
+                if (m == null) {
+                    b = (Bus)context.getBean("cxf");
+                    m = b.getExtension(ResourceManager.class);
+                }
+                if (m != null) {
+                    resourceManager = m;
+                    if (!(b instanceof SpringBus)) {
+                        resourceManager
+                            .addResourceResolver(new BusApplicationContextResourceResolver(context));
+                    }
+                }
+            }
+            isProcessing = temp;
+        }
+        return resourceManager;
+    }
+    public Object postProcessAfterInitialization(Object bean, String beanId) throws BeansException {
+        if (!isProcessing) {
+            if (resourceManager == null && bean instanceof ResourceManager) {
+                resourceManager = (ResourceManager)bean;
+                resourceManager.addResourceResolver(new BusApplicationContextResourceResolver(context));
+            }
+            return bean;
+        }
+        if (bean != null 
+            && injectable(bean, beanId)) {
+            new ResourceInjector(getResourceManager(bean)).construct(bean);
+        }
+        return bean;
+    }
+
+    public Object postProcessBeforeInitialization(Object bean, String beanId) throws BeansException {
+        if (!isProcessing) {
+            return bean;
+        }
+        if (bean instanceof Bus) {
+            getResourceManager(bean);
+        }
+        /*
+        if (bean.getClass().getName().contains("Corb")) {
+            Thread.dumpStack();
+        }
+        */
+        
+        if (bean != null 
+            && injectable(bean, beanId)) {
+            new ResourceInjector(getResourceManager(bean)).inject(bean);
+            /*
+            System.out.println("p :" + (++count) + ": " + bean.getClass().getName() + " " + beanId);
+        } else if (bean != null) {
+            System.out.println("np: " + (++count2) 
+                               + ": " + bean.getClass().getName() + " " + beanId);
+                               */
+        }
+        return bean;
+    }
+
+    public void postProcessBeforeDestruction(Object bean, String beanId) {
+        if (!isProcessing) {
+            return;
+        }
+        if (bean != null 
+            && injectable(bean, beanId)) {
+            new ResourceInjector(getResourceManager(bean)).destroy(bean);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/Messages.properties
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/Messages.properties b/rt/spring/src/main/java/org/apache/cxf/bus/spring/Messages.properties
new file mode 100644
index 0000000..3783c8e
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/Messages.properties
@@ -0,0 +1,27 @@
+#
+#
+#    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.
+#
+#
+USER_CFG_FILE_NOT_FOUND_MSG = Could not find the configuration file {0} on the classpath.
+USER_CFG_FILE_IN_USE= Loaded configuration file {0}.
+USER_CFG_FILE_URL_ERROR_MSG = The configuration file URL {0} is a a malformed URL.
+USER_CFG_FILE_URL_NOT_FOUND_MSG = Could not find the configuration file in the url of {0}.
+APP_CONTEXT_CREATION_FAILED_MSG = Failed to create application context.
+INITIAL_APP_CONTEXT_CREATION_FAILED_MSG = Initial attempt to create application context was unsuccessful.
+USER_CFG_FILE_NOT_LOADED=Failed to load configuration {0}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/NamespaceHandler.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/NamespaceHandler.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/NamespaceHandler.java
new file mode 100644
index 0000000..9a67b84
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/NamespaceHandler.java
@@ -0,0 +1,57 @@
+/**
+ * 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.spring;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.configuration.spring.SimpleBeanDefinitionParser;
+import org.apache.cxf.feature.FastInfosetFeature;
+import org.apache.cxf.feature.LoggingFeature;
+import org.apache.cxf.workqueue.AutomaticWorkQueueImpl;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+import org.springframework.beans.factory.xml.ParserContext;
+
+public class NamespaceHandler extends NamespaceHandlerSupport {
+    public void init() {
+        registerBeanDefinitionParser("bus",
+                                     new BusDefinitionParser());
+        registerBeanDefinitionParser("logging",
+                                     new SimpleBeanDefinitionParser(LoggingFeature.class));
+        registerBeanDefinitionParser("fastinfoset",
+                                     new SimpleBeanDefinitionParser(FastInfosetFeature.class));
+        
+        registerBeanDefinitionParser("workqueue",
+                                     new SimpleBeanDefinitionParser(AutomaticWorkQueueImpl.class) {
+
+                protected void processNameAttribute(Element element,
+                                                ParserContext ctx,
+                                                BeanDefinitionBuilder bean,
+                                                String val) {
+                    bean.addPropertyValue("name", val);
+                    element.removeAttribute("name");
+                    if (!element.hasAttribute("id")) {
+                        val = "cxf.workqueue." + val;
+                        element.setAttribute("id", val);
+                    }
+                    
+                }
+            });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBeanLocator.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBeanLocator.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBeanLocator.java
new file mode 100644
index 0000000..6686cd1
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBeanLocator.java
@@ -0,0 +1,313 @@
+/**
+ * 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.spring;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerImpl;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.configuration.ConfiguredBeanLocator;
+import org.springframework.beans.Mergeable;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * 
+ */
+public class SpringBeanLocator implements ConfiguredBeanLocator {
+    private static final Logger LOG = LogUtils.getL7dLogger(SpringBeanLocator.class);
+    
+    ApplicationContext context;
+    ConfiguredBeanLocator orig;
+    Set<String> passThroughs = new HashSet<String>();
+    Object bundleContext;
+    boolean osgi = true;
+    
+    public SpringBeanLocator(ApplicationContext ctx) {
+        this(ctx, null);
+    }
+    public SpringBeanLocator(ApplicationContext ctx, Bus bus) {
+        context = ctx;
+        if (bus != null) {
+            orig = bus.getExtension(ConfiguredBeanLocator.class);
+            if (orig instanceof ExtensionManagerImpl) {
+                List<String> names = new ArrayList<String>();
+                for (String s : ctx.getBeanDefinitionNames()) {
+                    names.add(s);
+                    for (String s2 : ctx.getAliases(s)) {
+                        names.add(s2);
+                    }
+                }
+                
+                ((ExtensionManagerImpl)orig).removeBeansOfNames(names);
+            }
+        }
+        loadOSGIContext(bus);
+    }
+
+    private void loadOSGIContext(Bus b) {
+        bundleContext = findBundleContext(context, b);
+        if (bundleContext == null) {
+            osgi = false;
+        }
+    }
+    
+    private Object findBundleContext(ApplicationContext applicationContext, Bus b) {
+        Object answer = null;
+        ApplicationContext aContext = applicationContext;
+        // try to find out the bundleContext by going through the parent context
+        while (aContext != null && answer == null) {
+            answer = getBundleContext(aContext, b);
+            aContext = aContext.getParent();
+        }
+        return answer;
+    }
+    
+    private Object getBundleContext(ApplicationContext applicationContext, Bus b) {
+        try {
+            //use a little reflection to allow this to work without the spring-dm jars
+            //for the non-osgi cases
+            Method m = applicationContext.getClass().getMethod("getBundleContext");
+            Object o = m.invoke(applicationContext);
+            if (o != null && b != null) {
+                @SuppressWarnings("unchecked")
+                Class<Object> cls = (Class<Object>)m.getReturnType();
+                b.setExtension(o, cls);
+            }
+            return o;
+        } catch (Throwable t) {
+            // do nothing here
+        }
+        return null;
+    }
+    
+    public <T> T getBeanOfType(String name, Class<T> type) {
+        T t = null;
+        try {
+            t = type.cast(context.getBean(name, type));
+        } catch (NoSuchBeanDefinitionException nsbde) {
+            //ignore
+        }
+        if (t == null) {
+            t = orig.getBeanOfType(name, type);
+        }
+        return t;
+    }
+    
+    /** {@inheritDoc}*/
+    public List<String> getBeanNamesOfType(Class<?> type) {
+        Set<String> s = new LinkedHashSet<String>(Arrays.asList(context.getBeanNamesForType(type,
+                                                                                         false,
+                                                                                         false)));
+        s.removeAll(passThroughs);
+        s.addAll(orig.getBeanNamesOfType(type));
+        return new ArrayList<String>(s);
+    }
+
+    /** {@inheritDoc}*/
+    public <T> Collection<? extends T> getBeansOfType(Class<T> type) {
+        Set<String> s = new LinkedHashSet<String>(Arrays.asList(context.getBeanNamesForType(type,
+                                                                                            false,
+                                                                                            false)));
+        s.removeAll(passThroughs);
+        List<T> lst = new LinkedList<T>();
+        for (String n : s) {
+            lst.add(type.cast(context.getBean(n, type)));
+        }
+        lst.addAll(orig.getBeansOfType(type));
+        if (lst.isEmpty()) {
+            tryOSGI(lst, type);
+        }
+        return lst;
+    }
+    private <T> void tryOSGI(Collection<T> lst, Class<T> type) {
+        if (!osgi) {
+            return;
+        }
+        try {
+            //use a little reflection to allow this to work without the spring-dm jars
+            //for the non-osgi cases
+            Class<?> contextClass = findContextClass(bundleContext.getClass());
+
+            Method m = contextClass.getMethod("getServiceReference", String.class);
+            ReflectionUtil.setAccessible(m);
+            Object o = m.invoke(bundleContext, type.getName());
+            if (o != null) {
+                m = contextClass.getMethod("getService", m.getReturnType());
+                ReflectionUtil.setAccessible(m);
+                o = m.invoke(bundleContext, o);
+                lst.add(type.cast(o));
+            }
+        } catch (NoSuchMethodException e) {
+            osgi = false;
+            //not using OSGi
+        } catch (Throwable e) {
+            //ignore
+            LOG.log(Level.WARNING, "Could not get service for " + type.getName(), e);
+        }
+    }
+    private Class<?> findContextClass(Class<?> cls) {
+        for (Class<?> c : cls.getInterfaces()) {
+            if (c.getName().equals("org.osgi.framework.BundleContext")) {
+                return c;
+            }
+        }
+        for (Class<?> c : cls.getInterfaces()) {
+            Class<?> c2 = findContextClass(c);
+            if (c2 != null) {
+                return c2;
+            }
+        }
+        Class<?> c2 = findContextClass(cls.getSuperclass());
+        if (c2 != null) {
+            return c2;
+        }
+        
+        return cls;
+    }
+    
+
+    public <T> boolean loadBeansOfType(Class<T> type,
+                                       BeanLoaderListener<T> listener) {
+        List<String> list = new ArrayList<String>(Arrays.asList(context.getBeanNamesForType(type,
+                                                                                            false,
+                                                                                            false)));
+        list.removeAll(passThroughs);
+        Collections.reverse(list);
+        boolean loaded = false;
+        for (String s : list) {
+            Class<?> beanType = context.getType(s);
+            Class<? extends T> t = beanType.asSubclass(type);
+            if (listener.loadBean(s, t)) {
+                Object o = context.getBean(s);
+                if (listener.beanLoaded(s, type.cast(o))) {
+                    return true;
+                }
+                loaded = true;
+            }
+        }
+        return loaded || orig.loadBeansOfType(type, listener);
+    }
+
+    public boolean hasConfiguredPropertyValue(String beanName, String propertyName, String searchValue) {
+        if (context.containsBean(beanName) && !passThroughs.contains(beanName)) {
+            ConfigurableApplicationContext ctxt = (ConfigurableApplicationContext)context;
+            BeanDefinition def = ctxt.getBeanFactory().getBeanDefinition(beanName);
+            if (!ctxt.getBeanFactory().isSingleton(beanName) || def.isAbstract()) {
+                return false;
+            }
+            Collection<?> ids = null;
+            PropertyValue pv = def.getPropertyValues().getPropertyValue(propertyName);
+            
+            if (pv != null) {
+                Object value = pv.getValue();
+                if (!(value instanceof Collection)) {
+                    throw new RuntimeException("The property " + propertyName + " must be a collection!");
+                }
+    
+                if (value instanceof Mergeable) {
+                    if (!((Mergeable)value).isMergeEnabled()) {
+                        ids = (Collection<?>)value;
+                    }
+                } else {
+                    ids = (Collection<?>)value;
+                }
+            } 
+            
+            if (ids != null) {
+                for (Iterator<?> itr = ids.iterator(); itr.hasNext();) {
+                    Object o = itr.next();
+                    if (o instanceof TypedStringValue) {
+                        if (searchValue.equals(((TypedStringValue) o).getValue())) {
+                            return true;
+                        }
+                    } else {
+                        if (searchValue.equals(o)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return orig.hasConfiguredPropertyValue(beanName, propertyName, searchValue);
+    }
+
+    public <T> List<T> getOSGiServices(Class<T> type) {
+        List<T> lst = new ArrayList<T>();
+        if (!osgi) {
+            return lst;
+        }
+        
+        Class<?> contextClass = findContextClass(bundleContext.getClass());
+        try {
+            Method m = contextClass.getMethod("getServiceReference", String.class);
+            Class<?> servRefClass = m.getReturnType();
+            m = contextClass.getMethod("getServiceReferences", String.class, String.class);
+            
+            Object o = ReflectionUtil.setAccessible(m).invoke(bundleContext, type.getName(), null);
+            if (o != null) {
+                m = contextClass.getMethod("getService", servRefClass);
+                ReflectionUtil.setAccessible(m);
+                for (int x = 0; x < Array.getLength(o); x++) {
+                    Object ref = Array.get(o, x);
+                    Object o2 = m.invoke(bundleContext, ref);
+                    if (o2 != null) {
+                        lst.add(type.cast(o2));
+                    }
+                }
+            }
+        } catch (NoSuchMethodException e) {
+            //not using OSGi apparently
+            e.printStackTrace();
+        } catch (Throwable e) {
+            //ignore
+            e.printStackTrace();
+            LOG.log(Level.FINE, "Could not get services for " + type.getName(), e);
+        }
+        return lst;
+    }
+
+    public boolean hasBeanOfName(String name) {
+        if (context.containsBean(name)) {
+            return true;
+        }
+        return orig.hasBeanOfName(name);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBus.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBus.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBus.java
new file mode 100644
index 0000000..648431d
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBus.java
@@ -0,0 +1,145 @@
+/**
+ * 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.spring;
+
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.configuration.ConfiguredBeanLocator;
+import org.apache.cxf.configuration.Configurer;
+import org.apache.cxf.configuration.spring.ConfigurerImpl;
+import org.apache.cxf.resource.ResourceManager;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.context.support.AbstractApplicationContext;
+
+/**
+ * 
+ */
+public class SpringBus extends ExtensionManagerBus 
+    implements ApplicationContextAware {
+
+    AbstractApplicationContext ctx;
+    boolean closeContext;
+    
+    public SpringBus() {
+    }
+    
+    public void setBusConfig(BusDefinitionParser.BusConfig bc) {
+        bc.setBus(this);
+    }
+    
+    public void loadAdditionalFeatures() {
+        super.loadAdditionalFeatures();
+    }
+    
+    /** {@inheritDoc}*/
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        ctx = (AbstractApplicationContext)applicationContext;
+        @SuppressWarnings("rawtypes")
+        ApplicationListener listener = new ApplicationListener() {
+            public void onApplicationEvent(ApplicationEvent event) {
+                SpringBus.this.onApplicationEvent(event);
+            }
+        };
+        ctx.addApplicationListener(listener);
+        ApplicationContext ac = applicationContext.getParent();
+        while (ac != null) {
+            if (ac instanceof AbstractApplicationContext) {
+                ((AbstractApplicationContext)ac).addApplicationListener(listener);
+            }
+            ac = ac.getParent();
+        }
+        
+        // set the classLoader extension with the application context classLoader
+        setExtension(applicationContext.getClassLoader(), ClassLoader.class);
+        
+        setExtension(new ConfigurerImpl(applicationContext), Configurer.class);
+        
+        ResourceManager m = getExtension(ResourceManager.class);
+        m.addResourceResolver(new BusApplicationContextResourceResolver(applicationContext));
+        
+        setExtension(applicationContext, ApplicationContext.class);
+        ConfiguredBeanLocator loc = getExtension(ConfiguredBeanLocator.class);
+        if (!(loc instanceof SpringBeanLocator)) {
+            setExtension(new SpringBeanLocator(applicationContext, this), ConfiguredBeanLocator.class);
+        }
+        if (getState() != BusState.RUNNING) {
+            initialize();
+        }
+    }
+
+    public void onApplicationEvent(ApplicationEvent event) {
+        if (ctx == null) {
+            return;
+        }
+        boolean doIt = false;
+        ApplicationContext ac = ctx;
+        while (ac != null && !doIt) {
+            if (event.getSource() == ac) {
+                doIt = true;
+                break;
+            }
+            ac = ac.getParent();
+        }
+        if (doIt) {
+            if (event instanceof ContextRefreshedEvent) {
+                if (getState() != BusState.RUNNING) {
+                    initialize();
+                }
+            } else if (event instanceof ContextClosedEvent && getState() == BusState.RUNNING) {
+                // The bus could be create by using SpringBusFactory.createBus("/cxf.xml"); 
+                // Just to make sure the shutdown is called rightly
+                shutdown();
+            }
+        }
+    }
+    
+    public void destroyBeans() {
+        if (closeContext) {
+            ctx.close();
+        }
+        super.destroyBeans();
+    }
+    
+    public String getId() {
+        if (id == null) {
+            try {
+                Class<?> clsbc = Class.forName("org.osgi.framework.BundleContext");
+                Class<?> clsb = Class.forName("org.osgi.framework.Bundle");
+                Object o = getExtension(clsbc);
+                Object o2 = clsbc.getMethod("getBundle").invoke(o);
+                String s = (String)clsb.getMethod("getSymbolicName").invoke(o2);
+                id = s + "-" + DEFAULT_BUS_ID + Integer.toString(this.hashCode());
+            } catch (Throwable t) {
+                id = super.getId();
+            }
+        }
+        return id;
+    }
+
+    public void setCloseContext(boolean b) {
+        closeContext = b;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBusFactory.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBusFactory.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBusFactory.java
new file mode 100644
index 0000000..04ea866
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/SpringBusFactory.java
@@ -0,0 +1,227 @@
+/**
+ * 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.spring;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.buslifecycle.BusLifeCycleListener;
+import org.apache.cxf.buslifecycle.BusLifeCycleManager;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.configuration.Configurer;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.xml.NamespaceHandlerResolver;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.io.Resource;
+
+public class SpringBusFactory extends BusFactory {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SpringBusFactory.class);
+    
+    private final ApplicationContext context;
+    private NamespaceHandlerResolver resolver;
+
+    public SpringBusFactory() {
+        this.context = null;
+    }
+
+    public SpringBusFactory(ApplicationContext context) {
+        this.context = context;
+        this.resolver = tryFindNamespaceHandler(context);
+    }
+    public SpringBusFactory(NamespaceHandlerResolver r) {
+        context = null;
+        this.resolver = r;
+    }
+    
+    private static NamespaceHandlerResolver tryFindNamespaceHandler(ApplicationContext ctx) {
+        try {
+            SpringBeanLocator sbl = new SpringBeanLocator(ctx);
+            List<NamespaceHandlerResolver> r = sbl.getOSGiServices(NamespaceHandlerResolver.class);
+            if (r != null && !r.isEmpty()) {
+                return r.get(0);
+            }
+        } catch (Throwable t) {
+            //ignore
+        }
+        return null;
+    }
+
+    public ApplicationContext getApplicationContext() {
+        return context;
+    }
+    public void setNamespaceHandlerResolver(NamespaceHandlerResolver r) {
+        resolver = r;
+    }
+        
+    public Bus createBus() {
+        return createBus((String)null);
+    }
+    
+    private boolean defaultBusNotExists() {
+        if (null != context) {
+            return !context.containsBean(Bus.DEFAULT_BUS_ID);
+        }
+        return true;
+    }
+
+    public Bus createBus(String cfgFile) {
+        return createBus(cfgFile, defaultBusNotExists());
+    }
+    
+    public Bus createBus(String cfgFiles[]) {
+        return createBus(cfgFiles, defaultBusNotExists());
+    }
+        
+    protected Bus finishCreatingBus(ConfigurableApplicationContext bac) {
+        final Bus bus = (Bus)bac.getBean(Bus.DEFAULT_BUS_ID);
+
+        bus.setExtension(bac, ApplicationContext.class);
+        if (bac instanceof BusApplicationContext) {
+            bus.setExtension((BusApplicationContext)bac, BusApplicationContext.class);
+        }
+        possiblySetDefaultBus(bus);
+        
+        initializeBus(bus);        
+        
+        registerApplicationContextLifeCycleListener(bus, bac);
+        
+        if (bus instanceof SpringBus && defaultBusNotExists()) {
+            ((SpringBus)bus).setCloseContext(true);
+        }
+        return bus;
+    }
+    
+    public Bus createBus(String cfgFile, boolean includeDefaults) {
+        if (cfgFile == null) {
+            return createBus((String[])null, includeDefaults);
+        }
+        return createBus(new String[] {cfgFile}, includeDefaults);
+    }    
+    
+    public Bus createBus(String cfgFiles[], boolean includeDefaults) {
+        try {
+            String userCfgFile 
+                = SystemPropertyAction.getPropertyOrNull(Configurer.USER_CFG_FILE_PROPERTY_NAME);
+            String sysCfgFileUrl 
+                = SystemPropertyAction.getPropertyOrNull(Configurer.USER_CFG_FILE_PROPERTY_URL);
+            final Resource r = BusApplicationContext.findResource(Configurer.DEFAULT_USER_CFG_FILE);
+
+            boolean exists = true;
+            if (r != null) {
+                exists = AccessController
+                    .doPrivileged(new PrivilegedAction<Boolean>() {
+                        public Boolean run() {
+                            return r.exists();
+                        }
+                    });
+            }
+            if (context == null && userCfgFile == null && cfgFiles == null && sysCfgFileUrl == null 
+                && (r == null || !exists) && includeDefaults) {
+                return new org.apache.cxf.bus.CXFBusFactory().createBus();
+            }
+            return finishCreatingBus(createApplicationContext(cfgFiles, includeDefaults));
+        } catch (BeansException ex) {
+            LogUtils.log(LOG, Level.WARNING, "APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null);
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    protected ConfigurableApplicationContext createApplicationContext(String cfgFiles[], boolean includeDefaults) {
+        try {      
+            return new BusApplicationContext(cfgFiles, includeDefaults, context, resolver);
+        } catch (BeansException ex) {
+            LogUtils.log(LOG, Level.WARNING, "INITIAL_APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null);
+            ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
+            if (contextLoader != BusApplicationContext.class.getClassLoader()) {
+                Thread.currentThread().setContextClassLoader(
+                    BusApplicationContext.class.getClassLoader());
+                try {
+                    return new BusApplicationContext(cfgFiles, includeDefaults, context);        
+                } finally {
+                    Thread.currentThread().setContextClassLoader(contextLoader);
+                }
+            } else {
+                throw ex;
+            }
+        }
+    }
+    
+    public Bus createBus(URL url) {
+        return createBus(url, defaultBusNotExists());
+    }
+    public Bus createBus(URL[] urls) {
+        return createBus(urls, defaultBusNotExists());
+    }
+    
+    public Bus createBus(URL url, boolean includeDefaults) {
+        if (url == null) {
+            return createBus((URL[])null, includeDefaults);
+        }
+        return createBus(new URL[] {url}, includeDefaults);
+    }
+    
+    public Bus createBus(URL[] urls, boolean includeDefaults) {
+        try {      
+            return finishCreatingBus(createAppContext(urls, includeDefaults));
+        } catch (BeansException ex) {
+            LogUtils.log(LOG, Level.WARNING, "APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null);
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    protected ConfigurableApplicationContext createAppContext(URL[] urls, boolean includeDefaults) {
+        return new BusApplicationContext(urls, includeDefaults, context, resolver);
+    }
+
+    void registerApplicationContextLifeCycleListener(Bus bus, ConfigurableApplicationContext bac) {
+        BusLifeCycleManager lm = bus.getExtension(BusLifeCycleManager.class);
+        if (null != lm) {
+            lm.registerLifeCycleListener(new BusApplicationContextLifeCycleListener(bac));
+        }
+    } 
+
+    static class BusApplicationContextLifeCycleListener implements BusLifeCycleListener {
+        private ConfigurableApplicationContext bac;
+
+        BusApplicationContextLifeCycleListener(ConfigurableApplicationContext b) {
+            bac = b;
+        }
+
+        public void initComplete() {
+        }
+
+        public void preShutdown() {
+        }
+
+        public void postShutdown() {
+            bac.close();
+        }
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/e46d0180/rt/spring/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java
----------------------------------------------------------------------
diff --git a/rt/spring/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java b/rt/spring/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java
new file mode 100644
index 0000000..b67fd94
--- /dev/null
+++ b/rt/spring/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java
@@ -0,0 +1,146 @@
+/**
+ * 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.spring;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.sax.SAXSource;
+
+import org.w3c.dom.Document;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import com.sun.xml.fastinfoset.stax.StAXDocumentParser;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.staxutils.W3CDOMStreamWriter;
+import org.springframework.beans.factory.xml.DefaultDocumentLoader;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+
+/**
+ * A Spring DocumentLoader that uses WoodStox when we are not validating to speed up the process. 
+ */
+class TunedDocumentLoader extends DefaultDocumentLoader {
+    private static final Logger LOG = LogUtils.getL7dLogger(TunedDocumentLoader.class); 
+    
+    private static boolean hasFastInfoSet;
+    
+    static {
+        try { 
+            ClassLoaderUtils
+                .loadClass("com.sun.xml.fastinfoset.stax.StAXDocumentParser", 
+                           TunedDocumentLoader.class); 
+            hasFastInfoSet = true;
+        } catch (Throwable e) { 
+            LOG.fine("FastInfoset not found on classpath. Disabling context load optimizations.");
+            hasFastInfoSet = false;
+        } 
+    }
+    private SAXParserFactory saxParserFactory;
+    private SAXParserFactory nsasaxParserFactory;
+    
+    TunedDocumentLoader() {
+        try {
+            Class<?> cls = ClassLoaderUtils.loadClass("com.ctc.wstx.sax.WstxSAXParserFactory",
+                                                      TunedDocumentLoader.class);
+            saxParserFactory = (SAXParserFactory)cls.newInstance();
+            nsasaxParserFactory = (SAXParserFactory)cls.newInstance();
+        } catch (Throwable e) {
+            //woodstox not found, use any other Stax parser
+            saxParserFactory = SAXParserFactory.newInstance();
+            nsasaxParserFactory = SAXParserFactory.newInstance();
+        }
+
+        try {
+            nsasaxParserFactory.setFeature("http://xml.org/sax/features/namespaces", true); 
+            nsasaxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", 
+                                           true);
+        } catch (Throwable e) {
+            //ignore
+        }
+        
+    }
+    
+    public static boolean hasFastInfoSet() {
+        return hasFastInfoSet;
+    }
+
+    @Override
+    public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
+                                 ErrorHandler errorHandler, int validationMode, boolean namespaceAware)
+        throws Exception {
+        if (validationMode == XmlBeanDefinitionReader.VALIDATION_NONE) {
+            SAXParserFactory parserFactory = 
+                namespaceAware ? nsasaxParserFactory : saxParserFactory;
+            SAXParser parser = parserFactory.newSAXParser();
+            XMLReader reader = parser.getXMLReader();
+            reader.setEntityResolver(entityResolver);
+            reader.setErrorHandler(errorHandler);
+            SAXSource saxSource = new SAXSource(reader, inputSource);
+            W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+            StaxUtils.copy(saxSource, writer);
+            return writer.getDocument();
+        } else {
+            return super.loadDocument(inputSource, entityResolver, errorHandler, validationMode,
+                                      namespaceAware);
+        }
+    }
+
+    @Override
+    protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware)
+        throws ParserConfigurationException {
+        DocumentBuilderFactory factory = super.createDocumentBuilderFactory(validationMode, namespaceAware);
+        try {
+            factory.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
+        } catch (Throwable e) {
+            // we can get all kinds of exceptions from this
+            // due to old copies of Xerces and whatnot.
+        }
+        
+        return factory;
+    }
+    
+    static Document loadFastinfosetDocument(URL url) 
+        throws IOException, ParserConfigurationException, XMLStreamException {
+        InputStream is = url.openStream();
+        InputStream in = new BufferedInputStream(is);
+        XMLStreamReader staxReader = new StAXDocumentParser(in);
+        W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+        StaxUtils.copy(staxReader, writer);
+        in.close();
+        return writer.getDocument();
+    }
+
+}


Mime
View raw message