KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > storage > search > implementation > database > informix > excalibur > EtxIndexCreator


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.storage.search.implementation.database.informix.excalibur;
11
12 import java.io.*;
13 import java.sql.*;
14 import java.util.*;
15
16 import org.mmbase.util.xml.ModuleReader;
17 import org.w3c.dom.*;
18 import org.xml.sax.*;
19
20 /**
21  * The Etx index creator creates Excalibur Text Search indices,
22  * when used with an Informix database and a Excalibur Text Search datablade.
23  * This class is provided as a utility to supplement the
24  * {@link EtxSqlHandler EtxSqlHandler}.
25  * <p>
26  * When run as an application, the index creator reads a list of etx-indices
27  * from a configuration file, and creates the indices that are not present
28  * already.
29  * The configurationfile must be named <em>etxindices.xml</em> and located
30  * inside the <em>databases</em> configuration directory.
31  * It's DTD is located in the directory
32  * <code>org.mmbase.storage.search.implementation.database.informix.excalibur.resources</code>
33  * in the MMBase source tree and
34  * <a HREF="http://www.mmbase.org/dtd/etxindices.dtd">here</a> online.
35  *
36  * @author Rob van Maris
37  * @version $Id: EtxIndexCreator.java,v 1.4 2005/09/02 15:02:44 pierre Exp $
38  * @since MMBase-1.7
39  */

40 public class EtxIndexCreator {
41
42     /** Path to the MMBase configuration directory. */
43     private String JavaDoc configDir = null;
44
45     /** Database connection. */
46     private Connection con = null;
47
48     /**
49      * Creates a new instance of EtxIndexCreator, opens database connection.
50      *
51      * @param configDir Path to MMBase configuration directory.
52      */

53     public EtxIndexCreator(String JavaDoc configDir) throws Exception JavaDoc{
54         this.configDir = configDir;
55
56         // Get database connection:
57
// 1 - read database configuration
58
ModuleReader moduleReader = new ModuleReader(new InputSource(new FileInputStream(configDir + "/modules/jdbc.xml")));
59         Map properties = moduleReader.getProperties();
60         String JavaDoc url = (String JavaDoc) properties.get("url");
61         String JavaDoc host = (String JavaDoc) properties.get("host");
62         String JavaDoc port = (String JavaDoc) properties.get("port");
63         String JavaDoc database = (String JavaDoc) properties.get("database");
64         String JavaDoc user = (String JavaDoc) properties.get("user");
65         String JavaDoc password = (String JavaDoc) properties.get("password");
66         String JavaDoc driver = (String JavaDoc) properties.get("driver");
67         // 2 - construct url, substituting database, host and port when needed
68
int pos = url.indexOf("$DBM");
69         if (pos != -1) {
70             url = url.substring(0, pos) + database + url.substring(pos + 4);
71         }
72         pos = url.indexOf("$HOST");
73         if (pos !=- 1) {
74             url = url.substring(0, pos) + host + url.substring(pos + 5);
75         }
76         pos=url.indexOf("$PORT");
77         if (pos != -1) {
78             url = url.substring(0, pos) + port + url.substring(pos + 5);
79         }
80         // 3 - Load driver
81
Class.forName(driver);
82         // 4 - Create connection
83
if (user.equals("url") && password.equals("url")) {
84             con = DriverManager.getConnection(url);
85         } else {
86             con = DriverManager.getConnection(url, user, password);
87         }
88     }
89
90     /**
91      * Application main method.
92      * <p>
93      * Reads etxindices configuration file, and creates the etx indices
94      * that are not already created.
95      *
96      * @param args The command line arguments, should be path to
97      * MMBase configuration directory.
98      */

99     public static void main(String JavaDoc[] args) {
100         if (args.length != 1) {
101             System.out.println("Command line arguments not as expected,"
102                 + "should be path to MMBase configuration directory.");
103             System.exit(1);
104         }
105         try {
106             // Execute tasks.
107
new EtxIndexCreator(args[0]).execute();
108         } catch (Exception JavaDoc e) {
109             e.printStackTrace();
110         }
111     }
112
113     /**
114      * Executes the tasks: reads configuration file and creates indices
115      * as needed, and closes database connection.
116      */

117     public void execute() throws Exception JavaDoc {
118         try {
119             // Read etxindices config.
120
File etxConfigFile = new File(
121                 configDir + "/databases/etxindices.xml");
122             XmlEtxIndicesReader configReader =
123                 new XmlEtxIndicesReader(
124                     new InputSource(
125                         new BufferedReader(
126                             new FileReader(etxConfigFile))));
127
128             for (Iterator iSbspaces = configReader.getSbspaceElements(); iSbspaces.hasNext();) {
129                 Element sbspace = (Element) iSbspaces.next();
130                 String JavaDoc sbspaceName = configReader.getSbspaceName(sbspace);
131
132                 for (Iterator iEtxindices = configReader.getEtxindexElements(sbspace); iEtxindices.hasNext();) {
133                     Element etxindex = (Element) iEtxindices.next();
134                     String JavaDoc name = configReader.getEtxindexValue(etxindex);
135                     String JavaDoc table = configReader.getEtxindexTable(etxindex);
136                     String JavaDoc field = configReader.getEtxindexField(etxindex);
137                     if (!etxIndexExists(name)) {
138                         createEtxIndex(sbspaceName,
139                             name, table, field);
140                     }
141               }
142             }
143
144         } finally {
145             if (con != null) {
146                 con.close();
147             }
148         }
149     }
150
151     /**
152      * Tests if a Etx index already exists with a specified name.
153      * NOTE: Tests if the index exists, but does not verify that is is
154      * indeed an Etx index.
155      *
156      * @param etxindexName The index name.
157      * @return True if a Etx index already exists with this name,
158      * false otherwise.
159      */

160     private boolean etxIndexExists(String JavaDoc etxindexName) throws SQLException {
161         PreparedStatement ps = null;
162         ResultSet rs = null;
163         try {
164             ps = con.prepareStatement(
165                 "SELECT * FROM sysindexes WHERE idxname = ?");
166             ps.setString(1, etxindexName);
167             try {
168                 rs = ps.executeQuery();
169
170                 if (rs.next()) {
171                     System.out.println("Index " + etxindexName + " exists already.");
172                     return true;
173                 } else {
174                     System.out.println("Index " + etxindexName + " does not exist already.");
175                     return false;
176                 }
177             } finally {
178                 if (rs != null) {
179                     rs.close();
180                 }
181             }
182         } finally {
183             if (ps != null) {
184                 ps.close();
185             }
186         }
187     }
188
189     /**
190      * Creates new Etx index.
191      *
192      * @param sbspace The sbspace to use.
193      * @param name The index name.
194      * @param table The table.
195      * @param field The field.
196      */

197     private void createEtxIndex(String JavaDoc sbspace,
198         String JavaDoc name, String JavaDoc table, String JavaDoc field)
199         throws SQLException {
200             String JavaDoc operatorclass = getOperatorClass(table, field);
201             String JavaDoc sqlCreateIndex =
202                 "CREATE INDEX " + name
203                 + " ON " + table + " (" + field + " " + operatorclass
204                 + ") USING etx (CHAR_SET='OVERLAP_ISO', "
205                 + "PHRASE_SUPPORT='MAXIMUM', "
206                 + "WORD_SUPPORT='PATTERN') IN " + sbspace;
207
208             Statement st = null;
209             try {
210                 System.out.println(sqlCreateIndex);
211                 st = con.createStatement();
212                 st.executeUpdate(sqlCreateIndex);
213                 System.out.println("Index " + name + " created.");
214             } finally {
215                 if (st != null) {
216                     st.close();
217                 }
218             }
219     }
220
221     /**
222      * Determines the appropriate operator class for a field to be indexed,
223      * based on metadata retrieved from the database.
224      *
225      * @param table The table.
226      * @param field The field.
227      * @return The operator class.
228      */

229     private String JavaDoc getOperatorClass(String JavaDoc table, String JavaDoc field) throws SQLException {
230         DatabaseMetaData metadata = con.getMetaData();
231         ResultSet columninfo = metadata.getColumns(null, null, table, field);
232         try {
233             boolean hasRows = columninfo.next();
234             if (!hasRows) {
235                 throw new IllegalArgumentException JavaDoc(
236                     "The field " + field + " of table " + table
237                     + " does not exist.");
238             }
239             String JavaDoc typeName = columninfo.getString("TYPE_NAME").toLowerCase();
240             if (typeName.equals("blob")) {
241                 return "etx_blob_ops";
242             } else if (typeName.equals("clob")) {
243                 return "etx_clob_ops";
244             } else if (typeName.equals("char")) {
245                 return "etx_char_ops";
246             } else if (typeName.equals("lvarchar")) {
247                 return "etx_lvarc_ops";
248             } else if (typeName.equals("varchar")) {
249                 return ("etx_varc_ops");
250             } else {
251                 throw new IllegalArgumentException JavaDoc(
252                     "The field " + field + " of table " + table
253                     + " is not of an appropriate type for an Etx index.");
254             }
255         } finally {
256             columninfo.close();
257         }
258     }
259 }
260
Popular Tags