Package org.lilyproject.runtime.module.build

Source Code of org.lilyproject.runtime.module.build.LilyRuntimeNamespaceHandler

/*
* Copyright 2013 NGDATA nv
* Copyright 2007 Outerthought bvba and Schaubroeck nv
*
* Licensed 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.lilyproject.runtime.module.build;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.jxpath.JXPathContext;
import org.lilyproject.runtime.LilyRTException;
import org.lilyproject.runtime.conf.Conf;
import org.lilyproject.runtime.model.JavaServiceInjectDefinition;
import org.lilyproject.runtime.module.javaservice.JavaServiceManager;
import org.lilyproject.runtime.rapi.ConfRegistry;
import org.lilyproject.runtime.rapi.LilyRuntimeModule;
import org.lilyproject.runtime.rapi_impl.LilyRuntimeModuleImpl;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.NamespaceHandler;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class LilyRuntimeNamespaceHandler implements NamespaceHandler {

    public void init() {
    }

    public BeanDefinition parse(Element element, ParserContext parserContext) {
        SpringBuildContext springBuildContext = ModuleBuilder.SPRING_BUILD_CONTEXT.get();

        String elementName = element.getLocalName();
        ElementProcessor processor = ELEMENT_PROCESSORS.get(elementName);

        if (processor != null) {
            try {
                return processor.process(element, parserContext, springBuildContext);
            } catch (Throwable e) {
                throw new LilyRTException("Error handling " + elementName + " directive.", e);
            }
        }

        return null;
    }

    public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder beanDefinitionHolder, ParserContext parserContext) {
        return null;
    }

    private static interface ElementProcessor {
        BeanDefinition process(Element element, ParserContext parserContext, SpringBuildContext springBuildContext) throws Exception;
    }

    private static final ElementProcessor MODULE_PROCESSOR = new ElementProcessor() {
        public BeanDefinition process(Element element, ParserContext parserContext, SpringBuildContext springBuildContext) {
            String classLoaderBeanId = element.getAttribute("classLoader");
            if (classLoaderBeanId.length() > 0) {
                RootBeanDefinition def = new RootBeanDefinition(ObjectFactoryBean.class);

                ConstructorArgumentValues args = new ConstructorArgumentValues();
                args.addIndexedArgumentValue(0, ClassLoader.class);
                args.addIndexedArgumentValue(1, springBuildContext.getModuleClassLoader());

                def.setConstructorArgumentValues(args);
                def.setLazyInit(false);

                parserContext.getRegistry().registerBeanDefinition(classLoaderBeanId, def);
            }

            String handleBeanId = element.getAttribute("handle");
            if (handleBeanId.length() > 0) {
                RootBeanDefinition def = new RootBeanDefinition(ObjectFactoryBean.class);

                ConstructorArgumentValues args = new ConstructorArgumentValues();
                args.addIndexedArgumentValue(0, LilyRuntimeModule.class);
                args.addIndexedArgumentValue(1, new LilyRuntimeModuleImpl(springBuildContext.getModule(), springBuildContext.getRuntime()));

                def.setConstructorArgumentValues(args);
                def.setLazyInit(false);

                parserContext.getRegistry().registerBeanDefinition(handleBeanId, def);
            }

            String confBeanId = element.getAttribute("conf");
            if (confBeanId.length() > 0) {
                RootBeanDefinition def = new RootBeanDefinition(ObjectFactoryBean.class);

                String moduleId = springBuildContext.getModule().getDefinition().getId();
                ConfRegistry confRegistry = springBuildContext.getRuntime().getConfManager().getConfRegistry(moduleId);

                ConstructorArgumentValues args = new ConstructorArgumentValues();
                args.addIndexedArgumentValue(0, ConfRegistry.class);
                args.addIndexedArgumentValue(1, confRegistry);

                def.setConstructorArgumentValues(args);
                def.setLazyInit(false);

                parserContext.getRegistry().registerBeanDefinition(confBeanId, def);
            }

            return null;
        }
    };

    private static final ElementProcessor IMPORT_SERVICE_PROCESSOR = new ElementProcessor() {
        public BeanDefinition process(Element element, ParserContext parserContext, SpringBuildContext springBuildContext) throws ClassNotFoundException {
            String service = element.getAttribute("service");
            Class serviceClass = parserContext.getReaderContext().getBeanClassLoader().loadClass(service);
            JavaServiceManager javaServiceManager = springBuildContext.getRuntime().getJavaServiceManager();

            String id = element.getAttribute("id");

            String dependencyName = element.getAttribute("name");
            if (dependencyName.equals("")) {
                dependencyName = id;
            }

            Object component;
            try {
                JavaServiceInjectDefinition injectDef = springBuildContext.getModule().getDefinition().getJavaServiceInject(dependencyName);
                if (injectDef == null) {
                    injectDef = springBuildContext.getModule().getDefinition().getJavaServiceInjectByService(serviceClass.getName());
                }

                if (injectDef != null) {
                    String moduleId = injectDef.getSourceModuleId();
                    String name = injectDef.getSourceJavaServiceName();
                    if (moduleId != null && name != null) {
                        component = javaServiceManager.getService(serviceClass, moduleId, name);
                    } else {
                        component = javaServiceManager.getService(serviceClass, moduleId);
                    }
                } else {
                    component = javaServiceManager.getService(serviceClass);
                }
            } catch (Throwable t) {
                throw new LilyRTException("Error assigning Java service dependency " + dependencyName + " of module "
                        + springBuildContext.getModule().getDefinition().getId(), t);
            }

            RootBeanDefinition def = new RootBeanDefinition(ObjectFactoryBean.class);

            ConstructorArgumentValues args = new ConstructorArgumentValues();
            args.addIndexedArgumentValue(0, serviceClass);
            args.addIndexedArgumentValue(1, component);

            def.setConstructorArgumentValues(args);
            def.setLazyInit(false);
            parserContext.getRegistry().registerBeanDefinition(id, def);

            return null;
        }
    };

    private static final ElementProcessor EXPORT_SERVICE_PROCESSOR = new ElementProcessor() {
        public BeanDefinition process(Element element, ParserContext parserContext, SpringBuildContext springBuildContext)
                throws ClassNotFoundException {
            String service = element.getAttribute("service");
            Class serviceClass = parserContext.getReaderContext().getBeanClassLoader().loadClass(service);

            String beanName = element.getAttribute("ref");
            String name = element.getAttribute("name");
            if (name.equals("")) {
                name = beanName;
            }

            springBuildContext.exportJavaService(name, serviceClass, beanName);

            return null;
        }
    };

    private static final ElementProcessor CONF_PROCESSOR = new ElementProcessor() {
        public BeanDefinition process(Element element, ParserContext parserContext, SpringBuildContext springBuildContext)
                throws Exception {
            String path = element.getAttribute("path");
            String expr = element.getAttribute("select");
            String type = element.getAttribute("type");

            String moduleId = springBuildContext.getModule().getDefinition().getId();
            Conf conf = springBuildContext.getRuntime().getConfManager().getConfRegistry(moduleId).getConfiguration(path);

            if (expr.length() > 0) {
                JXPathContext context = JXPathContext.newContext(conf);
                Object value;

                try {
                    if (type != null && type.equals("node")) {
                        value = context.selectSingleNode(expr);
                        if (!(value instanceof Conf)) {
                            throw new LilyRTException("Element " + element.getTagName() + " of Spring bean config in module " +
                            moduleId + ": configuration pointed to by expression \"" + expr + "\""
                            + " does not evaluate to a node.");
                        }
                    } else {
                        value = String.valueOf(context.getValue(expr));
                    }
                } catch (LilyRTException e) {
                    throw e;
                } catch (Exception e) {
                    throw new LilyRTException("Element " + element.getTagName() + " of Spring bean config in module " +
                            moduleId + ": error retrieving configuration value using expression \"" + expr + "\""
                            + " from configuration path \"" + path + "\".", e);
                }

                GenericBeanDefinition def = new GenericBeanDefinition();
                def.setBeanClass(ObjectFactoryBean.class);

                ConstructorArgumentValues args = new ConstructorArgumentValues();
                args.addIndexedArgumentValue(0, value instanceof Conf ? Conf.class : String.class);
                args.addIndexedArgumentValue(1, value);

                def.setConstructorArgumentValues(args);
                def.setLazyInit(false);

                return def;
            } else {
                GenericBeanDefinition def = new GenericBeanDefinition();
                def.setBeanClass(ObjectFactoryBean.class);

                ConstructorArgumentValues args = new ConstructorArgumentValues();
                args.addIndexedArgumentValue(0, Conf.class);
                args.addIndexedArgumentValue(1, conf);

                def.setConstructorArgumentValues(args);
                def.setLazyInit(false);

                return def;
            }
        }
    };

    private static final Map<String, ElementProcessor> ELEMENT_PROCESSORS;

    static {
        ELEMENT_PROCESSORS = new HashMap<String, ElementProcessor>();
        ELEMENT_PROCESSORS.put("import-service", IMPORT_SERVICE_PROCESSOR);
        ELEMENT_PROCESSORS.put("export-service", EXPORT_SERVICE_PROCESSOR);
        ELEMENT_PROCESSORS.put("module", MODULE_PROCESSOR);
        ELEMENT_PROCESSORS.put("conf", CONF_PROCESSOR);
    }
}
TOP

Related Classes of org.lilyproject.runtime.module.build.LilyRuntimeNamespaceHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.