Package org.jboss.seam.wiki.core.plugin.binding.lacewiki

Source Code of org.jboss.seam.wiki.core.plugin.binding.lacewiki.PluginBinder

/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.seam.wiki.core.plugin.binding.lacewiki;

import org.dom4j.Element;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.*;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.exception.InvalidWikiConfigurationException;
import org.jboss.seam.wiki.core.plugin.PluginRegistry;
import org.jboss.seam.wiki.core.plugin.PluginCacheManager;
import org.jboss.seam.wiki.core.plugin.metamodel.MacroPluginModule;
import org.jboss.seam.wiki.core.plugin.metamodel.*;
import org.jboss.seam.wiki.core.plugin.metamodel.PluginModule;
import org.jboss.seam.wiki.preferences.PreferenceVisibility;
import org.jboss.seam.wiki.preferences.metamodel.PreferenceEntity;
import org.jboss.seam.wiki.preferences.metamodel.PreferenceRegistry;

import java.util.*;

/**
* Parses and binds plugin.xml metadata to plugin metamodel.
*
* @author Christian Bauer
*/
@Name("pluginBinder")
@Scope(ScopeType.APPLICATION)
@Startup
public class PluginBinder extends org.jboss.seam.wiki.core.plugin.binding.PluginBinder {

    @Logger
    Log log;

    @In
    PreferenceRegistry preferenceRegistry;

    @In
    Map<String,String> messages;

    @Create
    public void readDescriptors() {
        log.debug("reading deployment descriptors as XML...");
        descriptors = PluginDeploymentHandler.instance().getDescriptorsAsXmlElements();
    }

    Map<String, Element> descriptors = new HashMap<String, Element>();

    public void bindPlugins(PluginRegistry registry) {
        log.debug("installing plugins from XML descriptors: " + descriptors.size());

        for (Map.Entry<String, Element> descriptor : descriptors.entrySet()) {
            log.debug("installing deployment descriptor: " + descriptor.getKey());
            Element root = descriptor.getValue();

            String pluginKey = root.attributeValue("key");

            log.debug("binding plugin: " + descriptor.getKey());
            Plugin plugin = new Plugin(descriptor.getKey(), pluginKey);
            log.debug("plugin descriptor package path: " + plugin.getDescriptorPackagePath());
            registry.addPlugin(pluginKey, plugin);

            String pluginLabel = root.attributeValue("label");
            if (pluginLabel == null) pluginLabel = getMessage(plugin.getKey()+".label");
            plugin.setLabel(pluginLabel);

            bindPluginInfo(root, plugin);
            bindMacroPluginModules(registry, root, plugin);
            bindProfilePluginModules(registry, root, plugin);
        }

        bindMacroParameters(registry);
    }

    private void bindPluginInfo(Element root, Plugin plugin) {
        List<Element> pluginInfos = root.elements("plugin-info");
        if (pluginInfos.size() == 1) {
            PluginInfo pluginInfo = new PluginInfo();

            pluginInfo.setVersion(pluginInfos.get(0).attributeValue("version"));

            String description = pluginInfos.get(0).attributeValue("description");
            if (description == null) description = getMessage(plugin.getKey()+".description");
            pluginInfo.setDescription(description);

            List<Element> applicationVersions = pluginInfos.get(0).elements("application-version");
            if (applicationVersions.size() == 1) {
                pluginInfo.setApplicationVersion(
                    applicationVersions.get(0).attributeValue("min"),
                    applicationVersions.get(0).attributeValue("max")
                );
            }

            List<Element> vendors = pluginInfos.get(0).elements("vendor");
            if (vendors.size() == 1) {
                pluginInfo.setVendor(
                    vendors.get(0).attributeValue("name"),
                    vendors.get(0).attributeValue("url")
                );
            }
           
            plugin.setPluginInfo(pluginInfo);
        }
    }

    private void bindMacroPluginModules(PluginRegistry registry, Element root, Plugin plugin) {

        // Iterate through the XML descriptor and bind every <macro> to corresponding metamodel instances
        List<Element> macroPlugins = root.elements("macro");
        for (Element descriptor : macroPlugins) {

            String moduleKey = descriptor.attributeValue("key");
            MacroPluginModule module = new MacroPluginModule(plugin, moduleKey);

            log.debug("binding macro plugin module: " + module.getFullyQualifiedKey());

            bindLabelDescription(descriptor, module, plugin);
            bindMacroApplicableTo(descriptor, module);
            bindMacroRenderOptions(descriptor, module);
            bindSkins(descriptor, module);
            bindCacheRegions(descriptor, module);

            String macroName = descriptor.attributeValue("name");
            if (registry.getMacroPluginModulesByMacroName().containsKey(macroName)) {
                throw new InvalidWikiConfigurationException("Duplicate macro name, needs to be globally unique: " + macroName);
            }
            module.setName(macroName);

            // Finally, bind it
            plugin.getModules().add(module);
            registry.getMacroPluginModulesByKey().put(module.getFullyQualifiedKey(), module);
            registry.getMacroPluginModulesByMacroName().put(module.getName(), module);
        }

    }

    private void bindProfilePluginModules(PluginRegistry registry, Element root, Plugin plugin) {

        // Iterate through the XML descriptor and bind every <profile> to corresponding metamodel instances
        List<Element> profilePlugins = root.elements("profile");
        for (Element descriptor : profilePlugins) {

            String moduleKey = descriptor.attributeValue("key");
            ProfilePluginModule module = new ProfilePluginModule(plugin, moduleKey);

            log.debug("binding profile plugin module: " + module.getFullyQualifiedKey());

            bindLabelDescription(descriptor, module, plugin);
            bindSkins(descriptor, module);

            module.setTemplate(descriptor.attributeValue("template"));
            module.setPriority(new Integer(descriptor.attributeValue("priority")));

            // Finally, bind it
            plugin.getModules().add(module);
            registry.getProfilePluginModulesByPriority().add(module);
        }

    }

    private void bindLabelDescription(Element descriptor, PluginModule module, Plugin plugin) {
        String label = descriptor.attributeValue("label");
        if (label == null) label = getMessage(plugin.getKey() + "." + module.getKey() + ".label");
        module.setLabel(label);
        String description = descriptor.attributeValue("description");
        if (description == null) description = getMessage(plugin.getKey() + "." + module.getKey() + ".description");
        module.setDescription(description);
    }

    private void bindCacheRegions(Element descriptor, PluginModule module) {
        Element cacheRegionsDescriptor = descriptor.element("cache-regions");
        if (cacheRegionsDescriptor != null) {
            List<Element> cacheRegions = cacheRegionsDescriptor.elements("cache-region");
            if (cacheRegions.size() > 0) {
                for (Element cacheRegion : cacheRegions) {
                    String unqualifiedCacheRegionName = cacheRegion.attributeValue("name");
                    module.addFragmentCacheRegion(unqualifiedCacheRegionName);

                    List<Element> invalidationEvents = cacheRegion.elements("invalidation-event");
                    if (invalidationEvents != null) {
                        for (Element invalidationEvent : invalidationEvents) {
                            String eventName = invalidationEvent.attributeValue("name");
                            PluginCacheManager.registerBinding(
                                    eventName,
                                    module.getQualifiedCacheRegionName(unqualifiedCacheRegionName)
                            );
                        }
                    }
                }
            }
        }
    }

    private void bindSkins(Element descriptor, PluginModule module) {
        Element skins = descriptor.element("skins");
        if (skins != null) bindSkin(skins, module);
    }

    private void bindSkin(Element descriptor, PluginModule module) {
        List<Element> skins = descriptor.elements("skin");
        if (skins.size() > 0) {
            String[] skinNames = new String[skins.size()];
            for (int i = 0; i < skins.size(); i++)
                skinNames[i] = skins.get(i).attributeValue("name");
            module.setSkins(skinNames);
        }
    }

    private void bindMacroApplicableTo(Element descriptor, MacroPluginModule module) {
        Element applicableTo = descriptor.element("applicable-to");
        if (applicableTo != null) {
            boolean header = Boolean.parseBoolean(applicableTo.attributeValue("header"));
            boolean content = Boolean.parseBoolean(applicableTo.attributeValue("content"));
            boolean footer = Boolean.parseBoolean(applicableTo.attributeValue("footer"));
            List<MacroPluginModule.DocumentArea> applicableList = new ArrayList<MacroPluginModule.DocumentArea>();
            if (header) applicableList.add(MacroPluginModule.DocumentArea.HEADER);
            if (content) applicableList.add(MacroPluginModule.DocumentArea.CONTENT);
            if (footer) applicableList.add(MacroPluginModule.DocumentArea.FOOTER);
            MacroPluginModule.DocumentArea[] applicableArray = new MacroPluginModule.DocumentArea[applicableList.size()];
            module.setApplicableTo(applicableList.toArray(applicableArray));
        }
    }

    private void bindMacroRenderOptions(Element descriptor, MacroPluginModule module) {
        Element renderOptions = descriptor.element("render-options");
        if (renderOptions != null) {
            List<MacroPluginModule.RenderOption> renderOptionList =
                        new ArrayList<MacroPluginModule.RenderOption>();
            List<Element> options = renderOptions.elements();
            for (Element option : options) {
                if (option.getName().equals("singleton"))
                    renderOptionList.add(MacroPluginModule.RenderOption.SINGLETON);
            }
            MacroPluginModule.RenderOption[] renderOptionArray =
                    new MacroPluginModule.RenderOption[renderOptionList.size()];
            module.setRenderOptions(renderOptionList.toArray(renderOptionArray));
        }

    }

    private void bindMacroParameters(PluginRegistry registry) {
        // Iterate through all @Preference entities, look for instanceType() values (which are fully qualified macro keys)
        Set<PreferenceEntity> entitiesWithInstanceProperties =
                preferenceRegistry.getPreferenceEntities(PreferenceVisibility.INSTANCE);
        for (PreferenceEntity entity : entitiesWithInstanceProperties) {
            if (entity.getMappedTo() != null && entity.getMappedTo().length() > 0) {
                // All INSTANCE properties of this entity are for one macro, ignore whatever is configured on the properties
                String macroPluginKey = entity.getMappedTo();
                MacroPluginModule macroPluginModule = registry.getMacroPluginModulesByKey().get(macroPluginKey);
                if (macroPluginModule != null) {
                    log.debug("binding all INSTANCE properties as parameters of macro '" + macroPluginModule.getName() +"': " + entity);
                    macroPluginModule.setPreferenceEntity(entity);
                } else {
                    throw new InvalidWikiConfigurationException(
                        "Configured mapping to macro module '"+macroPluginKey+"' not found for " + entity
                    );
                }
            } else {
                // Some INSTANCE properties are for one macro, others for other macros, so we need to mix and match
                for (PreferenceEntity.Property property : entity.getPropertiesInstanceVisible()) {
                    if (property.getMappedTo() == null || property.getMappedTo().length() == 0) continue;
                   
                    String macroPluginKey = property.getMappedTo();
                    MacroPluginModule macroPluginModule = registry.getMacroPluginModulesByKey().get(macroPluginKey);
                    if (macroPluginModule != null) {
                        log.debug("binding INSTANCE property as parameter of macro '" + macroPluginModule.getName() +"': " + property);
                        macroPluginModule.setPreferenceEntity(entity);
                        macroPluginModule.getParameters().add(property);
                    } else {
                        throw new InvalidWikiConfigurationException(
                            "Configured mapping to macro module  '"+macroPluginKey+"' not found for " + property + " in " + entity
                        );
                    }
                }
            }
        }
    }

    private String getMessage(String key) {
        String message = messages.get(key);
        if (message.equals(key)) {
            throw new InvalidWikiConfigurationException("Could not find message key for label/description: " + key);
        }
        return message;
    }

}
TOP

Related Classes of org.jboss.seam.wiki.core.plugin.binding.lacewiki.PluginBinder

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.