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 List<ClassDescriptor> _descriptors = new Vector<ClassDescriptor>();
28  
29      /** 
30       * All class descriptors added so far, keyed by class name. 
31       */
32      private 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()
60       * {@inheritDoc}
61       */
62      public final ClassLoader getClassLoader() {
63          return _loader;
64      }
65  
66      /**
67       * Enables or disables the ability to allow the redefinition of class mappings.
68       * 
69       * @param allow A boolean that when true enables redefinitions.
70       */
71      public final void setAllowRedefinitions(boolean allow) {
72          _allowRedefinitions = allow;
73      }
74      
75      /**
76       * Is the ability to allow redefinitions enabled or disabled?
77       * 
78       * @return A boolean that when true enables redefinitions.
79       */
80      public final boolean isAllowRedefinition() {
81          return _allowRedefinitions;
82      }
83  
84      /**
85       * Adds a class descriptor. Will throw a mapping exception if a descriptor for this class
86       * already exists.
87       *
88       * @param descriptor The descriptor to add.
89       * @throws MappingException A descriptor for this class already exists.
90       */
91      protected final void addDescriptor(final ClassDescriptor descriptor)
92      throws MappingException {
93          String classname = descriptor.getJavaClass().getName();
94          if (_descriptorsByClassname.containsKey(classname)) {
95              if (!isAllowRedefinition()) {
96                  throw new MappingException("mapping.duplicateDescriptors", classname);
97              }
98              for (Iterator<ClassDescriptor> iterator = _descriptors.iterator(); iterator.hasNext(); ) {
99                  ClassDescriptor d = iterator.next();
100                 if (classname.equals(d.getJavaClass().getName())) {
101                     iterator.remove();
102                 }
103             }
104             _descriptors.add(descriptor);
105         } else {
106             _descriptors.add(descriptor);
107         }
108         
109         //-- if we make it here...add class
110         _descriptorsByClassname.put(classname, descriptor);
111     }
112 
113     /**
114      * @see org.exolab.castor.mapping.MappingLoader#getDescriptor(java.lang.String)
115      * {@inheritDoc}
116      */
117     public final ClassDescriptor getDescriptor(final String classname) {
118         if (classname == null) { return null; }
119         return _descriptorsByClassname.get(classname);
120     }
121 
122 //    /**
123 //     * @see org.exolab.castor.mapping.MappingLoader#descriptorIterator()
124 //     * {@inheritDoc}
125 //     */
126 //    public final Iterator<ClassDescriptor> descriptorIterator() {
127 //        return _descriptors.iterator();
128 //    }
129 
130     public final List<ClassDescriptor> getDescriptors() {
131         return _descriptors;
132     }
133     
134     /**
135      * Return if mapping should be loaded with this MappingLoader instance or if another
136      * mapping have been loaded previously. If no mapping have been loaded previously
137      * then prevent any other mapping to be loaded later on.
138      * 
139      * @return <code>true</code> if mapping should be loaded, <code>false</code>
140      *         otherwise.
141      */
142     protected final boolean loadMapping() {
143         if (_loaded) { return false; }
144         _loaded = true;
145         return true;
146     }
147     
148 }