org.oddjob.arooa.deploy.ArooaDescriptorBean Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of arooa Show documentation
Show all versions of arooa Show documentation
A Rip Off Of Ant - A drag and drop component framework.
/*
* (c) Rob Gordon 2006
*/
package org.oddjob.arooa.deploy;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.oddjob.arooa.ArooaBeanDescriptor;
import org.oddjob.arooa.ArooaDescriptor;
import org.oddjob.arooa.ArooaException;
import org.oddjob.arooa.ArooaType;
import org.oddjob.arooa.ClassResolver;
import org.oddjob.arooa.ElementMappings;
import org.oddjob.arooa.beandocs.MappingsContents;
import org.oddjob.arooa.beandocs.MappingsBeanDoc;
import org.oddjob.arooa.convert.ConversionProvider;
import org.oddjob.arooa.convert.ConversionRegistry;
import org.oddjob.arooa.deploy.annotations.ArooaAttribute;
import org.oddjob.arooa.design.DesignFactory;
import org.oddjob.arooa.life.ClassLoaderClassResolver;
import org.oddjob.arooa.life.ElementsForIdentifier;
import org.oddjob.arooa.life.InstantiationContext;
import org.oddjob.arooa.life.SimpleArooaClass;
import org.oddjob.arooa.parsing.ArooaElement;
import org.oddjob.arooa.reflect.ArooaClass;
import org.oddjob.arooa.reflect.PropertyAccessor;
import org.oddjob.arooa.standard.StandardArooaParser;
import org.oddjob.arooa.utils.ClassUtils;
import org.oddjob.arooa.utils.ListSetterHelper;
/**
* A bean style implementation of an {@link ArooaDescriptorFactory}.
* As such it is able to be configured using a {@link StandardArooaParser}.
*
* @oddjob.description A definition of an Arooa descriptor.
*
* @oddjob.example
*
* See the Dev Guide. There is an example of a custom descriptor
* here.
*
* @oddjob.example
*
* The descriptor for the JMX client and server. This is the internal descriptor
* used by Oddjob.
*
* {@oddjob.xml.resource org/oddjob/jmx/jmx.xml}
*
* @author rob
*
*/
public class ArooaDescriptorBean
implements ArooaDescriptorFactory {
/**
* @oddjob.property
* @oddjob.description The name space that applies to
* all elements defined in definitions.
* @oddjob.required No.
*/
private URI namespace;
/**
* @oddjob.property
* @oddjob.description The default prefix for the name space.
* @oddjob.required Yes if name space is provided.
*/
private String prefix;
/**
* @oddjob.property conversions
* @oddjob.description List of class names that must implement
* the {@link ConversionProvider} interface.
* @oddjob.required No.
*/
private List convertlets =
new ArrayList();
/**
* @oddjob.property
* @oddjob.description A list of {@link BeanDefinition}s for components.
* @oddjob.required No.
*/
private List components =
new ArrayList();
/**
* @oddjob.property
* @oddjob.description A list of {@link BeanDefinition}s for values.
* @oddjob.required No.
*/
private List values =
new ArrayList();
/**
* Setter for conversions.
*
* @param index
* @param convertletProvider
*/
public void setConversions(int index,
String convertletProvider) {
convertlets.add(index, convertletProvider);
}
/**
* Setter for components.
*
* @param components
*/
public void setComponents(int index, BeanDefinition component) {
new ListSetterHelper(this.components).set(index, component);
}
/**
* Setter for values.
*
*
* @param value
*/
public void setValues(int index, BeanDefinition value) {
new ListSetterHelper(this.values).set(index, value);
}
/**
* Internal class to hold mappings.
*
*/
static class Mappings implements ElementMappings {
private final Map mappings =
new LinkedHashMap();
private final Map designs =
new LinkedHashMap();
@Override
public ArooaClass mappingFor(ArooaElement element,
InstantiationContext parentContext) {
SimpleArooaClass identifier = mappings.get(element);
if (identifier == null) {
return null;
}
return identifier;
}
@Override
public DesignFactory designFor(ArooaElement element,
InstantiationContext parentContext) {
return designs.get(element);
}
@Override
public ArooaElement[] elementsFor(
InstantiationContext propertyContext) {
return new ElementsForIdentifier(
mappings).elementsFor(propertyContext);
}
@Override
public MappingsContents getBeanDoc(ArooaType arooaType) {
return new MappingsBeanDoc(mappings);
}
}
private void populateMappings(Mappings mappings,
BeanDefinitions definitions,
Map definitionsMap,
ClassLoader classLoader) {
URI namespace = definitions.getNamespace();
for (BeanDefinition beanDefinition : definitions.getDefinitions()) {
if (beanDefinition.getElement() == null) {
throw new ArooaException("No Element in Class Mappings.");
}
ArooaElement element = new ArooaElement(
namespace,
beanDefinition.getElement());
SimpleArooaClass classIdentifier = null;
try {
Class> theClass = ClassUtils.classFor(
beanDefinition.getClassName(),
classLoader);
classIdentifier = new SimpleArooaClass(theClass);
mappings.mappings.put(element, classIdentifier);
}
catch (ClassNotFoundException e) {
throw new ArooaException("Failed loading class for element " +
element + " class [" + beanDefinition.getClassName() +
"] using class loader [" + classLoader + "]",
e);
}
if (beanDefinition.getDesignFactory() != null) {
try {
mappings.designs.put(element,
(DesignFactory) ClassUtils.classFor(
beanDefinition.getDesignFactory(),
classLoader).newInstance());
}
catch (Exception e) {
throw new ArooaException("Failed loading design class for element " +
element + " class [" + beanDefinition.getClassName() +
"] using class loader [" + classLoader + "]",
e);
}
}
definitionsMap.put(classIdentifier, beanDefinition);
}
}
/*
* (non-Javadoc)
* @see org.oddjob.arooa.deploy.ArooaDescriptorFactory#createDescriptor(java.lang.ClassLoader)
*/
public ArooaDescriptor createDescriptor(final ClassLoader classLoader) {
final Map beanDefinitions =
new HashMap();
final Map beanDescriptors =
new HashMap();
final Mappings componentMappings= new Mappings();
BeanDefinitions components = new BeanDefinitions(
namespace, prefix, this.components);
populateMappings(componentMappings, components,
beanDefinitions,
classLoader);
final Mappings valueMappings = new Mappings();
BeanDefinitions values = new BeanDefinitions(
namespace, prefix, this.values);
populateMappings(valueMappings, values,
beanDefinitions,
classLoader);
return new ArooaDescriptor() {
@Override
public ElementMappings getElementMappings() {
return new MappingsSwitch(componentMappings, valueMappings);
}
@Override
public ArooaBeanDescriptor getBeanDescriptor(
ArooaClass forClass, PropertyAccessor accessor) {
ArooaBeanDescriptor beanDescriptor =
beanDescriptors.get(forClass);
if (beanDescriptor != null) {
return beanDescriptor;
}
BeanDefinition beanDefinition =
beanDefinitions.get(forClass);
if (beanDefinition == null) {
return null;
}
beanDescriptor = new SupportedBeanDescriptorProvider(
).getBeanDescriptor(
forClass, accessor);
if (beanDescriptor instanceof PropertyDefinitionsHelper) {
((PropertyDefinitionsHelper)
beanDescriptor).mergeFromBeanDefinition(
beanDefinition);
}
beanDescriptors.put(forClass, beanDescriptor);
return beanDescriptor;
}
@Override
public ConversionProvider getConvertletProvider() {
return new ConversionProvider() {
public void registerWith(ConversionRegistry registry) {
for (String className: convertlets) {
if (className == null) {
continue;
}
ConversionProvider convertletProvider = (ConversionProvider)
ClassUtils.instantiate(className, classLoader);
convertletProvider.registerWith(registry);
}
}
};
}
@Override
public String getPrefixFor(URI namespace) {
if (namespace == null) {
return null;
}
if (namespace.equals(getNamespace())) {
return getPrefix();
}
return null;
}
@Override
public ClassResolver getClassResolver() {
return new ClassLoaderClassResolver(classLoader);
}
};
}
public URI getNamespace() {
return namespace;
}
@ArooaAttribute
public void setNamespace(URI namespace) {
this.namespace = namespace;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}