View Javadoc

1   package org.apache.torque.engine.database.model;
2   
3   /*
4    * Copyright 2001-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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      // flag to complete initialization only once.
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         // If we haven't yet loaded the properties and we have the
110         // information to do so, proceed with loading.
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"); // Torque.getDefaultDB());
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 }