Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2010-2011 Kevin Seim
*
* 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.beanio.config;
import java.beans.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.regex.PatternSyntaxException;
import org.beanio.BeanIOConfigurationException;
import org.beanio.parser.*;
import org.beanio.stream.*;
import org.beanio.types.*;
import org.beanio.util.*;
/**
* A StreamDefinitionFactory is used to convert a stream configuration into a
* StreamDefinition for parsing an I/O stream.
*
* @author Kevin Seim
* @since 1.0
*/
public abstract class StreamDefinitionFactory {
private TypeHandlerFactory typeHandlerFactory;
private boolean readEnabled = true;
private boolean writeEnabled = true;
/**
* Constructs a new StreamDefinitionFactory.
*/
public StreamDefinitionFactory() { }
/**
* Creates a new stream definition based on a stream configuration.
* @param config the stream configuration
* @return the new StreamDefinition
* @throws BeanIOConfigurationException if the configuration is invalid
*/
public StreamDefinition createStreamDefinition(StreamConfig config) throws BeanIOConfigurationException {
if (config.getName() == null) {
throw new BeanIOConfigurationException("stream name not configured");
}
try {
StreamDefinition definition = newStreamDefinition(config);
compileStreamDefinition(config, definition);
return definition;
}
catch (BeanIOConfigurationException ex) {
throw new BeanIOConfigurationException("Invalid '" + config.getName() +
"' stream configuration: " + ex.getMessage(), ex);
}
}
/**
* Compiles a stream definition from its configuration.
* @param config the stream configuration
* @param definition the stream definition to compile
* @throws BeanIOConfigurationException if the configuration is invalid
*/
protected void compileStreamDefinition(StreamConfig config, StreamDefinition definition)
throws BeanIOConfigurationException {
// set the stream mode, defaults to read/write, the stream mode may be used
// to enforce or relax validation rules specific to marshalling or unmarshalling
String mode = config.getMode();
if (mode == null || StreamConfig.READ_WRITE_MODE.equals(mode)) {
definition.setMode(StreamDefinition.READ_WRITE_MODE);
}
else if (StreamConfig.READ_ONLY_MODE.equals(mode)) {
definition.setMode(StreamDefinition.READ_ONLY_MODE);
writeEnabled = false;
}
else if (StreamConfig.WRITE_ONLY_MODE.equals(mode)) {
definition.setMode(StreamDefinition.WRITE_ONLY_MODE);
readEnabled = false;
}
else {
throw new BeanIOConfigurationException("Invalid mode '" + mode + "'");
}
definition.setName(config.getName());
definition.setMinOccurs(config.getRootGroupConfig().getMinOccurs());
definition.setMaxOccurs(config.getRootGroupConfig().getMaxOccurs());
// configure the record reader factory
Bean readerFactoryBean = config.getReaderFactory();
if (readerFactoryBean != null) {
RecordReaderFactory factory;
if (readerFactoryBean.getClassName() == null) {
factory = newRecordReaderFactory();
}
else {
Object object = BeanUtil.createBean(readerFactoryBean.getClassName());
if (!RecordReaderFactory.class.isAssignableFrom(object.getClass())) {
throw new BeanIOConfigurationException("Configured reader factory class '" +
readerFactoryBean.getClassName() + "' does not implement RecordReaderFactory");
}
factory = (RecordReaderFactory) object;
}
BeanUtil.configure(factory, readerFactoryBean.getProperties());
definition.setReaderFactory(factory);
}
// configure the record writer factory
Bean writerFactoryBean = config.getWriterFactory();
if (writerFactoryBean != null) {
RecordWriterFactory factory;
if (writerFactoryBean.getClassName() == null) {
factory = newRecordWriterFactory();
}
else {
Object object = BeanUtil.createBean(writerFactoryBean.getClassName());
if (!RecordWriterFactory.class.isAssignableFrom(object.getClass())) {
throw new BeanIOConfigurationException("Configured writer factory class '" +
writerFactoryBean.getClassName() + "' does not implement RecordWriterFactory");
}
factory = (RecordWriterFactory) object;
}
BeanUtil.configure(factory, writerFactoryBean.getProperties());
definition.setWriterFactory(factory);
}
// load the stream's default resource bundle
String bundleName = Settings.getInstance().getProperty(
"org.beanio." + definition.getFormat() + ".messages");
if (bundleName != null) {
try {
definition.setDefaultResourceBundle(ResourceBundle.getBundle(bundleName));
}
catch (MissingResourceException ex) {
throw new BeanIOConfigurationException("Missing default resource bundle '" +
bundleName + "' for stream format '" + definition.getFormat() + "'", ex);
}
}
// load the stream resource bundle
bundleName = config.getResourceBundle();
if (bundleName != null) {
try {
definition.setResourceBundle(ResourceBundle.getBundle(bundleName));
}
catch (MissingResourceException ex) {
throw new BeanIOConfigurationException("Missing resource bundle '" +
bundleName + "'", ex);
}
}
updateStreamDefinition(config, definition);
updateGroupDefinition(null, config.getRootGroupConfig(), definition.getRootGroupDefinition());
compileGroupDefinition(config, config.getRootGroupConfig(), definition.getRootGroupDefinition());
}
/**
* This method is called by compileStreamDefinition to allow the configuration
* of stream specific stream configuration settings.
* @param config the stream configuration
* @param definition the stream definition
* @since 1.1
*/
protected void updateStreamDefinition(StreamConfig config, StreamDefinition definition) { }
/**
* Compiles a group definition from its configuration.
* @param streamConfig the parent stream configuration
* @param groupConfig the group configuration
* @param definition the group definition to compile
*/
protected final void compileGroupDefinition(StreamConfig streamConfig, GroupConfig groupConfig,
GroupDefinition definition) {
List nodeList = groupConfig.getChildren();
if (nodeList.isEmpty()) {
throw new BeanIOConfigurationException("At least one record or record group is required.");
}
// by default, order is incremented for each record
int lastOrder = 0;
for (NodeConfig child : nodeList) {
String nodeType = child.getType() == NodeConfig.RECORD ? "record" : "group";
int order;
if (streamConfig.isOrdered()) {
order = child.getOrder();
// defaults the order to the last order plus one
if (order < 1) {
order = lastOrder + 1;
}
// validate all nodes are in order
else if (order < lastOrder) {
throw new BeanIOConfigurationException(
"'" + child.getName() + "' " + nodeType + " configuration is out of order");
}
lastOrder = order;
}
else {
// validate node order isn't set if the stream is unordered
if (child.getOrder() >= 0) {
throw new BeanIOConfigurationException(
"Invalid '" + child.getName() + "' " + nodeType + " configuration: " +
"Order cannot be set when ordered=\"false\"");
}
order = 1;
}
NodeDefinition childDefinition;
switch (child.getType()) {
case NodeConfig.RECORD:
try {
childDefinition = newRecordDefinition((RecordConfig) child);
compileNodeDefinition(child, childDefinition, order);
compileRecordDefinition(definition, (RecordConfig) child, (RecordDefinition) childDefinition);
compileFieldDefinitions((RecordConfig) child, (RecordDefinition) childDefinition);
}
catch (BeanIOConfigurationException ex) {
throw new BeanIOConfigurationException("Invalid '" + child.getName() +
"' record configuration: " + ex.getMessage(), ex);
}
break;
case NodeConfig.GROUP:
try {
childDefinition = newGroupDefinition((GroupConfig) child);
compileNodeDefinition(child, childDefinition, order);
updateGroupDefinition(definition, (GroupConfig) child, (GroupDefinition) childDefinition);
compileGroupDefinition(streamConfig, (GroupConfig) child, (GroupDefinition) childDefinition);
}
catch (BeanIOConfigurationException ex) {
throw new BeanIOConfigurationException("Invalid '" + child.getName() +
"' group configuration: " + ex.getMessage(), ex);
}
break;
default:
throw new IllegalStateException("Invalid node type: " + child.getType());
}
definition.addChild(childDefinition);
}
}
/**
* This method is called by compileGroupDefinition to allow the configuration
* of stream specific group configuration settings.
* @param parent the parent group definition
* @param config the group configuration
* @param definition the group definition
* @since 1.1
*/
protected void updateGroupDefinition(GroupDefinition parent, GroupConfig config, GroupDefinition definition) {
}
private void compileNodeDefinition(NodeConfig config, NodeDefinition definition, int order) {
definition.setName(config.getName());
definition.setOrder(order);
int minOccurs = config.getMinOccurs() != null ? config.getMinOccurs() : 1; // default to 1
definition.setMinOccurs(minOccurs);
int maxOccurs = config.getMaxOccurs() != null ? config.getMaxOccurs() : -1; // default to unbounded
definition.setMaxOccurs(maxOccurs);
if (maxOccurs == 0) {
throw new BeanIOConfigurationException("maxOccurs must be 1 or greater");
}
if (maxOccurs > 0 && maxOccurs < minOccurs) {
throw new BeanIOConfigurationException("maxOccurs cannot be less than minOccurs");
}
}
/**
* Compiles a record definition from its configuration.
* @param config the record configuration
* @param recordDefinition the record definition
*/
protected void compileRecordDefinition(GroupDefinition group, RecordConfig config, RecordDefinition recordDefinition) {
BeanDefinition beanDefinition = newBeanDefinition(config.getBean());
beanDefinition.setName(recordDefinition.getName());
beanDefinition.setPropertyType(getBeanClass(config.getBean()));
beanDefinition.setLazy(false);
updateBeanDefinition(config.getBean(), beanDefinition);
recordDefinition.setBeanDefinition(beanDefinition);
}
/**
* Compiles a bean definition.
* @param config the bean configuration
* @param definition the bean definition to update
*/
protected void compileBeanDefinition(BeanDefinition parent, BeanConfig config, BeanDefinition definition) {
String name = config.getName();
if (name == null) {
throw new BeanIOConfigurationException("Bean name not set");
}
definition.setName(name);
definition.setParent(parent);
try {
// determine and validate the bean class
Class> beanClass = getBeanClass(config);
if (beanClass == null) {
throw new BeanIOConfigurationException("Bean class not set");
}
definition.setProperty(true);
definition.setPropertyType(beanClass);
// determine the collection type
Class extends Collection