KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibatis > dao > engine > builder > xml > XmlDaoManagerBuilder


1 /*
2  * Copyright 2004 Clinton Begin
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 com.ibatis.dao.engine.builder.xml;
17
18 import com.ibatis.common.io.ReaderInputStream;
19 import com.ibatis.common.resources.Resources;
20 import com.ibatis.common.exception.NestedRuntimeException;
21 import com.ibatis.dao.client.Dao;
22 import com.ibatis.dao.client.DaoException;
23 import com.ibatis.dao.client.DaoManager;
24 import com.ibatis.dao.engine.impl.DaoContext;
25 import com.ibatis.dao.engine.impl.DaoImpl;
26 import com.ibatis.dao.engine.impl.StandardDaoManager;
27 import com.ibatis.dao.engine.transaction.DaoTransactionManager;
28 import com.ibatis.dao.engine.transaction.external.ExternalDaoTransactionManager;
29 import com.ibatis.dao.engine.transaction.hibernate.HibernateDaoTransactionManager;
30 import com.ibatis.dao.engine.transaction.jdbc.JdbcDaoTransactionManager;
31 import com.ibatis.dao.engine.transaction.jta.JtaDaoTransactionManager;
32 import com.ibatis.dao.engine.transaction.sqlmap.SqlMapDaoTransactionManager;
33 import org.w3c.dom.*;
34 import org.xml.sax.ErrorHandler JavaDoc;
35 import org.xml.sax.SAXException JavaDoc;
36 import org.xml.sax.SAXParseException JavaDoc;
37
38 import javax.xml.parsers.DocumentBuilder JavaDoc;
39 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
40 import java.io.IOException JavaDoc;
41 import java.io.OutputStreamWriter JavaDoc;
42 import java.io.PrintWriter JavaDoc;
43 import java.io.Reader JavaDoc;
44 import java.lang.reflect.Constructor JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.util.Map JavaDoc;
47 import java.util.Properties JavaDoc;
48
49 /**
50  * NOT THREAD SAFE. USE SEPARATE INSTANCES PER THREAD.
51  */

52 public class XmlDaoManagerBuilder {
53
54
55   private static final String JavaDoc DAO_CONFIG_ELEMENT = "daoConfig";
56   private static final String JavaDoc PROPERTIES_ELEMENT = "properties";
57   private static final String JavaDoc CONTEXT_ELEMENT = "context";
58   private static final String JavaDoc TRANS_MGR_ELEMENT = "transactionManager";
59   private static final String JavaDoc PROPERTY_ELEMENT = "property";
60   private static final String JavaDoc DAO_ELEMENT = "dao";
61
62   private Properties JavaDoc properties = null;
63   private boolean validationEnabled = true;
64   private Map JavaDoc typeAliases = new HashMap JavaDoc();
65
66   public XmlDaoManagerBuilder() {
67     typeAliases.put("JDBC", JdbcDaoTransactionManager.class.getName());
68     typeAliases.put("JTA", JtaDaoTransactionManager.class.getName());
69     typeAliases.put("EXTERNAL", ExternalDaoTransactionManager.class.getName());
70     typeAliases.put("HIBERNATE", HibernateDaoTransactionManager.class.getName());
71     typeAliases.put("SQLMAP", SqlMapDaoTransactionManager.class.getName());
72   }
73
74   public DaoManager buildDaoManager(Reader JavaDoc reader, Properties JavaDoc props)
75       throws DaoException {
76     properties = props;
77     return buildDaoManager(reader);
78   }
79
80   public DaoManager buildDaoManager(Reader JavaDoc reader)
81       throws DaoException {
82     StandardDaoManager daoManager = new StandardDaoManager();
83
84     try {
85
86       Document doc = getDoc(reader);
87       Element root = (Element) doc.getLastChild();
88
89       String JavaDoc rootname = root.getNodeName();
90       if (!DAO_CONFIG_ELEMENT.equals(rootname)) {
91         throw new IOException JavaDoc("Error while configuring DaoManager. The root tag of the DAO configuration XML " +
92             "document must be '" + DAO_CONFIG_ELEMENT + "'.");
93       }
94
95       NodeList children = root.getChildNodes();
96       for (int i = 0; i < children.getLength(); i++) {
97         Node child = children.item(i);
98         if (child.getNodeType() == Node.ELEMENT_NODE) {
99           if (CONTEXT_ELEMENT.equals(child.getNodeName())) {
100             DaoContext daoContext = parseContext((Element) child, daoManager);
101             daoManager.addContext(daoContext);
102           } else if (PROPERTIES_ELEMENT.equals(child.getNodeName())) {
103             Properties JavaDoc attributes = parseAttributes(child);
104             if (attributes.containsKey("resource")) {
105               String JavaDoc resource = attributes.getProperty("resource");
106               if (properties == null) {
107                 properties = Resources.getResourceAsProperties(resource);
108               } else {
109                 Properties JavaDoc tempProps = Resources.getResourceAsProperties(resource);
110                 tempProps.putAll(properties);
111                 properties = tempProps;
112               }
113             } else if (attributes.containsKey("url")) {
114               String JavaDoc url = attributes.getProperty("url");
115               if (properties == null) {
116                 properties = Resources.getUrlAsProperties(url);
117               } else {
118                 Properties JavaDoc tempProps = Resources.getUrlAsProperties(url);
119                 tempProps.putAll(properties);
120                 properties = tempProps;
121               }
122             }
123           }
124         }
125       }
126     } catch (Exception JavaDoc e) {
127       throw new DaoException("Error while configuring DaoManager. Cause: " + e.toString(), e);
128     }
129     return daoManager;
130   }
131
132   public boolean isValidationEnabled() {
133     return validationEnabled;
134   }
135
136   public void setValidationEnabled(boolean validationEnabled) {
137     this.validationEnabled = validationEnabled;
138   }
139
140   private DaoContext parseContext(Element contextElement, StandardDaoManager daoManager)
141       throws DaoException {
142     DaoContext daoContext = new DaoContext();
143
144     daoContext.setDaoManager(daoManager);
145     String JavaDoc id = contextElement.getAttribute("id");
146     if (id != null && id.length() > 0) {
147       daoContext.setId(id);
148     }
149
150     NodeList children = contextElement.getChildNodes();
151     for (int i = 0; i < children.getLength(); i++) {
152       Node child = children.item(i);
153       if (child.getNodeType() == Node.ELEMENT_NODE) {
154         if (TRANS_MGR_ELEMENT.equals(child.getNodeName())) {
155           DaoTransactionManager txMgr = parseTransactionManager((Element) child);
156           daoContext.setTransactionManager(txMgr);
157         } else if (DAO_ELEMENT.equals(child.getNodeName())) {
158           DaoImpl daoImpl = parseDao((Element) child, daoManager, daoContext);
159           daoContext.addDao(daoImpl);
160         }
161       }
162     }
163
164     return daoContext;
165   }
166
167   private DaoTransactionManager parseTransactionManager(Element transPoolElement)
168       throws DaoException {
169     DaoTransactionManager txMgr = null;
170
171     Properties JavaDoc attributes = parseAttributes(transPoolElement);
172
173     String JavaDoc implementation = attributes.getProperty("type");
174     implementation = resolveAlias(implementation);
175
176
177     try {
178       txMgr = (DaoTransactionManager) Class.forName(implementation).newInstance();
179     } catch (Exception JavaDoc e) {
180       throw new DaoException("Error while configuring DaoManager. Cause: " + e.toString(), e);
181     }
182
183     Properties JavaDoc props = properties;
184
185     if (props == null) {
186       props = parsePropertyElements(transPoolElement);
187     } else {
188       props.putAll(parsePropertyElements(transPoolElement));
189     }
190
191     txMgr.configure(props);
192
193     if (txMgr == null) {
194       throw new DaoException("Error while configuring DaoManager. Some unknown condition caused the " +
195           "DAO Transaction Manager to be null after configuration.");
196     }
197
198     return txMgr;
199   }
200
201   private DaoImpl parseDao(Element element, StandardDaoManager daoManager, DaoContext daoContext) {
202     DaoImpl daoImpl = new DaoImpl();
203     if (element.getNodeType() == Node.ELEMENT_NODE) {
204       if (DAO_ELEMENT.equals(element.getNodeName())) {
205
206         Properties JavaDoc attributes = parseAttributes(element);
207
208         try {
209           String JavaDoc iface = attributes.getProperty("interface");
210           String JavaDoc impl = attributes.getProperty("implementation");
211           daoImpl.setDaoManager(daoManager);
212           daoImpl.setDaoContext(daoContext);
213           daoImpl.setDaoInterface(Resources.classForName(iface));
214           daoImpl.setDaoImplementation(Resources.classForName(impl));
215
216           Class JavaDoc daoClass = daoImpl.getDaoImplementation();
217           Dao dao = null;
218
219           try {
220             Constructor JavaDoc constructor = daoClass.getConstructor(new Class JavaDoc[]{DaoManager.class});
221             dao = (Dao) constructor.newInstance(new Object JavaDoc[]{daoManager});
222           } catch (Exception JavaDoc e) {
223             dao = (Dao) daoClass.newInstance();
224           }
225
226           daoImpl.setDaoInstance(dao);
227           daoImpl.initProxy();
228         } catch (Exception JavaDoc e) {
229           throw new DaoException("Error configuring DAO. Cause: " + e, e);
230         }
231       }
232     }
233     return daoImpl;
234   }
235
236   private Properties JavaDoc parsePropertyElements(Element propsParentElement) {
237
238     Properties JavaDoc props = new Properties JavaDoc();
239
240     NodeList children = propsParentElement.getChildNodes();
241     for (int i = 0; i < children.getLength(); i++) {
242       Node child = children.item(i);
243
244       if (child.getNodeType() == Node.ELEMENT_NODE) {
245         if (PROPERTY_ELEMENT.equals(child.getNodeName())) {
246
247           Properties JavaDoc attributes = parseAttributes(child);
248
249           String JavaDoc name = attributes.getProperty("name");
250           String JavaDoc value = attributes.getProperty("value");
251
252           props.setProperty(name, value);
253         }
254       }
255
256     }
257
258     return props;
259   }
260
261   private Properties JavaDoc parseAttributes(Node n) {
262     Properties JavaDoc attributes = new Properties JavaDoc();
263     NamedNodeMap attributeNodes = n.getAttributes();
264     for (int i = 0; i < attributeNodes.getLength(); i++) {
265       Node attribute = attributeNodes.item(i);
266       String JavaDoc value = parsePropertyTokens(attribute.getNodeValue());
267       attributes.put(attribute.getNodeName(), value);
268     }
269     return attributes;
270   }
271
272   private String JavaDoc parsePropertyTokens(String JavaDoc string) {
273     final String JavaDoc OPEN = "${";
274     final String JavaDoc CLOSE = "}";
275     String JavaDoc newString = string;
276     if (newString != null && properties != null) {
277       int start = newString.indexOf(OPEN);
278       int end = newString.indexOf(CLOSE);
279
280       while (start > -1 && end > start) {
281         String JavaDoc prepend = newString.substring(0, start);
282         String JavaDoc append = newString.substring(end + CLOSE.length());
283         String JavaDoc propName = newString.substring(start + OPEN.length(), end);
284         String JavaDoc propValue = properties.getProperty(propName);
285         if (propValue == null) {
286           newString = prepend + append;
287         } else {
288           newString = prepend + propValue + append;
289         }
290         start = newString.indexOf(OPEN);
291         end = newString.indexOf(CLOSE);
292       }
293     }
294     return newString;
295   }
296
297   private Document getDoc(Reader JavaDoc reader) {
298     try {
299       // Configuration
300
DocumentBuilderFactory JavaDoc dbf = DocumentBuilderFactory.newInstance();
301       dbf.setNamespaceAware(false);
302       dbf.setValidating(true);
303       dbf.setIgnoringComments(true);
304       dbf.setIgnoringElementContentWhitespace(true);
305       dbf.setCoalescing(false);
306       dbf.setExpandEntityReferences(false);
307
308       OutputStreamWriter JavaDoc errorWriter = new OutputStreamWriter JavaDoc(System.err);
309
310       DocumentBuilder JavaDoc db = dbf.newDocumentBuilder();
311       db.setErrorHandler(new SimpleErrorHandler(new PrintWriter JavaDoc(errorWriter, true)));
312       db.setEntityResolver(new DaoClasspathEntityResolver());
313
314       // Parse input file
315
Document doc = db.parse(new ReaderInputStream(reader));
316       return doc;
317     } catch (Exception JavaDoc e) {
318       throw new NestedRuntimeException("XML Parser Error. Cause: " + e);
319     }
320   }
321
322   private String JavaDoc resolveAlias(String JavaDoc string) {
323     String JavaDoc newString = null;
324     if (typeAliases.containsKey(string)) {
325       newString = (String JavaDoc) typeAliases.get(string);
326     }
327     if (newString != null) {
328       string = newString;
329     }
330     return string;
331   }
332
333   /**
334    * **********************************
335    * ******* SimpleErrorHandler *******
336    * **********************************
337    */

338
339   // Error handler to report errors and warnings
340
private static class SimpleErrorHandler implements ErrorHandler JavaDoc {
341     /**
342      * Error handler output goes here
343      */

344     private PrintWriter JavaDoc out;
345
346     SimpleErrorHandler(PrintWriter JavaDoc out) {
347       this.out = out;
348     }
349
350     /**
351      * Returns a string describing parse exception details
352      */

353     private String JavaDoc getParseExceptionInfo(SAXParseException JavaDoc spe) {
354       String JavaDoc systemId = spe.getSystemId();
355       if (systemId == null) {
356         systemId = "null";
357       }
358       String JavaDoc info = "URI=" + systemId +
359           " Line=" + spe.getLineNumber() +
360           ": " + spe.getMessage();
361       return info;
362     }
363
364     // The following methods are standard SAX ErrorHandler methods.
365
// See SAX documentation for more info.
366

367     public void warning(SAXParseException JavaDoc spe) throws SAXException JavaDoc {
368       out.println("Warning: " + getParseExceptionInfo(spe));
369     }
370
371     public void error(SAXParseException JavaDoc spe) throws SAXException JavaDoc {
372       String JavaDoc message = "Error: " + getParseExceptionInfo(spe);
373       throw new SAXException JavaDoc(message);
374     }
375
376     public void fatalError(SAXParseException JavaDoc spe) throws SAXException JavaDoc {
377       String JavaDoc message = "Fatal Error: " + getParseExceptionInfo(spe);
378       throw new SAXException JavaDoc(message);
379     }
380   }
381
382 }
383
Popular Tags