package org.etk.kernel.container.xml;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.etk.common.logging.Logger;
import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
/**
* Define the rule for root element which is configured in the binding.xml.
* JIBX library base on the binding.xml file for mapping to the Java Object.
*
* Example: The content which configures in the binding.xml
*
* <!-- configuration object mapping -->
<mapping name="configuration" class="org.etk.kernel.core.container.xml.Configuration">
<collection item-type="org.etk.kernel.core.container.xml.ContainerLifecyclePlugin" usage="optional"
add-method="addContainerLifecyclePlugin" iter-method="getContainerLifecyclePluginIterator"
test-method="hasContainerLifecyclePlugin"/>
<collection item-type="org.etk.kernel.core.container.xml.ComponentLifecyclePlugin" usage="optional"
add-method="addComponentLifecyclePlugin" iter-method="getComponentLifecyclePluginIterator"
test-method="hasComponentLifecyclePlugin"/>
<collection item-type="org.etk.kernel.core.container.xml.Component" usage="optional"
add-method="addComponent" iter-method="getComponentIterator"
test-method="hasComponent"/>
<collection item-type="org.etk.kernel.core.container.xml.ExternalComponentPlugins" usage="optional"
add-method="addExternalComponentPlugins" iter-method="getExternalComponentPluginsIterator"
test-method="hasExternalComponentPlugins"/>
<collection item-type="java.lang.String" field="imports_" usage="optional">
<value name="import" style="element"/>
</collection>
<collection item-type="java.lang.String" field="removeConfiguration_" usage="optional">
<value name="remove-configuration" style="element"/>
</collection>
</mapping>
*
*
* @author thanh_vucong
*
*/
public class Configuration implements Cloneable {
private static final Logger log = Logger.getLogger(Configuration.class);
public static final String KERNEL_CONFIGURATION_1_0_URI = "http://www.exoplaform.org/xml/ns/kernel_1_0.xsd";
private Map<String, ContainerLifecyclePlugin> containerLifecyclePlugin = new HashMap<String, ContainerLifecyclePlugin>();
private Map<String, ComponentLifecyclePlugin> componentLifecyclePlugin = new HashMap<String, ComponentLifecyclePlugin>();
private Map<String, Component> component = new HashMap<String, Component>();
private Map<String, ExternalComponentPlugins> externalComponentPlugins = new HashMap<String, ExternalComponentPlugins>();
private ArrayList<String> imports;
private ArrayList<String> removeConfiguration_;
public Collection<ContainerLifecyclePlugin> getContainerLifecyclePlugins() {
List<ContainerLifecyclePlugin> plugins = new ArrayList<ContainerLifecyclePlugin>(this.containerLifecyclePlugin.values());
Collections.sort(plugins);
return plugins;
}
/**
* <collection item-type="org.etk.kernel.core.container.xml.ContainerLifecyclePlugin" usage="optional"
* add-method="addContainerLifecyclePlugin" iter-method="getContainerLifecyclePluginIterator"
* test-method="hasContainerLifecyclePlugin"/>
*
* @param object Type of org.etk.kernel.core.container.xml.ContainerLifecyclePlugin
*/
public void addContainerLifecyclePlugin(Object object) {
ContainerLifecyclePlugin plugin = (ContainerLifecyclePlugin) object;
String key = plugin.getType();
this.containerLifecyclePlugin.put(key, plugin);
}
/**
* Retrieving the ContainerLifecyclePlugin().getItrator
* @return
*/
public Iterator<ContainerLifecyclePlugin> getContainerLifecyclePluginIterator() {
return getContainerLifecyclePlugins().iterator();
}
/**
* Determines the containerLifecyclePlugin has size > 0.
*
* @return containerLifecyclePlugin
*/
public boolean hasContainerLifecyclePlugin() {
return this.containerLifecyclePlugin.size() > 0;
}
public Collection getComponentLifecyclePlugins() {
return this.componentLifecyclePlugin.values();
}
/**
* This method shows you how to configure for xml mapping.
* <collection item-type="org.etk.kernel.core.container.xml.ComponentLifecyclePlugin" usage="optional"
add-method="addComponentLifecyclePlugin" iter-method="getComponentLifecyclePluginIterator"
test-method="hasComponentLifecyclePlugin"/>
* @param object
*/
public void addComponentLifecyclePlugin(Object object) {
ComponentLifecyclePlugin plugin = (ComponentLifecyclePlugin) object;
String key = plugin.getClass().getName();
this.componentLifecyclePlugin.put(key, plugin);
}
public Iterator getComponentLifecyclePluginIterator() {
return this.componentLifecyclePlugin.values().iterator();
}
public boolean hasComponentLifecyclePlugin() {
return this.componentLifecyclePlugin.size() > 0;
}
public Component getComponent(String s) {
return component.get(s);
}
/**
* <collection item-type="org.etk.kernel.core.container.xml.Component" usage="optional"
* add-method="addComponent" iter-method="getComponentIterator"
* test-method="hasComponent"/>
*
* @param object
*/
public void addComponent(Object object) {
Component comp = (Component) object;
String key = comp.getKey();
if (key == null) {
key = comp.getType();
comp.setKey(key);
}
component.put(key, comp);
}
/**
*
* @return
*/
public Collection getComponents() {
return component.values();
}
/**
* Provides to the binding mechanism to get element via iterator.
*
* @return Iterator in the Component collection.
*/
public Iterator getComponentIterator() {
return component.values().iterator();
}
/**
* Provides the method to binding.xml configuration.
* test-method="hasComponent"
*
* @return
*/
public boolean hasComponent() {
return component.size() > 0;
}
public ExternalComponentPlugins getExternalComponentPlugins(String s) {
return externalComponentPlugins.get(s);
}
public void addExternalComponentPlugins(Object o) {
if (o instanceof ExternalComponentPlugins) {
ExternalComponentPlugins eps = (ExternalComponentPlugins) o;
// Retrieve potential existing external component
// plugins with same target component.
String targetComponent = eps.getTargetComponent();
ExternalComponentPlugins foundExternalComponentPlugins = (ExternalComponentPlugins) externalComponentPlugins.get(targetComponent);
if (foundExternalComponentPlugins == null) {
// No external component plugins found. Create a new entry.
externalComponentPlugins.put(targetComponent, eps);
} else {
// Found external component plugins. Add the specified one.
foundExternalComponentPlugins.merge(eps);
}
}
}
public Iterator getExternalComponentPluginsIterator() {
return externalComponentPlugins.values().iterator();
}
public boolean hasExternalComponentPlugins() {
return externalComponentPlugins.size() > 0;
}
public void addImport(String url) {
if (imports == null)
imports = new ArrayList<String>();
imports.add(url);
}
public List getImports() {
return imports;
}
public void addRemoveConfiguration(String type) {
if (removeConfiguration_ == null)
removeConfiguration_ = new ArrayList<String>();
removeConfiguration_.add(type);
}
public List getRemoveConfiguration() {
return removeConfiguration_;
}
public void removeConfiguration(String type) {
component.remove(type);
}
// -------------------------end new mapping configuration--------------------
/**
* Put all of the component, containerLifecyclePlugin, and componentLifecyclePlugin
* from other which was contained in other(different Configuration)
* to the current(Configuration).
*/
public void mergeConfiguration(Configuration other) {
component.putAll(other.component);
this.componentLifecyclePlugin.putAll(other.componentLifecyclePlugin);
this.containerLifecyclePlugin.putAll(other.containerLifecyclePlugin);
// merge the external plugins
Iterator i = other.externalComponentPlugins.values().iterator();
while (i.hasNext()) {
addExternalComponentPlugins(i.next());
}
if (other.getRemoveConfiguration() == null)
return;
if (removeConfiguration_ == null)
removeConfiguration_ = new ArrayList<String>();
removeConfiguration_.addAll(other.getRemoveConfiguration());
}
/**
* Merge all the given configurations and return a safe copy of the result
*
* @param configs the list of configurations to merge ordered by priority, the
* second configuration will override the configuration of the first
* one and so on.
* @return the merged configuration
*/
public static Configuration merge(Configuration... configs) {
if (configs == null || configs.length == 0) {
return null;
}
Configuration result = null;
for (Configuration conf : configs) {
if (conf == null) {
// Ignore the null configuration
continue;
} else if (result == null) {
try {
// Initialize with the clone of the first non null configuration
result = (Configuration) conf.clone();
} catch (CloneNotSupportedException e) {
log.warn("Could not clone the configuration", e);
break;
}
} else {
// The merge the current configuration with this new configuration
result.mergeConfiguration(conf);
}
}
return result;
}
/**
* Dumps the configuration in XML format into the given {@link Writer}
*/
public void toXML(Writer w) {
try {
IBindingFactory bfact = BindingDirectory.getFactory(Configuration.class);
IMarshallingContext mctx = bfact.createMarshallingContext();
mctx.setIndent(2);
mctx.marshalDocument(this, "UTF-8", null, w);
} catch (Exception e) {
log.warn("Couldn't dump the runtime configuration in XML Format", e);
}
}
/**
* Dumps the configuration in XML format into a {@link StringWriter} and
* returns the content
*/
public String toXML() {
StringWriter sw = new StringWriter();
try {
toXML(sw);
} catch (Exception e) {
log.warn("Cannot convert the configuration to XML format", e);
return null;
} finally {
try {
sw.close();
} catch (IOException ignore) {
}
}
return sw.toString();
}
}