KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > install > InstallHelper


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.install;
17
18 import org.outerj.daisy.repository.Repository;
19 import org.outerj.daisy.repository.Credentials;
20 import org.outerj.daisy.repository.RepositoryManager;
21 import org.outerj.daisy.repository.user.Role;
22 import org.outerj.daisy.repository.clientimpl.RemoteRepositoryManager;
23 import org.outerj.daisy.jdbcutil.DriverLoader;
24 import org.outerj.daisy.configutil.PropertyResolver;
25 import org.w3c.dom.Document JavaDoc;
26 import org.w3c.dom.Element JavaDoc;
27 import org.w3c.dom.NodeList JavaDoc;
28
29 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
30 import javax.xml.parsers.DocumentBuilder JavaDoc;
31 import javax.xml.transform.TransformerFactory JavaDoc;
32 import javax.xml.transform.Transformer JavaDoc;
33 import javax.xml.transform.stream.StreamResult JavaDoc;
34 import javax.xml.transform.dom.DOMSource JavaDoc;
35 import java.io.*;
36 import java.util.Properties JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.regex.Pattern JavaDoc;
40 import java.util.regex.Matcher JavaDoc;
41 import java.nio.channels.FileChannel JavaDoc;
42 import java.security.SecureRandom JavaDoc;
43 import java.sql.DriverManager JavaDoc;
44 import java.sql.Connection JavaDoc;
45 import java.sql.DatabaseMetaData JavaDoc;
46
47 public class InstallHelper {
48     private static List JavaDoc ALL_DATABASES;
49     static {
50         ALL_DATABASES = new ArrayList JavaDoc();
51         ALL_DATABASES.add(new DatabaseInfo("MySQL-4.1.x (requires version 4.1.7 or higher)",
52                 "com.mysql.jdbc.Driver",
53                 "mysql/jars/mysql-connector-java-3.1.12-bin.jar",
54                 "jdbc:mysql://localhost/@dbname@?useServerPrepStmts=false&characterEncoding=UTF-8",
55                 new GenericDatabaseValidator("mysql", 4, 1, 7)));
56         ALL_DATABASES.add(new DatabaseInfo("MySQL-5.x",
57                 "com.mysql.jdbc.Driver",
58                 "mysql/jars/mysql-connector-java-3.1.12-bin.jar",
59                 "jdbc:mysql://localhost/@dbname@?characterEncoding=UTF-8",
60                 new GenericDatabaseValidator("mysql", 5, 0, -1)));
61         ALL_DATABASES.add(new DatabaseInfo("PostgreSQL (only for 7.4.x !! see http://cocoondev.org/daisyscratchpad/220.html)",
62                 "org.postgresql.Driver",
63                 "postgresql/jars/postgresql-7.4-215-jdbc3.jar",
64                 "jdbc:postgresql://localhost/@dbname@",
65                 new NoOpDatabaseValidator()));
66         ALL_DATABASES.add(new DatabaseInfo("ORACLE (tested for ORACLE 10g) (does not work)",
67                 "oracle.jdbc.driver.OracleDriver",
68                 "oracle/jars/ojdbc14-10.2.0.1.0.jar",
69                 "jdbc:oracle:thin:@localhost:1521:ora10g",
70                 new NoOpDatabaseValidator()));
71     }
72
73     public static class DatabaseInfo {
74         private String JavaDoc description;
75         private String JavaDoc driverClass;
76         private String JavaDoc driverPath;
77         private String JavaDoc driverUrl;
78         private DatabaseValidator validator;
79
80         public DatabaseInfo(String JavaDoc description, String JavaDoc driverClass, String JavaDoc driverPath, String JavaDoc driverUrl, DatabaseValidator validator) {
81             this.description = description;
82             this.driverClass = driverClass;
83             this.driverPath = driverPath;
84             this.driverUrl = driverUrl;
85             this.validator = validator;
86         }
87
88         public String JavaDoc getDescription() {
89             return description;
90         }
91
92         public String JavaDoc getDriverClass() {
93             return driverClass;
94         }
95
96         public String JavaDoc getDriverPath() {
97             return driverPath;
98         }
99
100         public String JavaDoc getDriverUrl(String JavaDoc dbname) {
101             return driverUrl.replaceAll("@dbname@", dbname);
102         }
103
104         public DatabaseValidator getValidator() {
105             return validator;
106         }
107     }
108
109     public static DatabaseInfo chooseDatabase() throws Exception JavaDoc {
110         System.out.println("Choose database (MySQL in the only 'officially' supported one):");
111         for (int i = 0; i < ALL_DATABASES.size(); i++) {
112             DatabaseInfo dbInfo = (DatabaseInfo)ALL_DATABASES.get(i);
113             System.out.println(" " + (i + 1) + ". " + dbInfo.getDescription());
114         }
115         System.out.println();
116         int dbIndex = Integer.parseInt(prompt("Choose database type [enter number, default 1] : ", "1"));
117         if (dbIndex < 1 || dbIndex > ALL_DATABASES.size()) {
118             System.out.println("Number too large or small, quiting.");
119             System.exit(1);
120         }
121         return (DatabaseInfo)ALL_DATABASES.get(dbIndex - 1);
122     }
123
124     public static class DatabaseParams {
125         private final String JavaDoc url;
126         private final String JavaDoc user;
127         private final String JavaDoc password;
128         private final String JavaDoc driverClassName;
129         private final String JavaDoc driverClassPath;
130         private final DatabaseValidator validator;
131
132         public DatabaseParams(String JavaDoc url, String JavaDoc user, String JavaDoc password, String JavaDoc driverClassName, String JavaDoc driverClassPath) {
133             this(url, user, password, driverClassName, driverClassPath, null);
134         }
135
136         public DatabaseParams(String JavaDoc url, String JavaDoc user, String JavaDoc password, String JavaDoc driverClassName, String JavaDoc driverClassPath,
137                 DatabaseValidator validator) {
138             this.url = url;
139             this.user = user;
140             this.password = password;
141             this.driverClassName = driverClassName;
142             this.driverClassPath = driverClassPath;
143             this.validator = validator;
144         }
145
146         public String JavaDoc getUrl() {
147             return url;
148         }
149
150         public String JavaDoc getUser() {
151             return user;
152         }
153
154         public String JavaDoc getPassword() {
155             return password;
156         }
157
158         public String JavaDoc getDriverClassName() {
159             return driverClassName;
160         }
161
162         public String JavaDoc getDriverClassPath() {
163             return driverClassPath;
164         }
165
166         public void loadDriver() throws Exception JavaDoc {
167             DriverLoader.loadDatabaseDriver(PropertyResolver.resolveProperties(driverClassPath), driverClassName);
168         }
169
170         public void checkDatabase() throws Exception JavaDoc {
171             Connection JavaDoc conn = null;
172             try {
173                 conn = DriverManager.getConnection(getUrl(), getUser(), getPassword());
174                 if (validator != null)
175                     validator.validate(conn);
176             } finally {
177                 if (conn != null)
178                     conn.close();
179             }
180         }
181     }
182
183     public static DatabaseParams collectDatabaseParams(DatabaseInfo dbInfo, String JavaDoc user, String JavaDoc password, String JavaDoc dbName) throws Exception JavaDoc {
184         String JavaDoc dbUrl = dbInfo.getDriverUrl(dbName);
185         dbUrl = InstallHelper.prompt("Enter database URL [default = " + dbUrl + "] : ", dbUrl);
186         String JavaDoc dbUser = InstallHelper.prompt("Enter database user [default = " + user + "] : ", user);
187         String JavaDoc dbPassword = InstallHelper.prompt("Enter database password [default = " + password + "] : ", password);
188
189         String JavaDoc dbDriverClassName = dbInfo.getDriverClass();
190         dbDriverClassName = InstallHelper.prompt("Enter database driver class [default = " + dbDriverClassName + "] : ", dbDriverClassName);
191
192         String JavaDoc dbDriverClasspath = getRepoLocation() + "/" + dbInfo.getDriverPath();
193         dbDriverClasspath = InstallHelper.prompt("Enter database driver jar location [default = " + dbDriverClasspath + "] : ", dbDriverClasspath);
194
195         DatabaseParams dbParams = new DatabaseParams(dbUrl, dbUser, dbPassword, dbDriverClassName, dbDriverClasspath, dbInfo.getValidator());
196         System.out.println("Registering driver...");
197         dbParams.loadDriver();
198         System.out.println("Successful.");
199         System.out.println();
200
201         return dbParams;
202     }
203
204     public static String JavaDoc getRepoLocation() {
205         String JavaDoc daisyHome = System.getProperty("daisy.home");
206         String JavaDoc repoLocation;
207         if (daisyHome != null) {
208             repoLocation = "${daisy.home}" + File.separator + "lib";
209         } else {
210             repoLocation = System.getProperty("user.home") + "/.maven/repository";
211         }
212         return repoLocation;
213     }
214
215     public static File getDaisyHome() throws Exception JavaDoc {
216         String JavaDoc daisyHomeProp = System.getProperty("daisy.home");
217
218         if (daisyHomeProp == null)
219             throw new Exception JavaDoc("System property daisy.home missing.");
220
221         File daisyHome = new File(daisyHomeProp);
222         if (!daisyHome.exists() || !daisyHome.isDirectory())
223             throw new Exception JavaDoc("daisy.home does not point to an existing directory");
224
225         return daisyHome;
226     }
227
228     public static File getDaisySourceHome() throws Exception JavaDoc {
229         String JavaDoc daisySourceHomeProp = System.getProperty("daisy.sourcehome");
230
231         if (daisySourceHomeProp == null)
232             throw new Exception JavaDoc("System property daisy.sourcehome missing.");
233
234         File daisySourceHome = new File(daisySourceHomeProp);
235         if (!daisySourceHome.exists() || !daisySourceHome.isDirectory())
236             throw new Exception JavaDoc("daisy.sourcehome does not point to an existing directory");
237
238         return daisySourceHome;
239     }
240
241     public static boolean isDevelopmentSetup() {
242         return System.getProperty("daisy.home") == null;
243     }
244
245     public static boolean isDistroDirectory(File daisyHome) {
246         // if there is a directory called 'repository-server', assume we're in the distro home
247
File file = new File(daisyHome, "repository-server");
248         return file.exists();
249     }
250
251     public static String JavaDoc prompt(String JavaDoc message) throws Exception JavaDoc {
252         System.out.println(message);
253         System.out.flush();
254         String JavaDoc input = null;
255         while (input == null || input.trim().equals("")) {
256             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
257             try {
258                 input = in.readLine();
259             } catch (IOException e) {
260                 throw new Exception JavaDoc("Error reading input from console.", e);
261             }
262         }
263         return input;
264     }
265
266     public static String JavaDoc prompt(String JavaDoc message, String JavaDoc defaultInput) throws Exception JavaDoc {
267         System.out.println(message);
268         System.out.flush();
269         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
270         String JavaDoc input;
271         try {
272             input = in.readLine();
273         } catch (IOException e) {
274             throw new Exception JavaDoc("Error reading input from console.", e);
275         }
276         if (input == null || input.trim().equals(""))
277             input = defaultInput;
278         return input;
279     }
280
281     public static boolean promptYesNo(String JavaDoc message, boolean defaultInput) throws Exception JavaDoc {
282         String JavaDoc input = "";
283         while (!input.equals("yes") && !input.equals("no")) {
284             input = prompt(message, defaultInput ? "yes" : "no");
285             input = input.toLowerCase();
286         }
287         return input.equals("yes");
288     }
289
290     public static void waitPrompt() throws Exception JavaDoc {
291         promptYesNo("Press enter to continue.", true);
292     }
293
294     public static void printTitle(String JavaDoc title) {
295         System.out.println("--------------------------------------------------------------------------");
296         System.out.println(title);
297         System.out.println("--------------------------------------------------------------------------");
298     }
299
300     public static String JavaDoc generatePassword() throws Exception JavaDoc {
301         byte[] bytes = new byte[15];
302         SecureRandom JavaDoc random = SecureRandom.getInstance("SHA1PRNG");
303         random.nextBytes(bytes);
304         return toHexString(bytes);
305     }
306
307     public static String JavaDoc toHexString(byte[] b) {
308         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(b.length * 2);
309         for (int i = 0; i < b.length; i++) {
310             sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
311             sb.append(hexChar[b[i] & 0x0f]);
312         }
313         return sb.toString();
314     }
315
316     static char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
317
318     public static Properties JavaDoc loadDistroProperties(File daisyHome) throws Exception JavaDoc {
319         Properties JavaDoc properties = new Properties JavaDoc();
320         File config = new File(daisyHome, "config.properties");
321         if (config.exists()) {
322             properties.load(new FileInputStream(config));
323         }
324         return properties;
325     }
326
327     public static void storeDistroProperties(Properties JavaDoc properties, File daisyHome) throws Exception JavaDoc {
328         File config = new File(daisyHome, "config.properties");
329         properties.store(new FileOutputStream(config), null);
330     }
331
332     public static void copyFile(File source, File destination) throws Exception JavaDoc {
333         if (source.isDirectory()) {
334             destination.mkdirs();
335             File[] files = source.listFiles();
336             for (int i = 0; i < files.length; i++) {
337                 copyFile(files[i], new File(destination, files[i].getName()));
338             }
339         } else {
340             destination.getParentFile().mkdirs();
341             destination.createNewFile();
342             copyFileFile(source, destination);
343         }
344     }
345
346     private static void copyFileFile(File source, File destination) throws Exception JavaDoc {
347         FileChannel JavaDoc srcChannel = new FileInputStream(source).getChannel();
348         FileChannel JavaDoc dstChannel = new FileOutputStream(destination).getChannel();
349         dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
350         srcChannel.close();
351         dstChannel.close();
352     }
353
354     public static void deleteFile(File file) {
355         if (file.isDirectory()) {
356             File[] files = file.listFiles();
357             for (int i = 0; i < files.length; i++)
358                 deleteFile(files[i]);
359         }
360         file.delete();
361     }
362
363     public static void copyStream(InputStream source, File destination) throws Exception JavaDoc {
364         FileOutputStream os = null;
365         try {
366             os = new FileOutputStream(destination);
367             byte[] buffer = new byte[32768];
368             int read;
369             while ((read = source.read(buffer)) != -1) {
370                 os.write(buffer, 0, read);
371             }
372         } finally {
373             if (source != null)
374                 source.close();
375             if (os != null)
376                 os.close();
377         }
378     }
379
380     public static Repository promptRepository() throws Exception JavaDoc {
381         System.out.println(" == Login To Daisy Repository Server ==");
382         String JavaDoc url = InstallHelper.prompt("Address where the Daisy Repository Server is listening [default = http://localhost:9263] :", "http://localhost:9263");
383         System.out.println("Enter login (user) and password for Daisy (this should be a user with the Administrator role):");
384         String JavaDoc login = InstallHelper.prompt("Enter login: ");
385         String JavaDoc pwd = InstallHelper.prompt("Enter password: ");
386         System.out.println();
387         Credentials credentials = new Credentials(login, pwd);
388
389         RepositoryManager repositoryManager = new RemoteRepositoryManager(url, credentials);
390         Repository repository = repositoryManager.getRepository(credentials);
391         repository.switchRole(Role.ADMINISTRATOR);
392         return repository;
393     }
394
395     public static File promptForEmptyDir(String JavaDoc message, String JavaDoc defaultPath) throws Exception JavaDoc {
396         File dir;
397         while (true) {
398             // defaultPath is optional
399
String JavaDoc dirInput = defaultPath == null ? InstallHelper.prompt(message) : InstallHelper.prompt(message + " [ default = " + defaultPath + "]", defaultPath);
400             dir = new File(dirInput);
401             if (dir.exists() && !dir.isDirectory()) {
402                 System.out.println("\nThe specified path exists and is not a directory.");
403                 continue;
404             } else if (dir.exists() && dir.list().length > 0) {
405                 System.out.println("\nThe specified directory exists and is not empty.");
406                 continue;
407             }
408             break;
409         }
410         return dir;
411     }
412
413     public static void backupFile(File file) throws Exception JavaDoc {
414         File backupFile = new File(file.getAbsolutePath() + ".backup");
415         InstallHelper.copyFile(file, backupFile);
416         System.out.println("Made backup file " + backupFile.getAbsolutePath());
417     }
418
419     public static Document JavaDoc parseFile(File file) throws Exception JavaDoc {
420         DocumentBuilderFactory JavaDoc documentBuilderFactory = DocumentBuilderFactory.newInstance();
421         documentBuilderFactory.setNamespaceAware(true);
422         DocumentBuilder JavaDoc documentBuilder = documentBuilderFactory.newDocumentBuilder();
423         return documentBuilder.parse(file);
424     }
425
426     public static void saveDocument(File file, Document JavaDoc document) throws Exception JavaDoc {
427         TransformerFactory JavaDoc transformerFactory = TransformerFactory.newInstance();
428         Transformer JavaDoc transformer = transformerFactory.newTransformer();
429         DOMSource JavaDoc source = new DOMSource JavaDoc(document);
430         StreamResult JavaDoc result = new StreamResult JavaDoc(file);
431         transformer.setOutputProperty("encoding", "UTF-8");
432         transformer.transform(source, result);
433     }
434
435     public static void setElementValue(Element JavaDoc element, String JavaDoc value) {
436         NodeList JavaDoc nodes = element.getChildNodes();
437         for (int i = 0; i < nodes.getLength(); i++)
438             element.removeChild(nodes.item(i));
439
440         element.appendChild(element.getOwnerDocument().createTextNode(value));
441     }
442
443     /**
444      * Gets the property value for a given key
445      * @param props Object containing the properties
446      * @param key Key for which a value should be returned
447      * @return Value of the property
448      * @throws PropertyNotFoundException Thrown if the property is not found;
449      */

450     public static String JavaDoc getPropertyValue (Properties JavaDoc props, String JavaDoc key) throws PropertyNotFoundException {
451         if ((props.containsKey(key))&&(props.getProperty(key)!=null)){
452             return props.getProperty(key);
453         }else {
454             throw new PropertyNotFoundException(key);
455         }
456     }
457
458     /**
459      * Gets the property value for a given key. If the key is not found the default value will be returned.
460      * @param props Object containing the properties
461      * @param key Key for which a value should be returned
462      * @param defaultValue Value returned if the value for the key is not found
463      * @return Value of the property
464      */

465     public static String JavaDoc getPropertyValue (Properties JavaDoc props, String JavaDoc key, String JavaDoc defaultValue) {
466         String JavaDoc value = defaultValue;
467         try {
468             value = getPropertyValue(props, key);
469         } catch (PropertyNotFoundException e) {
470             System.out.println("Value for property " + key + " not found. Falling back to a default value.");
471         }
472         return value;
473     }
474
475     static interface DatabaseValidator {
476         void validate(Connection JavaDoc conn) throws Exception JavaDoc;
477     }
478
479     static class NoOpDatabaseValidator implements DatabaseValidator {
480         public void validate(Connection JavaDoc conn) throws Exception JavaDoc {
481             // do nothing
482
}
483     }
484
485     static class GenericDatabaseValidator implements DatabaseValidator {
486         private String JavaDoc databaseProductName;
487         private int majorVersion;
488         private int minorVersion;
489         private int patchVersion;
490
491         public GenericDatabaseValidator(String JavaDoc databaseProductName, int majorVersion, int minorVersion, int patchVersion) {
492             this.databaseProductName = databaseProductName;
493             this.majorVersion = majorVersion;
494             this.minorVersion = minorVersion;
495             this.patchVersion = patchVersion;
496         }
497
498         public void validate(Connection JavaDoc conn) throws Exception JavaDoc {
499             DatabaseMetaData JavaDoc metadata = conn.getMetaData();
500
501             String JavaDoc dbProductName = metadata.getDatabaseProductName();
502             if (!dbProductName.equalsIgnoreCase(databaseProductName)) {
503                 System.out.println(" *** WARNING ***");
504                 System.out.println("Database reported it is \"" + dbProductName + "\" but \"" + databaseProductName + "\" was expected.");
505                 if (!promptYesNo("Continue anyway? [yes/no, default: no]", false)) {
506                     System.exit(1);
507                 } else {
508                     // further checks won't make sense anymore
509
return;
510                 }
511             }
512
513             System.out.println("Detected database version: " + metadata.getDatabaseProductVersion());
514
515             int foundMajorVersion = metadata.getDatabaseMajorVersion();
516             int foundMinorVersion = metadata.getDatabaseMinorVersion();
517             if (foundMajorVersion != majorVersion || foundMinorVersion != minorVersion) {
518                 System.out.println(" *** WARNING ***");
519                 System.out.println("Expected database product version " + majorVersion + "." + minorVersion + " but instead found " + foundMajorVersion + "." + foundMinorVersion);
520                 if (!promptYesNo("Continue anyway? [yes/no, default: no]", false)) {
521                     System.exit(1);
522                 } else {
523                     return;
524                 }
525             }
526
527             // check patch version if desired, this code is probably quite mysql specific
528
if (patchVersion != -1) {
529                 Pattern JavaDoc versionPattern = Pattern.compile("([0-9]+)\\.([0-9]+)\\.([0-9]+).*");
530                 Matcher JavaDoc versionMatcher = versionPattern.matcher(metadata.getDatabaseProductVersion());
531                 if (versionMatcher.matches()) {
532                     int majorVersion = Integer.parseInt(versionMatcher.group(1));
533                     int minorVersion = Integer.parseInt(versionMatcher.group(2));
534                     int patchVersion = Integer.parseInt(versionMatcher.group(3));
535
536                     if (patchVersion < this.patchVersion) {
537                         String JavaDoc version = majorVersion + "." + minorVersion + "." + patchVersion;
538                         String JavaDoc recommendedVersion = majorVersion + "." + minorVersion + "." + patchVersion;
539                         System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++");
540                         System.out.println(" WARNING: you are using " + databaseProductName + " version " + version);
541                         System.out.println(" but for Daisy we recommend at least " + recommendedVersion);
542                         System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++");
543                     }
544                 } else {
545                     System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
546                     System.out.println(" Warning: unrecognized version string: " + metadata.getDatabaseProductName());
547                     System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
548                 }
549             }
550         }
551
552     }
553 }
554
Popular Tags