View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  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,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.mailboxmanager.torque;
21  
22  import java.io.File;
23  import java.sql.Connection;
24  import java.sql.DatabaseMetaData;
25  import java.sql.ResultSet;
26  import java.sql.SQLException;
27  import java.util.HashMap;
28  import java.util.Locale;
29  
30  import org.apache.avalon.framework.configuration.ConfigurationException;
31  import org.apache.avalon.framework.logger.Logger;
32  import org.apache.commons.configuration.BaseConfiguration;
33  import org.apache.commons.configuration.PropertiesConfiguration;
34  import org.apache.commons.logging.impl.AvalonLogger;
35  import org.apache.james.imap.api.display.HumanReadableText;
36  import org.apache.james.imap.mailbox.MailboxException;
37  import org.apache.james.mailboxmanager.torque.om.MailboxRowPeer;
38  import org.apache.james.mailboxmanager.torque.om.MessageBodyPeer;
39  import org.apache.james.mailboxmanager.torque.om.MessageFlagsPeer;
40  import org.apache.james.mailboxmanager.torque.om.MessageHeaderPeer;
41  import org.apache.james.mailboxmanager.torque.om.MessageRowPeer;
42  import org.apache.james.services.FileSystem;
43  import org.apache.james.util.sql.SqlResources;
44  import org.apache.torque.Torque;
45  import org.apache.torque.TorqueException;
46  import org.apache.torque.util.BasePeer;
47  import org.apache.torque.util.Transaction;
48  
49  public class DefaultMailboxManager extends TorqueMailboxManager {
50  
51      private static final String[] tableNames = new String[] {
52          MailboxRowPeer.TABLE_NAME, MessageRowPeer.TABLE_NAME,
53          MessageHeaderPeer.TABLE_NAME, MessageBodyPeer.TABLE_NAME,
54          MessageFlagsPeer.TABLE_NAME };
55      
56      private BaseConfiguration torqueConf;
57  
58      private boolean initialized;
59  
60      private final FileSystem fileSystem;
61      private String configFile;
62      
63      public DefaultMailboxManager(UserManager userManager, FileSystem fileSystem, Logger logger) {
64          super(userManager);
65          this.fileSystem = fileSystem;
66          log = new AvalonLogger(logger);
67      }
68  
69      
70      public void initialize() throws Exception {
71          if (!initialized) {
72              if (torqueConf == null) {
73                  throw new RuntimeException("must be configured first!");
74              }
75              if (Torque.isInit()) {
76                  throw new RuntimeException("Torque is already initialized!");
77              }
78              Connection conn = null;
79              try {
80                  Torque.init(torqueConf);
81                  conn = Transaction.begin(MailboxRowPeer.DATABASE_NAME);
82                  SqlResources sqlResources = new SqlResources();
83                  sqlResources.init(fileSystem.getResource(configFile),
84                          DefaultMailboxManager.class.getName(), conn,
85                          new HashMap());
86  
87                  DatabaseMetaData dbMetaData = conn.getMetaData();
88  
89                  for (int i = 0; i < tableNames.length; i++) {
90                      if (!tableExists(dbMetaData, tableNames[i])) {
91                          BasePeer.executeStatement(sqlResources
92                                  .getSqlString("createTable_" + tableNames[i]),
93                                  conn);
94                          System.out.println("Created table " + tableNames[i]);
95                          getLog().info("Created table " + tableNames[i]);
96                      }
97                  }
98  
99                  Transaction.commit(conn);
100                 initialized = true;
101                 System.out.println("MailboxManager has been initialized");
102                 getLog().info("MailboxManager has been initialized");
103             } catch (Exception e) {
104                 System.err
105                         .println("============================================");
106                 e.printStackTrace();
107                 System.err
108                         .println("--------------------------------------------");
109                 Transaction.safeRollback(conn);
110                 try {
111                     Torque.shutdown();
112                 } catch (TorqueException e1) {
113 
114                 }
115                 throw new MailboxException(new HumanReadableText("org.apache.james.imap.INIT_FAILED", "Initialisation failed"), e);
116             }
117         }
118     }
119 
120     public void configureDefaults()
121             throws org.apache.commons.configuration.ConfigurationException {
122         File torqueConfigFile = new File("torque.properties");
123         if (torqueConfigFile.canRead()) {
124             getLog().info("reading torque.properties...");
125             torqueConf = new PropertiesConfiguration(torqueConfigFile);
126         } else {
127             torqueConf = new BaseConfiguration();
128             torqueConf.addProperty("torque.database.default", "mailboxmanager");
129             torqueConf.addProperty("torque.database.mailboxmanager.adapter",
130                     "derby");
131             torqueConf.addProperty("torque.dsfactory.mailboxmanager.factory",
132                     "org.apache.torque.dsfactory.SharedPoolDataSourceFactory");
133             torqueConf.addProperty(
134                     "torque.dsfactory.mailboxmanager.connection.driver",
135                     "org.apache.derby.jdbc.EmbeddedDriver");
136             torqueConf.addProperty(
137                     "torque.dsfactory.mailboxmanager.connection.url",
138                     "jdbc:derby:target/testdb;create=true");
139             torqueConf.addProperty(
140                     "torque.dsfactory.mailboxmanager.connection.user", "app");
141             torqueConf.addProperty(
142                     "torque.dsfactory.mailboxmanager.connection.password",
143                     "app");
144             torqueConf.addProperty(
145                     "torque.dsfactory.mailboxmanager.pool.maxActive", "100");
146         }
147         configFile = "file://conf/mailboxManagerSqlResources.xml";
148     }
149 
150     public void configure(
151             org.apache.avalon.framework.configuration.Configuration conf)
152             throws ConfigurationException {
153         torqueConf = new BaseConfiguration();
154         org.apache.avalon.framework.configuration.Configuration[] tps = conf
155                 .getChild("torque-properties").getChildren("property");
156         for (int i = 0; i < tps.length; i++) {
157             torqueConf.addProperty(tps[i].getAttribute("name"), tps[i]
158                     .getAttribute("value"));
159         }
160         configFile = conf.getChild("configFile").getValue();
161         if (configFile == null) configFile = "file://conf/mailboxManagerSqlResources.xml";
162     }
163 
164     private boolean tableExists(DatabaseMetaData dbMetaData, String tableName)
165             throws SQLException {
166         return (tableExistsCaseSensitive(dbMetaData, tableName)
167                 || tableExistsCaseSensitive(dbMetaData, tableName
168                         .toUpperCase(Locale.US)) || tableExistsCaseSensitive(
169                 dbMetaData, tableName.toLowerCase(Locale.US)));
170     }
171 
172     private boolean tableExistsCaseSensitive(DatabaseMetaData dbMetaData,
173             String tableName) throws SQLException {
174         ResultSet rsTables = dbMetaData.getTables(null, null, tableName, null);
175         try {
176             boolean found = rsTables.next();
177             return found;
178         } finally {
179             if (rsTables != null) {
180                 rsTables.close();
181             }
182         }
183     }
184 }