001: package org.exolab.castor.mapping.loader;
002:
003: import java.util.Hashtable;
004: import java.util.Iterator;
005: import java.util.List;
006: import java.util.Map;
007: import java.util.Vector;
008:
009: import org.exolab.castor.mapping.ClassDescriptor;
010: import org.exolab.castor.mapping.MappingException;
011: import org.exolab.castor.mapping.MappingLoader;
012:
013: public abstract class AbstractMappingLoader2 implements MappingLoader {
014: //--------------------------------------------------------------------------
015:
016: /** The class loader to use. */
017: private ClassLoader _loader;
018:
019: /** A flag indicating whether or not mappings can be redefined. */
020: private boolean _allowRedefinitions = false;
021:
022: /** Has loadMapping been called? */
023: private boolean _loaded = false;
024:
025: /** All class descriptors in the original order. */
026: private List _descriptors = new Vector();
027:
028: /** All class descriptors added so far, keyed by classname. */
029: private Map _descriptorsByClassname = new Hashtable();
030:
031: //--------------------------------------------------------------------------
032:
033: public AbstractMappingLoader2(final ClassLoader loader) {
034: setClassLoader(loader);
035: }
036:
037: public final void clear() {
038: _allowRedefinitions = false;
039: _loaded = false;
040: _descriptors.clear();
041: _descriptorsByClassname.clear();
042: }
043:
044: //--------------------------------------------------------------------------
045:
046: /**
047: * @see org.exolab.castor.mapping.MappingLoader#setClassLoader(java.lang.ClassLoader)
048: * {@inheritDoc}
049: */
050: public final void setClassLoader(final ClassLoader loader) {
051: if (loader == null) {
052: _loader = getClass().getClassLoader();
053: } else {
054: _loader = loader;
055: }
056: }
057:
058: /**
059: * @see org.exolab.castor.mapping.MappingLoader#getClassLoader()
060: * {@inheritDoc}
061: */
062: public final ClassLoader getClassLoader() {
063: return _loader;
064: }
065:
066: /**
067: * Enables or disables the ability to allow the redefinition of class mappings.
068: *
069: * @param allow A boolean that when true enables redefinitions.
070: */
071: public final void setAllowRedefinitions(boolean allow) {
072: _allowRedefinitions = allow;
073: }
074:
075: /**
076: * Is the ability to allow redefinitions enabled or disabled?
077: *
078: * @return A boolean that when true enables redefinitions.
079: */
080: public final boolean isAllowRedefinition() {
081: return _allowRedefinitions;
082: }
083:
084: //--------------------------------------------------------------------------
085:
086: /**
087: * Adds a class descriptor. Will throw a mapping exception if a descriptor for this class
088: * already exists.
089: *
090: * @param descriptor The descriptor to add.
091: * @throws MappingException A descriptor for this class already exists.
092: */
093: protected final void addDescriptor(final ClassDescriptor descriptor)
094: throws MappingException {
095: String classname = descriptor.getJavaClass().getName();
096: if (_descriptorsByClassname.containsKey(classname)) {
097: if (!isAllowRedefinition()) {
098: throw new MappingException(
099: "mapping.duplicateDescriptors", classname);
100: }
101: } else {
102: _descriptors.add(descriptor);
103: }
104:
105: //-- if we make it here...add class
106: _descriptorsByClassname.put(classname, descriptor);
107: }
108:
109: /**
110: * @see org.exolab.castor.mapping.MappingLoader#getDescriptor(java.lang.String)
111: * {@inheritDoc}
112: */
113: public final ClassDescriptor getDescriptor(final String classname) {
114: if (classname == null) {
115: return null;
116: }
117: return (ClassDescriptor) _descriptorsByClassname.get(classname);
118: }
119:
120: /**
121: * @see org.exolab.castor.mapping.MappingLoader#descriptorIterator()
122: * {@inheritDoc}
123: */
124: public final Iterator descriptorIterator() {
125: return _descriptors.iterator();
126: }
127:
128: //--------------------------------------------------------------------------
129:
130: /**
131: * Return if mapping should be loaded with this MappingLoader instance or if another
132: * mapping have been loaded previously. If no mapping have been loaded previously
133: * then prevent any other mapping to be loaded later on.
134: *
135: * @return <code>true</code> if mapping should be loaded, <code>false</code>
136: * otherwise.
137: */
138: protected final boolean loadMapping() {
139: if (_loaded) {
140: return false;
141: }
142: _loaded = true;
143: return true;
144: }
145:
146: //--------------------------------------------------------------------------
147: }
|