package org.bifrost.xmlio.config;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.bifrost.xmlio.XmlException;
import org.bifrost.xmlio.XmlReader;
import org.bifrost.xmlio.impl.DefaultConverter;
import org.bifrost.xmlio.impl.ObjectFactory;
/**
* <p>Boundary class that allows for overall XmlIO configuration.</p>
* <p>
* Created: Oct 15, 2003<br/>
* Copyright: Copyright (c) 2004<br/>
* Assumptions: none<br/>
* Requires: nothing<br/>
* Required by: nothing<br/>
* Revision History:<br/>
* <br/>
* </p>
* <p>Example:</p>
* <pre>
* </pre>
* <p>Conventions:<br/>
* <ul>
* </ul>
* </p>
* @author Donald Kittle <donald@bifrost.org> (last commit: $Author: donald $)
* @version 1.0 (revision $Revision: 1.12 $)
* @stereotype Boundary
*/
public class XmlIOConfig
{
private final static String _VERSION =
"$Id: XmlIOConfig.java,v 1.12 2005/02/28 18:17:15 donald Exp $";
private static XmlIOConfig instance;
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Data type converters
*/
private Map converterMap = new HashMap();
/**
* Object mappings
*/
private Map objectAliasMap = new HashMap();
private Map objectNameMap = new HashMap();
/**
* Property mappings
*/
private Map propertyAliasMap = new HashMap();
private Map propertyNameMap = new HashMap();
/**
* Namespace mappings
*/
private Map namespaceUriMap = new HashMap();
private Map namespacePackageMap = new HashMap();
/**
* The implementation name of the object factory.
*/
private String objectFactoryImpl = ObjectFactory.class.getName();
/**
* An instance of the default ObjectFactory
*/
private ObjectFactory defaultObjectFactory = new ObjectFactory();
/**
* The current instance of the ObjectFactory
*/
private ObjectFactory objectFactory = new ObjectFactory();
public XmlIOConfig()
{
init();
} // end Constructor()
public static XmlIOConfig getInstance()
{
if (instance == null)
createInstance();
return instance;
}
private static synchronized void createInstance()
{
instance = new XmlIOConfig();
}
private void init()
{
objectAliasMap = new HashMap();
objectNameMap = new HashMap();
converterMap = new HashMap();
propertyAliasMap = new HashMap();
propertyNameMap = new HashMap();
List props = new LinkedList();
props.add(new PropertyMap("object", "ObjectMap"));
addObjectMap(new ObjectMap("config", "XmlIOConfig", props));
props = new LinkedList();
props.add(new PropertyMap("name", "name"));
props.add(new PropertyMap("xmlname", "xmlName"));
props.add(new PropertyMap("property", "PropertyMap"));
addObjectMap(new ObjectMap("object", "ObjectMap", props));
props = new LinkedList();
props.add(new PropertyMap("name", "propertyName"));
props.add(new PropertyMap("xmlname", "propertyXmlName"));
props.add(new PropertyMap("attribute", "writeAsAttribute"));
props.add(new PropertyMap("converter", "converter"));
addObjectMap(new ObjectMap("property", "PropertyMap", props));
String defaultConverterName = DefaultConverter.class.getName();
// Add all default converters for primatives
addConverter(new Converter("boolean", defaultConverterName,
"parseBooleanPrimative", "printBooleanPrimative"));
addConverter(new Converter("byte", defaultConverterName,
"parseBytePrimative", "printBytePrimative"));
addConverter(new Converter("char", defaultConverterName,
"parseCharPrimative", "printCharPrimative"));
addConverter(new Converter("double", defaultConverterName,
"parseDoublePrimative", "printDoublePrimative"));
addConverter(new Converter("float", defaultConverterName,
"parseFloatPrimative", "printFloatPrimative"));
addConverter(new Converter("int", defaultConverterName,
"parseIntegerPrimative", "printIntegerPrimative"));
addConverter(new Converter("long", defaultConverterName,
"parseLongPrimative", "printLongPrimative"));
addConverter(new Converter("short", defaultConverterName,
"parseShortPrimative", "printShortPrimative"));
// Add all default converters for objects
addConverter(new Converter(Boolean.class.getName(),
defaultConverterName, "parseBoolean", "printBoolean"));
addConverter(new Converter(Byte.class.getName(),
defaultConverterName, "parseByte", "printByte"));
addConverter(new Converter(Double.class.getName(),
defaultConverterName, "parseDouble", "printDouble"));
addConverter(new Converter(Character.class.getName(),
defaultConverterName, "parseChar", "printChar"));
addConverter(new Converter(Float.class.getName(),
defaultConverterName, "parseFloat", "printFloat"));
addConverter(new Converter(Integer.class.getName(),
defaultConverterName, "parseInteger", "printInteger"));
addConverter(new Converter(Long.class.getName(),
defaultConverterName, "parseLong", "printLong"));
addConverter(new Converter(Short.class.getName(),
defaultConverterName, "parseShort", "printShort"));
addConverter(new Converter(String.class.getName(),
defaultConverterName, "parseString", "printString"));
addConverter(new Converter(Date.class.getName(),
DateConverter.class.getName(),
"parseDate", "printDate"));
addConverter(new Converter(Timestamp.class.getName(),
TimestampConverter.class.getName(),
"parseTimestamp", "printTimestamp"));
addConverter(new Converter(Calendar.class.getName(),
CalendarConverter.class.getName(),
"parseCalendar", "printCalendar"));
addConverter(new Converter(GregorianCalendar.class.getName(),
GregorianCalendarConverter.class.getName(),
"parseCalendar", "printCalendar"));
}
public void reset()
{
init();
}
public Map getNamespaceMap()
{
return namespaceUriMap;
}
public void setNamespaceUriMap(Map mappings)
{
this.namespaceUriMap = mappings;
}
public void addNamespaceMap(String urn, String classname)
{
NamespaceMap map = new NamespaceMap();
namespaceUriMap.put(urn, classname);
}
public void addNamespaceMap(NamespaceMap map)
{
if (map == null)
return;
if (map.getUri() != null)
namespaceUriMap.put(map.getUri(), map);
if (map.getPackageName() != null)
namespaceUriMap.put(map.getPackageName(), map);
}
public NamespaceMap getNamespaceMapByUri(String uri)
{
if (uri == null)
return null;
return (NamespaceMap)namespaceUriMap.get(uri);
}
public NamespaceMap getNamespaceMapByPackageName(String name)
{
if (name == null)
return null;
return (NamespaceMap)namespacePackageMap.get(name);
}
public PropertyMap getPropertyMapByAlias(String alias)
{
if (alias == null)
return null;
return (PropertyMap)propertyAliasMap.get(alias);
}
public PropertyMap getPropertyMapByName(String name)
{
if (name == null)
return null;
return (PropertyMap)propertyNameMap.get(name);
}
public ObjectMap getObjectMapByAlias(String alias)
{
if (alias == null)
return null;
return (ObjectMap)objectAliasMap.get(alias);
}
public ObjectMap getObjectMapByName(String name)
{
if (name == null)
return null;
return (ObjectMap)objectNameMap.get(name);
}
public void addPropertyMap(PropertyMap map)
{
if (map != null)
{
if (map.getPropertyXmlName() != null)
propertyAliasMap.put(map.getPropertyXmlName(), map);
if (map.getPropertyName() != null)
propertyNameMap.put(map.getPropertyName(), map);
}
} // end addPropertyMap()
public void load(String filename) throws XmlException
{
InputStream io = null;
try
{
io = new FileInputStream(filename);
}
catch (FileNotFoundException fnfe)
{
try
{
io = new FileInputStream("/" + filename);
}
catch (FileNotFoundException fnfe2)
{
io = this.getClass().getResourceAsStream(filename);
if (io == null)
io = this.getClass().getResourceAsStream("/" + filename);
if (io == null)
instance.logger.info("Cannot find " + filename + " configuration file.");
}
}
if (io == null)
throw new XmlException();
instance.logger.config("Reading " + filename);
load(io);
logger.config("Initial configuration read from " + filename);
} // end load()
public void load(InputStream io) throws XmlException
{
if (io == null)
throw new XmlException();
XmlReader reader = new XmlReader(io, "org.bifrost.xmlio.config");
XmlIOConfig conf = (XmlIOConfig)reader.getRootObject();
copyFrom(conf);
} // end load()
public void copyFrom(XmlIOConfig conf)
{
if (conf == null)
return;
// Copy all the object objectAliasMap read into the current instance
int count = 0;
if (conf.objectAliasMap != null)
{
Set keys = conf.objectAliasMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext();)
{
String key = (String)i.next();
ObjectMap map = (ObjectMap)conf.objectAliasMap.get(key);
if (map.getXmlName() != null)
{
objectAliasMap.put(map.getXmlName(), map);
count++;
}
} // end loop through all object objectAliasMap
logger.config(count + " object alias mappings loaded.");
} // end there were some object objectAliasMap
// Copy all the object objectNameMap read into the current instance
count = 0;
if (conf.objectNameMap != null)
{
Set keys = conf.objectNameMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext();)
{
String key = (String)i.next();
ObjectMap map = (ObjectMap)conf.objectNameMap.get(key);
if (map.getName() != null)
{
objectNameMap.put(map.getName(), map);
count++;
}
} // end loop through all object objectNameMap
logger.config(count + " object name mappings loaded.");
} // end there were some object objectNameMap
// Copy all the object propertyAliasMap read into the current instance
count = 0;
if (conf.propertyAliasMap != null)
{
Set keys = conf.propertyAliasMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext();)
{
PropertyMap map = (PropertyMap)i.next();
if (map.getPropertyXmlName() != null)
{
propertyAliasMap.put(map.getPropertyXmlName(), map);
count++;
}
} // end loop through all propertyAliasMap
logger.config(count + " property alias mappings loaded.");
} // end there were some propertyAliasMap
// Copy all the propertyNameMap read into the current instance
count = 0;
if (conf.propertyNameMap != null)
{
Set keys = conf.propertyNameMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext();)
{
PropertyMap map = (PropertyMap)i.next();
if (map.getPropertyName() != null)
{
propertyNameMap.put(map.getPropertyName(), map);
count++;
}
} // end loop through all propertyNameMap
logger.config(count + " property name mappings loaded.");
} // end there were some object objectNameMap
// Copy all the converters info the current instance
count = 0;
if (converterMap != null)
{
Set keys = conf.converterMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext();)
{
String key = (String)i.next();
Converter conv = (Converter)conf.converterMap.get(key);
addConverter(conv);
count++;
} // end loop through all object objectAliasMap
logger.config(count + " type converters loaded.");
}
}
public List getObjectMap()
{
List result = new ArrayList();
Set keys = objectAliasMap.keySet();
for(Iterator i = keys.iterator(); i.hasNext();)
{
String key = (String)i.next();
result.add(objectAliasMap.get(key));
}
return result;
} // end getObjectMap()
public void addObjectMap(ObjectMap map)
{
if (map == null)
return;
if (map.getXmlName() != null)
objectAliasMap.put(map.getXmlName(), map);
if (map.getName() != null)
objectNameMap.put(map.getName(), map);
} // end addObjectMap()
public ObjectMap getMappedObject(String alias)
{
if(objectAliasMap == null)
return null;
return (ObjectMap)objectAliasMap.get(alias);
}
public ObjectMap addClassAsMappedObject(Class theClass)
{
if (theClass == null || objectAliasMap == null)
return null;
ObjectMap om = ObjectMap.createFromClass(theClass);
if (om == null || om.getXmlName() == null)
return null;
objectAliasMap.put(om.getXmlName(), om);
return om;
}
/**
* Get a list of all converters
* @return Returns a List of converters
*/
public List getConverter()
{
List result = new LinkedList();
Set keys = converterMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext();)
{
String key = (String)i.next();
Converter conv = (Converter)converterMap.get(key);
result.add(conv);
} // end loop through all object objectAliasMap
return result;
} // end getConverter()
/**
* Add a new converter
* @param converter The converter to set.
*/
public void addConverter(Converter converter)
{
if (converter.getType() != null)
this.converterMap.put(converter.getType(), converter);
} // end setConverter()
/**
* Get a convert for a specific object type
* @param type the object type
* @return a converter for that specific type or null if there is none
*/
public Converter getConverter(String type)
{
return (Converter)converterMap.get(type);
} // end getConverter()
/**
* Change the implementation of the object factory. The new class must
* extend the default ObjectFactory or it will not be used.
* @param implementationName the fully qualified class name of the new
* object factory implementation.
*/
public void setObjectFactory(String implementationName)
{
if (defaultObjectFactory == null)
return;
Object factory = defaultObjectFactory.getInstance(implementationName);
if (factory == null)
return;
if (factory instanceof ObjectFactory)
objectFactory = (ObjectFactory)factory;
} // end setObjectFactory()
/**
* Gets the current object factory instance.
* @return ObjectFactory the current object factory instance
*/
public ObjectFactory getObjectFactory()
{
return objectFactory;
} // end getObjectFactory()
} // end XmlIOConfig Class