KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > elementprocessor > impl > AbstractElementProcessorFactory


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.elementprocessor.impl;
17
18 import java.lang.reflect.Constructor JavaDoc;
19 import java.lang.reflect.InvocationTargetException JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.avalon.framework.component.Component;
24 import org.apache.avalon.framework.logger.AbstractLogEnabled;
25
26 import org.apache.cocoon.components.elementprocessor.CannotCreateElementProcessorException;
27 import org.apache.cocoon.components.elementprocessor.ElementProcessor;
28 import org.apache.cocoon.components.elementprocessor.ElementProcessorFactory;
29
30 /**
31  * Create instances of specific ElementProcessor implementations to
32  * handle specific XML elements and their content.
33  *
34  * @author Marc Johnson (marc_johnson27591@hotmail.com)
35  * @version CVS $Id: AbstractElementProcessorFactory.java 30932 2004-07-29 17:35:38Z vgritsenko $
36  */

37 public abstract class AbstractElementProcessorFactory
38      extends AbstractLogEnabled implements ElementProcessorFactory, Component
39 {
40
41     // uses XML element names as keys and ElementProcessor progenitors
42
// as values. An ElementProcessor progenitor is an Object that can
43
// be used to create a new ElementProcessor instance that is
44
// specific to a particular XML element. A progenitor may be a
45
// Constructor or Class that can construct a new instance of an
46
// appropriate ElementProcessor implementation, or any other
47
// Object that an extension of AbstractElementProcessorFactory finds
48
// useful to create new ElementProcessor instances.
49
private Map JavaDoc _element_processor_map;
50
51     /**
52      * Protected default constructor
53      */

54
55     protected AbstractElementProcessorFactory() {
56         _element_processor_map = new HashMap JavaDoc();
57     }
58
59     /**
60      * Given an XML element name, create and return an appropriate
61      * ElementProcessor.
62      *
63      * @param name element name
64      *
65      * @return the specified ElementProcessor
66      *
67      * @exception CannotCreateElementProcessorException if there is no
68      * ElementProcessor available for the specified name
69      */

70
71     public ElementProcessor createElementProcessor(final String JavaDoc name)
72         throws CannotCreateElementProcessorException {
73         Object JavaDoc progenitor = lookupElementProcessorProgenitor(name);
74
75         if (progenitor == null) {
76             CannotCreateElementProcessorException exception =
77                 new CannotCreateElementProcessorException(
78                     "Cannot find progenitor for that name");
79             exception.setElementName(name);
80             throw exception;
81         }
82         ElementProcessor processor = null;
83
84         try {
85             processor = doCreateElementProcessor(progenitor);
86         } catch (CannotCreateElementProcessorException e) {
87             e.setElementName(name);
88             throw e;
89         }
90         return processor;
91     }
92
93     /**
94      * A method for extending classes to populate the map.
95      *
96      * @param name the element name for this progenitor; cannot be
97      * null ot empty
98      * @param progenitor an object that can be used to generate an
99      * appropriate ElementProcessor; cannot be nukk
100      *
101      * @exception IllegalArgumentException if name is already in the
102      * map or progenitor is null.
103      */

104
105     protected void addElementProcessorProgenitor(final String JavaDoc name,
106             final Object JavaDoc progenitor)
107     {
108         if ((name == null) || (name.equals(""))) {
109             throw new IllegalArgumentException JavaDoc(
110                 "Cannot use null or empty name as a key");
111         }
112         if (progenitor == null) {
113             throw new IllegalArgumentException JavaDoc(
114                 "Cannot add null progenitor to the map");
115         }
116         if (_element_processor_map.put(name, progenitor) != null) {
117             throw new IllegalArgumentException JavaDoc(
118                 name + " is already in use in the map");
119         }
120     }
121
122     /**
123      * A method to get the progenitor value associated with a
124      * specified element name.
125      *
126      * @param name the element name
127      *
128      * @return the associated ElementProcessor progenitor; will be
129      * null if the element name has not yet been associated
130      * with a progenitor.
131      */

132
133     protected Object JavaDoc lookupElementProcessorProgenitor(final String JavaDoc name)
134     {
135         Object JavaDoc obj = _element_processor_map.get(name);
136         if (obj == null && !name.equals("*")) {
137             obj = lookupElementProcessorProgenitor("*");
138         }
139         return obj;
140     }
141
142     /**
143      * The method that a concrete extension of AbstractElementProcessorFactory
144      * must implement. When this method is called, the element name
145      * has already been looked up in the map and a progenitor Object
146      * has been acquired. The progenitor is guaranteed not to be null.
147      *
148      * @param progenitor the object from which to create an
149      * ElementProcessor
150      *
151      * @return freshly created ElementProcessor
152      *
153      * @exception CannotCreateElementProcessorException if the
154      * specified ElementProcessor cannot be created.
155      */

156
157     protected abstract ElementProcessor doCreateElementProcessor(
158         final Object JavaDoc progenitor) throws CannotCreateElementProcessorException;
159
160     /**
161      * A reference implementation of doCreateElementProcessor that can
162      * be used by an extending class whose progenitors are Class
163      * objects for ElementProcessor implementations.
164      *
165      * @param progenitor a Class representing an ElementProcessor
166      *
167      * @return the new ElementProcessor instance
168      *
169      * @exception CannotCreateElementProcessorException if the
170      * ElementProcessor cannot be created.
171      */

172
173     protected ElementProcessor createNewElementProcessorInstance(
174             final Class JavaDoc progenitor)
175             throws CannotCreateElementProcessorException {
176         ElementProcessor rval = null;
177
178         try {
179             rval = (ElementProcessor)progenitor.newInstance();
180             if (rval instanceof AbstractLogEnabled) {
181                ((AbstractLogEnabled)rval).enableLogging(getLogger());
182             }
183         } catch (ExceptionInInitializerError JavaDoc e) {
184             throw new CannotCreateElementProcessorException(
185                     "an exception (" + e + ") occurred in initializing the associated ElementProcessor class");
186         } catch (SecurityException JavaDoc e) {
187             throw new CannotCreateElementProcessorException(
188                 "a security exception was caught while creating the associated ElementProcessor");
189         } catch (InstantiationException JavaDoc e) {
190             throw new CannotCreateElementProcessorException(
191                 "associated ElementProcessor is an interface or abstract class or has no zero-parameter constructor");
192         } catch (IllegalAccessException JavaDoc e) {
193             throw new CannotCreateElementProcessorException(
194                 "cannot access ElementProcessor class or its zero-parameter constructor");
195         } catch (ClassCastException JavaDoc e) {
196             throw new CannotCreateElementProcessorException(
197                 "object created does not implement ElementProcessor");
198         } catch (Exception JavaDoc e) {
199             throw new CannotCreateElementProcessorException(
200                 "exception (" + e
201                 + ") occured while creating new instance of ElementProcessor");
202         }
203         if (rval == null) {
204             throw new CannotCreateElementProcessorException(
205                 "somehow generated a null ElementProcessor");
206         }
207         return rval;
208     }
209
210     /**
211      * A reference implementation of doCreateElementProcessor that can
212      * be used by an extending class whose progenitors are Constructor
213      * objects that can create new instances of ElementProcessor
214      * implementations.
215      *
216      * @param progenitor a Constructor of an ElementProcessor
217      *
218      * @return the newly created ElementProcessor
219      *
220      * @exception CannotCreateElementProcessorException if the
221      * ElementProcessor cannot be created.
222      */

223
224     protected ElementProcessor constructElementProcessor(
225             final Constructor JavaDoc progenitor)
226             throws CannotCreateElementProcessorException {
227         ElementProcessor rval = null;
228
229         try {
230             rval = (ElementProcessor) progenitor.newInstance(new Object JavaDoc[0]);
231             if (rval instanceof AbstractLogEnabled) {
232                ((AbstractLogEnabled)rval).enableLogging(getLogger());
233             }
234         } catch (ExceptionInInitializerError JavaDoc e) {
235             throw new CannotCreateElementProcessorException(
236                 "an exception (" + e
237                 + ")occurred in initializing the associated ElementProcessor class");
238         } catch (IllegalArgumentException JavaDoc e) {
239             throw new CannotCreateElementProcessorException(
240                 "the ElementProcessor constructor apparently needs parameters");
241         } catch (InstantiationException JavaDoc e) {
242             throw new CannotCreateElementProcessorException(
243                 "associated ElementProcessor is an interface or abstract class");
244         } catch (IllegalAccessException JavaDoc e) {
245             throw new CannotCreateElementProcessorException(
246                 "cannot access ElementProcessor class or its zero-parameter constructor");
247         } catch (InvocationTargetException JavaDoc e) {
248             throw new CannotCreateElementProcessorException(
249                 "ElementProcessor constructor threw an exception ["
250                 + e.toString() + "]");
251         } catch (ClassCastException JavaDoc e) {
252             throw new CannotCreateElementProcessorException(
253                 "object created does not implement ElementProcessor");
254         }
255         if (rval == null) {
256             throw new CannotCreateElementProcessorException(
257                 "somehow generated a null ElementProcessor");
258         }
259         return rval;
260     }
261
262 } // end public abstract class AbstractElementProcessorFactory
263
Popular Tags