Source code: org/objectstyle/cayenne/conf/DefaultConfiguration.java
1 /* ====================================================================
2 *
3 * The ObjectStyle Group Software License, Version 1.0
4 *
5 * Copyright (c) 2002-2003 The ObjectStyle Group
6 * and individual authors of the software. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution, if
21 * any, must include the following acknowlegement:
22 * "This product includes software developed by the
23 * ObjectStyle Group (http://objectstyle.org/)."
24 * Alternately, this acknowlegement may appear in the software itself,
25 * if and wherever such third-party acknowlegements normally appear.
26 *
27 * 4. The names "ObjectStyle Group" and "Cayenne"
28 * must not be used to endorse or promote products derived
29 * from this software without prior written permission. For written
30 * permission, please contact andrus@objectstyle.org.
31 *
32 * 5. Products derived from this software may not be called "ObjectStyle"
33 * nor may "ObjectStyle" appear in their names without prior written
34 * permission of the ObjectStyle Group.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the ObjectStyle Group. For more
52 * information on the ObjectStyle Group, please see
53 * <http://objectstyle.org/>.
54 *
55 */
56 package org.objectstyle.cayenne.conf;
57
58 import java.io.InputStream;
59
60 import org.apache.log4j.Logger;
61 import org.objectstyle.cayenne.ConfigurationException;
62 import org.objectstyle.cayenne.util.ResourceLocator;
63 import org.objectstyle.cayenne.util.Util;
64
65 /**
66 * Subclass of Configuration that uses the System CLASSPATH to locate resources.
67 * If Cayenne classes are loaded using a different ClassLoader from
68 * the application classes, this configuration needs to be bootstrapped
69 * by calling {@link Configuration#bootstrapSharedConfiguration(Class)}</code>.
70 *
71 * @author Andrei Adamchik
72 */
73 public class DefaultConfiguration extends Configuration {
74 private static Logger logObj = Logger.getLogger(DefaultConfiguration.class);
75
76 /**
77 * the default ResourceLocator used for CLASSPATH loading
78 */
79 private ResourceLocator locator;
80
81 /**
82 * Default constructor.
83 * Simply calls {@link DefaultConfiguration#DefaultConfiguration(String)}
84 * with {@link Configuration#DEFAULT_DOMAIN_FILE} as argument.
85 * @see Configuration#Configuration()
86 */
87 public DefaultConfiguration() {
88 this(Configuration.DEFAULT_DOMAIN_FILE);
89 }
90
91 /**
92 * Constructor with a named domain configuration resource.
93 * Simply calls {@link Configuration#Configuration(String)}.
94 * @throws ConfigurationException when <code>domainConfigurationName</code>
95 * is <code>null</code>.
96 * @see Configuration#Configuration(String)
97 */
98 public DefaultConfiguration(String domainConfigurationName) {
99 super(domainConfigurationName);
100
101 if (domainConfigurationName == null) {
102 throw new ConfigurationException("cannot use null as domain file name.");
103 }
104
105 logObj.debug("using domain file name: " + domainConfigurationName);
106
107 // configure CLASSPATH-only locator
108 ResourceLocator l = new ResourceLocator();
109 l.setSkipAbsolutePath(true);
110 l.setSkipClasspath(false);
111 l.setSkipCurrentDirectory(true);
112 l.setSkipHomeDirectory(true);
113
114 // add the current Configuration subclass' package as additional path.
115 if (!(this.getClass().equals(DefaultConfiguration.class))) {
116 l.addClassPath(Util.getPackagePath(this.getClass().getName()));
117 }
118
119 // The Configuration superclass statically defines what
120 // ClassLoader to use for resources. This allows applications to
121 // control where resources are loaded from.
122 l.setClassLoader(Configuration.getResourceLoader());
123
124 // remember configured ResourceLocator
125 this.setResourceLocator(l);
126 }
127
128 /**
129 * Adds a custom path for class path lookups.
130 * Format should be "my/package/name" <i>without</i> leading "/".
131 *
132 * This allows for easy customization of custom search paths after
133 * Constructor invocation:
134 * <pre>
135 * conf = new DefaultConfiguration();
136 * conf.addClassPath("my/package/name");
137 * Configuration.initializeSharedConfiguration(conf);
138 * </pre>
139 *
140 */
141 public void addClassPath(String customPath) {
142 this.getResourceLocator().addClassPath(customPath);
143 }
144
145 /**
146 * Default implementation of {@link Configuration#canInitialize}.
147 * Creates a ResourceLocator suitable for loading from the CLASSPATH,
148 * unless it has already been set in a subclass.
149 * Always returns <code>true</code>.
150 */
151 public boolean canInitialize() {
152 logObj.debug("canInitialize started.");
153 // allow to proceed
154 return true;
155 }
156
157 /**
158 * Initializes all Cayenne resources. Loads all configured domains and their
159 * data maps, initializes all domain Nodes and their DataSources.
160 */
161 public void initialize() throws Exception {
162 logObj.debug("initialize starting.");
163
164 InputStream in = this.getDomainConfiguration();
165 if (in == null) {
166 StringBuffer msg = new StringBuffer();
167 msg
168 .append("[")
169 .append(this.getClass().getName())
170 .append("] : Domain configuration file \"")
171 .append(DEFAULT_DOMAIN_FILE)
172 .append("\" is not found.");
173
174 throw new ConfigurationException(msg.toString());
175 }
176
177 ConfigLoaderDelegate delegate = this.getLoaderDelegate();
178 if (delegate == null) {
179 delegate = new RuntimeLoadDelegate(this, this.getLoadStatus(), Configuration.getLoggingLevel());
180 }
181
182 ConfigLoader loader = new ConfigLoader(delegate);
183
184 try {
185 loader.loadDomains(in);
186 } finally {
187 this.setLoadStatus(delegate.getStatus());
188 in.close();
189 }
190
191 // log successful initialization
192 logObj.debug("initialize finished.");
193 }
194
195 /**
196 * Default implementation of {@link Configuration#didInitialize}.
197 * Currently does nothing except logging.
198 */
199 public void didInitialize() {
200 // empty default implementation
201 logObj.debug("didInitialize finished.");
202 }
203
204 /**
205 * Returns the default ResourceLocator configured for CLASSPATH lookups.
206 */
207 protected ResourceLocator getResourceLocator() {
208 return this.locator;
209 }
210
211 /**
212 * Sets the specified {@link ResourceLocator}.
213 * Currently called from {@link #initialize}.
214 */
215 protected void setResourceLocator(ResourceLocator locator) {
216 this.locator = locator;
217 }
218
219 /**
220 * Returns the domain configuration as a stream or <code>null</code> if it
221 * cannot be found. Uses the configured {@link ResourceLocator} to
222 * find the file.
223 */
224 protected InputStream getDomainConfiguration() {
225 return locator.findResourceStream(this.getDomainConfigurationName());
226 }
227
228 /**
229 * Returns the {@link org.objectstyle.cayenne.map.DataMap} configuration
230 * from a specified location or <code>null</code> if it cannot be found.
231 * Uses the configured {@link ResourceLocator} to find the file.
232 */
233 protected InputStream getMapConfiguration(String location) {
234 return locator.findResourceStream(location);
235 }
236
237 /**
238 * @see Object#toString()
239 */
240 public String toString() {
241 StringBuffer buf = new StringBuffer();
242 buf
243 .append('[')
244 .append(this.getClass().getName())
245 .append(": classloader=")
246 .append(locator.getClassLoader())
247 .append(']');
248 return buf.toString();
249 }
250
251 }