KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > conf > RuntimeLoadDelegate


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.conf;
57
58 import java.io.InputStream JavaDoc;
59 import java.util.HashMap JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.Map JavaDoc;
62
63 import javax.sql.DataSource JavaDoc;
64
65 import org.apache.log4j.Level;
66 import org.apache.log4j.Logger;
67 import org.objectstyle.cayenne.ConfigurationException;
68 import org.objectstyle.cayenne.access.DataDomain;
69 import org.objectstyle.cayenne.access.DataNode;
70 import org.objectstyle.cayenne.dba.DbAdapter;
71 import org.objectstyle.cayenne.dba.JdbcAdapter;
72 import org.objectstyle.cayenne.map.DataMap;
73 import org.objectstyle.cayenne.map.DataMapException;
74 import org.objectstyle.cayenne.map.MapLoader;
75 import org.xml.sax.InputSource JavaDoc;
76
77 /**
78  * Implementation of ConfigLoaderDelegate that creates Cayenne access objects
79  * stack.
80  *
81  * @author Andrei Adamchik
82  */

83 public class RuntimeLoadDelegate implements ConfigLoaderDelegate {
84     private static Logger logObj = Logger.getLogger(RuntimeLoadDelegate.class);
85
86     protected Map JavaDoc domains = new HashMap JavaDoc();
87     protected Map JavaDoc views = new HashMap JavaDoc();
88     protected ConfigStatus status;
89     protected Configuration config;
90     protected Level logLevel;
91     protected long startTime;
92
93     public RuntimeLoadDelegate(
94         Configuration config,
95         ConfigStatus status,
96         Level logLevel) {
97         this.config = config;
98         this.logLevel = logLevel;
99
100         if (status == null) {
101             status = new ConfigStatus();
102         }
103
104         this.status = status;
105     }
106
107     protected DataDomain findDomain(String JavaDoc name) throws FindException {
108         DataDomain domain = (DataDomain) domains.get(name);
109         if (domain == null) {
110             throw new FindException("Can't find DataDomain: " + name);
111         }
112
113         return domain;
114     }
115
116     protected DataMap findMap(String JavaDoc domainName, String JavaDoc mapName) throws FindException {
117         DataDomain domain = findDomain(domainName);
118         DataMap map = domain.getMap(mapName);
119         if (map == null) {
120             throw new FindException("Can't find DataMap: " + mapName);
121         }
122
123         return map;
124     }
125
126     protected DataNode findNode(String JavaDoc domainName, String JavaDoc nodeName)
127         throws FindException {
128         DataDomain domain = findDomain(domainName);
129         DataNode node = domain.getNode(nodeName);
130         if (node == null) {
131             throw new FindException("Can't find DataNode: " + nodeName);
132         }
133
134         return node;
135     }
136
137     public boolean loadError(Throwable JavaDoc th) {
138         logObj.log(logLevel, "Parser Exception.", th);
139         status.getOtherFailures().add(th.getMessage());
140         return false;
141     }
142
143     /**
144      * @since 1.1
145      */

146     public void shouldLoadProjectVersion(String JavaDoc version) {
147         config.setProjectVersion(version);
148     }
149
150     /**
151      * @since 1.1
152      */

153     public void shouldRegisterDataView(String JavaDoc name, String JavaDoc location) {
154         views.put(name, location);
155     }
156
157     public void shouldLoadDataDomainProperties(String JavaDoc domainName, Map JavaDoc properties) {
158         if (properties == null || properties.isEmpty()) {
159             return;
160         }
161
162         DataDomain domain = null;
163         try {
164             domain = findDomain(domainName);
165         }
166         catch (FindException ex) {
167             logObj.log(logLevel, "Error: Domain is not loaded: " + domainName);
168             throw new ConfigurationException("Domain is not loaded: " + domainName);
169         }
170
171         domain.initWithProperties(properties);
172     }
173
174     public void shouldLoadDataDomain(String JavaDoc domainName) {
175         if (domainName == null) {
176             logObj.log(logLevel, "Error: unnamed <domain>.");
177             throw new ConfigurationException("Domain 'name' attribute must be not null.");
178         }
179
180         logObj.log(logLevel, "loaded domain: " + domainName);
181         domains.put(domainName, new DataDomain(domainName));
182     }
183
184     public void shouldLoadDataMaps(String JavaDoc domainName, Map JavaDoc locations) {
185         if (locations.size() == 0) {
186             return;
187         }
188
189         DataDomain domain = null;
190         try {
191             domain = findDomain(domainName);
192         }
193         catch (FindException ex) {
194             logObj.log(logLevel, "Error: Domain is not loaded: " + domainName);
195             throw new ConfigurationException("Domain is not loaded: " + domainName);
196         }
197
198         // load DataMaps tree
199
Iterator JavaDoc it = locations.keySet().iterator();
200         while (it.hasNext()) {
201             String JavaDoc name = (String JavaDoc) it.next();
202             DataMap map = domain.getMap(name);
203             if (map != null) {
204                 continue;
205             }
206
207             loadDataMap(domain, name, locations);
208         }
209     }
210
211     /**
212      * Returns DataMap for the name and location information. If a DataMap
213      * is already loaded within a given domain, such loaded map is returned, otherwise
214      * the map is loaded and linked with the DataDomain.
215      */

216     protected DataMap loadDataMap(DataDomain domain, String JavaDoc mapName, Map JavaDoc locations) {
217
218         if (mapName == null) {
219             throw new ConfigurationException("Error: <map> without 'name'.");
220         }
221
222         String JavaDoc location = (String JavaDoc) locations.get(mapName);
223
224         if (location == null) {
225             throw new ConfigurationException(
226                 "Error: map '" + mapName + "' without 'location'.");
227         }
228
229         // load DataMap
230
InputStream JavaDoc mapIn = config.getMapConfiguration(location);
231         if (mapIn == null) {
232             logObj.log(logLevel, "Warning: map location not found.");
233             getStatus().addFailedMap(mapName, location, "map location not found");
234             return null;
235         }
236
237         try {
238             DataMap map = new MapLoader().loadDataMap(new InputSource JavaDoc(mapIn));
239
240             logObj.log(
241                 logLevel,
242                 "loaded <map name='" + mapName + "' location='" + location + "'>.");
243
244             map.setName(mapName);
245             map.setLocation(location);
246
247             domain.addMap(map);
248             return map;
249         }
250         catch (DataMapException dmex) {
251             logObj.log(logLevel, "Warning: map loading failed.", dmex);
252             getStatus().addFailedMap(
253                 mapName,
254                 location,
255                 "map loading failed - " + dmex.getMessage());
256             return null;
257         }
258     }
259
260     public void shouldLoadDataNode(
261         String JavaDoc domainName,
262         String JavaDoc nodeName,
263         String JavaDoc dataSource,
264         String JavaDoc adapter,
265         String JavaDoc factory) {
266
267         logObj.log(
268             logLevel,
269             "loading <node name='"
270                 + nodeName
271                 + "' datasource='"
272                 + dataSource
273                 + "' factory='"
274                 + factory
275                 + "'>.");
276
277         if (nodeName == null) {
278             throw new ConfigurationException("Error: <node> without 'name'.");
279         }
280
281         if (dataSource == null) {
282             logObj.log(
283                 logLevel,
284                 "Warning: <node> '" + nodeName + "' has no 'datasource'.");
285         }
286
287         if (factory == null) {
288             if (config.getDataSourceFactory() != null) {
289                 logObj.log(
290                     logLevel,
291                     "Warning: <node> '" + nodeName + "' without 'factory'.");
292             }
293             else {
294                 throw new ConfigurationException(
295                     "Error: <node> '" + nodeName + "' without 'factory'.");
296             }
297         }
298
299         // load DbAdapter
300
if (adapter == null) {
301             adapter = JdbcAdapter.class.getName();
302         }
303
304         DbAdapter dbAdapter = null;
305
306         try {
307             ClassLoader JavaDoc cl = config.getClassLoader();
308             Class JavaDoc dbAdapterClass = (cl != null) ? cl.loadClass(adapter) : Class
309                     .forName(adapter);
310             dbAdapter = (DbAdapter) dbAdapterClass.newInstance();
311         }
312         catch (Exception JavaDoc ex) {
313             logObj.log(
314                 logLevel,
315                 "instantiating adapter failed, using default adapter.",
316                 ex);
317             getStatus().addFailedAdapter(
318                 nodeName,
319                 adapter,
320                 "instantiating adapter failed - " + ex.getMessage());
321             dbAdapter = new JdbcAdapter();
322         }
323
324         DataNode node = new DataNode(nodeName);
325         node.setAdapter(dbAdapter);
326         node.setDataSourceFactory(factory);
327         node.setDataSourceLocation(dataSource);
328
329         // load DataSource
330
try {
331             // use DomainHelper factory if it exists, if not - use factory specified
332
// in configuration data
333
DataSourceFactory confFactory = config.getDataSourceFactory();
334             DataSourceFactory localFactory =
335                 (confFactory != null)
336                     ? confFactory
337                     : (DataSourceFactory) Class.forName(factory).newInstance();
338
339             logObj.log(logLevel, "using factory: " + localFactory.getClass().getName());
340
341             localFactory.initializeWithParentConfiguration(config);
342             DataSource JavaDoc ds = localFactory.getDataSource(dataSource, logLevel);
343             if (ds != null) {
344                 logObj.log(logLevel, "loaded datasource.");
345                 node.setDataSource(ds);
346             }
347             else {
348                 logObj.log(logLevel, "Warning: null datasource.");
349                 getStatus().getFailedDataSources().put(nodeName, dataSource);
350             }
351         }
352         catch (Exception JavaDoc ex) {
353             logObj.log(logLevel, "Error: DataSource load failed", ex);
354             getStatus().addFailedDataSource(
355                 nodeName,
356                 dataSource,
357                 "DataSource load failed - " + ex.getMessage());
358         }
359
360         try {
361             findDomain(domainName).addNode(node);
362         }
363         catch (FindException ex) {
364             logObj.log(logLevel, "Error: can't load node, unknown domain: " + domainName);
365             getStatus().addFailedDataSource(
366                 nodeName,
367                 nodeName,
368                 "can't load node, unknown domain: " + domainName);
369         }
370     }
371
372     public void shouldLinkDataMap(String JavaDoc domainName, String JavaDoc nodeName, String JavaDoc mapName) {
373
374         if (mapName == null) {
375             logObj.log(logLevel, "<map-ref> has no 'name'.");
376             throw new ConfigurationException("<map-ref> has no 'name'.");
377         }
378
379         logObj.log(logLevel, "loaded map-ref: " + mapName + ".");
380         DataMap map = null;
381         DataNode node = null;
382
383         try {
384             map = findMap(domainName, mapName);
385         }
386         catch (FindException ex) {
387             logObj.log(logLevel, "Error: unknown map: " + mapName);
388             getStatus().addFailedMapRefs(mapName, "unknown map: " + mapName);
389             return;
390         }
391
392         try {
393             node = findNode(domainName, nodeName);
394         }
395         catch (FindException ex) {
396             logObj.log(logLevel, "Error: unknown node: " + nodeName);
397             getStatus().addFailedMapRefs(mapName, "unknown node: " + nodeName);
398             return;
399         }
400
401         node.addDataMap(map);
402     }
403
404     /**
405      * Returns the domains.
406      * @return List
407      */

408     public Map JavaDoc getDomains() {
409         return domains;
410     }
411
412     /**
413      * Returns the status.
414      * @return ConfigStatus
415      */

416     public ConfigStatus getStatus() {
417         return status;
418     }
419
420     /**
421      * Returns the config.
422      * @return Configuration
423      */

424     public Configuration getConfig() {
425         return config;
426     }
427
428     /**
429      * Sets the config.
430      * @param config The config to set
431      */

432     public void setConfig(Configuration config) {
433         this.config = config;
434     }
435
436     /**
437      * Returns the logLevel.
438      * @return Level
439      */

440     public Level getLogLevel() {
441         return this.logLevel;
442     }
443
444     /**
445      * Sets the logLevel.
446      * @param logLevel The logLevel to set
447      */

448     public void setLogLevel(Level logLevel) {
449         this.logLevel = logLevel;
450     }
451
452     /**
453      * @see org.objectstyle.cayenne.conf.ConfigLoaderDelegate#finishedLoading()
454      */

455     public void finishedLoading() {
456         // check for failures
457
if (status.hasFailures()) {
458             if (!config.isIgnoringLoadFailures()) {
459                 StringBuffer JavaDoc msg = new StringBuffer JavaDoc(128);
460                 msg.append("Load failures. Main configuration class: ");
461                 msg.append(config.getClass().getName());
462                 msg.append(", details: ");
463                 msg.append(status.describeFailures());
464                 throw new ConfigurationException(msg.toString());
465             }
466         }
467
468         // update configuration object
469
Iterator JavaDoc it = getDomains().values().iterator();
470         while (it.hasNext()) {
471             config.addDomain((DataDomain) it.next());
472         }
473
474         config.setDataViewLocations(views);
475
476         logObj.log(
477             logLevel,
478             "finished configuration loading in "
479                 + (System.currentTimeMillis() - startTime)
480                 + " ms.");
481     }
482
483     /**
484      * @see org.objectstyle.cayenne.conf.ConfigLoaderDelegate#startedLoading()
485      */

486     public void startedLoading() {
487         startTime = System.currentTimeMillis();
488         logObj.log(logLevel, "started configuration loading.");
489     }
490
491     /**
492      * Thrown when loaded data does not contain certain expected objects.
493      */

494     class FindException extends Exception JavaDoc {
495         /**
496          * Constructor for FindException.
497          * @param msg
498          */

499         public FindException(String JavaDoc msg) {
500             super(msg);
501         }
502     }
503 }
504
Popular Tags