View Javadoc
1   package org.exolab.castor.mapping.loader;
2   
3   import java.util.Hashtable;
4   import java.util.Iterator;
5   import java.util.List;
6   import java.util.Map;
7   import java.util.Vector;
8   
9   import org.exolab.castor.mapping.ClassDescriptor;
10  import org.exolab.castor.mapping.MappingException;
11  import org.exolab.castor.mapping.MappingLoader;
12  
13  public abstract class AbstractMappingLoader2 implements MappingLoader {
14  
15    /** The class loader to use. */
16    private ClassLoader _loader;
17  
18    /** A flag indicating whether or not mappings can be redefined. */
19    private boolean _allowRedefinitions = false;
20  
21    /** Has loadMapping been called? */
22    private boolean _loaded = false;
23  
24    /**
25     * All class descriptors in the original order.
26     */
27    private final List<ClassDescriptor> _descriptors = new Vector<>();
28  
29    /**
30     * All class descriptors added so far, keyed by class name.
31     */
32    private final Map<String, ClassDescriptor> _descriptorsByClassname =
33        new Hashtable<String, ClassDescriptor>();
34  
35    public AbstractMappingLoader2(final ClassLoader loader) {
36      setClassLoader(loader);
37    }
38  
39    public final void clear() {
40      _allowRedefinitions = false;
41      _loaded = false;
42      _descriptors.clear();
43      _descriptorsByClassname.clear();
44    }
45  
46    /**
47     * @see org.exolab.castor.mapping.MappingLoader#setClassLoader(java.lang.ClassLoader)
48     *      {@inheritDoc}
49     */
50    public final void setClassLoader(final ClassLoader loader) {
51      if (loader == null) {
52        _loader = getClass().getClassLoader();
53      } else {
54        _loader = loader;
55      }
56    }
57  
58    /**
59     * @see org.exolab.castor.mapping.MappingLoader#getClassLoader() {@inheritDoc}
60     */
61    public final ClassLoader getClassLoader() {
62      return _loader;
63    }
64  
65    /**
66     * Enables or disables the ability to allow the redefinition of class mappings.
67     * 
68     * @param allow A boolean that when true enables redefinitions.
69     */
70    public final void setAllowRedefinitions(boolean allow) {
71      _allowRedefinitions = allow;
72    }
73  
74    /**
75     * Is the ability to allow redefinitions enabled or disabled?
76     * 
77     * @return A boolean that when true enables redefinitions.
78     */
79    public final boolean isAllowRedefinition() {
80      return _allowRedefinitions;
81    }
82  
83    /**
84     * Adds a class descriptor. Will throw a mapping exception if a descriptor for this class already
85     * exists.
86     *
87     * @param descriptor The descriptor to add.
88     * @throws MappingException A descriptor for this class already exists.
89     */
90    protected final void addDescriptor(final ClassDescriptor descriptor) throws MappingException {
91      String classname = descriptor.getJavaClass().getName();
92      if (_descriptorsByClassname.containsKey(classname)) {
93        if (!isAllowRedefinition()) {
94          throw new MappingException("mapping.duplicateDescriptors", classname);
95        }
96        for (Iterator<ClassDescriptor> iterator = _descriptors.iterator(); iterator.hasNext();) {
97          ClassDescriptor d = iterator.next();
98          if (classname.equals(d.getJavaClass().getName())) {
99            iterator.remove();
100         }
101       }
102       _descriptors.add(descriptor);
103     } else {
104       _descriptors.add(descriptor);
105     }
106 
107     // -- if we make it here...add class
108     _descriptorsByClassname.put(classname, descriptor);
109   }
110 
111   /**
112    * @see org.exolab.castor.mapping.MappingLoader#getDescriptor(java.lang.String) {@inheritDoc}
113    */
114   public final ClassDescriptor getDescriptor(final String classname) {
115     if (classname == null) {
116       return null;
117     }
118     return _descriptorsByClassname.get(classname);
119   }
120 
121   // /**
122   // * @see org.exolab.castor.mapping.MappingLoader#descriptorIterator()
123   // * {@inheritDoc}
124   // */
125   // public final Iterator<ClassDescriptor> descriptorIterator() {
126   // return _descriptors.iterator();
127   // }
128 
129   public final List<ClassDescriptor> getDescriptors() {
130     return _descriptors;
131   }
132 
133   /**
134    * Return if mapping should be loaded with this MappingLoader instance or if another mapping have
135    * been loaded previously. If no mapping have been loaded previously then prevent any other
136    * mapping to be loaded later on.
137    * 
138    * @return <code>true</code> if mapping should be loaded, <code>false</code> otherwise.
139    */
140   protected final boolean loadMapping() {
141     if (_loaded) {
142       return false;
143     }
144     _loaded = true;
145     return true;
146   }
147 
148 }