org.lilyproject.runtime.module.build.LilyRuntimeNamespaceHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.lilyproject.runtime.module.build.LilyRuntimeNamespaceHandler.java

Source

/*
 * 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);
    }
}