1 package org.apache.torque.engine.database.model;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Properties;
27
28 import org.apache.commons.lang.StringUtils;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33 import org.apache.torque.engine.EngineException;
34 import org.apache.torque.engine.database.transform.DTDResolver;
35
36 import org.xml.sax.Attributes;
37
38 /***
39 * A class for holding application data structures.
40 *
41 * @author <a href="mailto:leon@opticode.co.za>Leon Messerschmidt</a>
42 * @author <a href="mailto:jmcnally@collab.net>John McNally</a>
43 * @author <a href="mailto:dlr@finemaltcoding.com>Daniel Rall</a>
44 * @version $Id: AppData.java,v 1.4.2.2 2004/05/20 04:34:15 seade Exp $
45 */
46 public class AppData
47 {
48 /*** Logging class from commons.logging */
49 private static Log log = LogFactory.getLog(AppData.class);
50
51 /***
52 * The list of databases for this application.
53 */
54 private List dbList = new ArrayList(5);
55
56 /***
57 * The table of idiosyncrasies for various database types.
58 */
59 private Map idiosyncrasyTable = new HashMap(8);
60
61 /***
62 * The type for our databases.
63 */
64 private String databaseType;
65
66 /***
67 * The base of the path to the properties file, including trailing slash.
68 */
69 private String basePropsFilePath;
70
71 /***
72 * Name of the database. Only one database definition
73 * is allowed in one XML descriptor.
74 */
75 private String name;
76
77
78 boolean isInitialized;
79
80 /***
81 * Creates a new instance for the specified database type.
82 *
83 * @param databaseType The default type for any databases added to
84 * this application model.
85 * @param basePropsFilePath The base of the path to the properties
86 * file, including trailing slash.
87 */
88 public AppData(String databaseType, String basePropsFilePath)
89 {
90 this.basePropsFilePath = basePropsFilePath;
91 this.databaseType = databaseType;
92 }
93
94 /***
95 * Each database has its own list of idiosyncrasies which can be
96 * configured by editting its <code>db.props</code> file.
97 *
98 * @param databaseType The type of database to retrieve the
99 * properties of.
100 * @return The idiosyncrasies of <code>databaseType</code>.
101 * @exception EngineException Couldn't locate properties file.
102 */
103 protected Properties getIdiosyncrasies(String databaseType)
104 throws EngineException
105 {
106 Properties idiosyncrasies
107 = (Properties) idiosyncrasyTable.get(databaseType);
108
109
110
111 if (idiosyncrasies == null && basePropsFilePath != null
112 && databaseType != null)
113 {
114 idiosyncrasies = new Properties();
115 File propsFile = new File(basePropsFilePath + databaseType,
116 "db.props");
117 if (propsFile.exists())
118 {
119 try
120 {
121 idiosyncrasies.load(new FileInputStream(propsFile));
122 }
123 catch (Exception e)
124 {
125 log.error(e, e);
126 }
127 idiosyncrasyTable.put(databaseType, idiosyncrasies);
128 }
129 else
130 {
131 try
132 {
133 String path = '/' + basePropsFilePath + databaseType
134 + "/db.props";
135 idiosyncrasies.load(getClass().getResourceAsStream(path));
136 }
137 catch (Exception e)
138 {
139 log.error(e, e);
140 }
141 }
142
143 if (idiosyncrasies.isEmpty())
144 {
145 throw new EngineException("Database-specific properties "
146 + "file does not exist: "
147 + propsFile.getAbsolutePath());
148 }
149 }
150 return idiosyncrasies;
151 }
152
153 /***
154 * Set the name of the database.
155 *
156 * @param name of the database.
157 */
158 public void setName(String name)
159 {
160 this.name = name;
161 }
162
163 /***
164 * Get the name of the database.
165 *
166 * @return String name
167 */
168 public String getName()
169 {
170 return name;
171 }
172
173 /***
174 * Get the short name of the database (without the '-schema' postfix).
175 *
176 * @return String name
177 */
178 public String getShortName()
179 {
180 return StringUtils.replace(name, "-schema", "");
181 }
182
183 /***
184 * Get database object.
185 *
186 * @return Database database
187 */
188 public Database getDatabase()
189 throws EngineException
190 {
191 doFinalInitialization();
192 return (Database) dbList.get(0);
193 }
194
195 /***
196 * Return an array of all databases
197 *
198 * @return Array of Database objects
199 */
200 public Database[] getDatabases()
201 throws EngineException
202 {
203 doFinalInitialization();
204 int size = dbList.size();
205 Database[] dbs = new Database[size];
206 for (int i = 0; i < size; i++)
207 {
208 dbs[i] = (Database) dbList.get(i);
209 }
210 return dbs;
211 }
212
213 /***
214 * Returns whether this application has multiple databases.
215 *
216 * @return true if the application has multiple databases
217 */
218 public boolean hasMultipleDatabases()
219 {
220 return (dbList.size() > 1);
221 }
222
223 /***
224 * Return the database with the specified name.
225 *
226 * @param name database name
227 * @return A Database object. If it does not exist it returns null
228 */
229 public Database getDatabase (String name)
230 throws EngineException
231 {
232 doFinalInitialization();
233 for (Iterator i = dbList.iterator(); i.hasNext();)
234 {
235 Database db = (Database) i.next();
236 if (db.getName().equals(name))
237 {
238 return db;
239 }
240 }
241 return null;
242 }
243
244 /***
245 * An utility method to add a new database from an xml attribute.
246 *
247 * @param attrib the xml attributes
248 * @return the database
249 */
250 public Database addDatabase(Attributes attrib)
251 {
252 Database db = new Database();
253 db.loadFromXML (attrib);
254 addDatabase (db);
255 return db;
256 }
257
258 /***
259 * Add a database to the list and sets the AppData property to this
260 * AppData
261 *
262 * @param db the database to add
263 */
264 public void addDatabase(Database db)
265 {
266 db.setAppData (this);
267 if (db.getName() == null)
268 {
269 /*** @task check this */
270 db.setName("default");
271 }
272 if (db.getDatabaseType() == null)
273 {
274 db.setDatabaseType(databaseType);
275 }
276 dbList.add(db);
277 }
278
279 private void doFinalInitialization()
280 throws EngineException
281 {
282 if (!isInitialized)
283 {
284 Iterator dbs = dbList.iterator();
285 while (dbs.hasNext())
286 {
287 ((Database) dbs.next()).doFinalInitialization();
288 }
289 isInitialized = true;
290 }
291 }
292
293 /***
294 * Creats a string representation of this AppData.
295 * The representation is given in xml format.
296 *
297 * @return representation in xml format
298 */
299 public String toString()
300 {
301 StringBuffer result = new StringBuffer();
302
303 result.append ("<?xml version=\"1.0\"?>\n");
304 result.append ("<!DOCTYPE database SYSTEM \""
305 + DTDResolver.WEB_SITE_DTD + "\">\n");
306 result.append("<!-- Autogenerated by SQLToXMLSchema! -->\n");
307 for (Iterator i = dbList.iterator(); i.hasNext();)
308 {
309 result.append (i.next());
310 }
311 return result.toString();
312 }
313 }