Source Code Cross Referenced for Main.java in  » Database-Client » LiquiBase » liquibase » commandline » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database Client » LiquiBase » liquibase.commandline 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package liquibase.commandline;
0002:
0003:        import liquibase.CompositeFileOpener;
0004:        import liquibase.FileSystemFileOpener;
0005:        import liquibase.database.Database;
0006:        import liquibase.database.DatabaseFactory;
0007:        import liquibase.diff.Diff;
0008:        import liquibase.diff.DiffResult;
0009:        import liquibase.diff.DiffStatusListener;
0010:        import liquibase.exception.CommandLineParsingException;
0011:        import liquibase.exception.JDBCException;
0012:        import liquibase.exception.ValidationFailedException;
0013:        import liquibase.lock.LockHandler;
0014:        import liquibase.log.LogFactory;
0015:        import liquibase.Liquibase;
0016:        import liquibase.util.LiquibaseUtil;
0017:        import liquibase.util.StreamUtil;
0018:        import liquibase.util.StringUtils;
0019:
0020:        import javax.xml.parsers.ParserConfigurationException;
0021:        import java.io.*;
0022:        import java.lang.reflect.Field;
0023:        import java.net.URL;
0024:        import java.net.URLClassLoader;
0025:        import java.security.AccessController;
0026:        import java.security.PrivilegedAction;
0027:        import java.sql.Connection;
0028:        import java.sql.Driver;
0029:        import java.sql.SQLException;
0030:        import java.text.DateFormat;
0031:        import java.text.ParseException;
0032:        import java.text.SimpleDateFormat;
0033:        import java.util.*;
0034:        import java.util.jar.JarEntry;
0035:        import java.util.jar.JarFile;
0036:        import java.util.logging.Level;
0037:        import java.util.logging.Logger;
0038:
0039:        /**
0040:         * Class for executing LiquiBase via the command line.
0041:         */
0042:        public class Main {
0043:            protected ClassLoader classLoader;
0044:
0045:            protected String driver;
0046:            protected String username;
0047:            protected String password;
0048:            protected String url;
0049:            protected String databaseClass;
0050:            protected String defaultSchemaName;
0051:            protected String changeLogFile;
0052:            protected String classpath;
0053:            protected String contexts;
0054:            protected Boolean promptForNonLocalDatabase = null;
0055:            protected Boolean includeSystemClasspath;
0056:            protected String defaultsFile = "liquibase.properties";
0057:
0058:            protected String currentDateTimeFunction;
0059:
0060:            protected String command;
0061:            protected Set<String> commandParams = new HashSet<String>();
0062:
0063:            protected String logLevel;
0064:
0065:            public static void main(String args[])
0066:                    throws CommandLineParsingException, IOException {
0067:                String shouldRunProperty = System
0068:                        .getProperty(Liquibase.SHOULD_RUN_SYSTEM_PROPERTY);
0069:                if (shouldRunProperty != null
0070:                        && !Boolean.valueOf(shouldRunProperty)) {
0071:                    System.out.println("LiquiBase did not run because '"
0072:                            + Liquibase.SHOULD_RUN_SYSTEM_PROPERTY
0073:                            + "' system property was set to false");
0074:                    return;
0075:                }
0076:
0077:                Main main = new Main();
0078:                if (args.length == 1 && "--help".equals(args[0])) {
0079:                    main.printHelp(System.out);
0080:                    return;
0081:                } else if (args.length == 1 && "--version".equals(args[0])) {
0082:                    System.out.println("LiquiBase Version: "
0083:                            + LiquibaseUtil.getBuildVersion()
0084:                            + StreamUtil.getLineSeparator());
0085:                    return;
0086:                }
0087:
0088:                main.parseOptions(args);
0089:
0090:                File propertiesFile = new File(main.defaultsFile);
0091:
0092:                if (propertiesFile.exists()) {
0093:                    main
0094:                            .parsePropertiesFile(new FileInputStream(
0095:                                    propertiesFile));
0096:                }
0097:                List<String> setupMessages = main.checkSetup();
0098:                if (setupMessages.size() > 0) {
0099:                    main.printHelp(setupMessages, System.out);
0100:                    return;
0101:                }
0102:
0103:                try {
0104:                    main.applyDefaults();
0105:                    main.configureClassLoader();
0106:                    main.doMigration();
0107:                } catch (Throwable e) {
0108:                    String message = e.getMessage();
0109:                    if (e.getCause() != null) {
0110:                        message = e.getCause().getMessage();
0111:                    }
0112:                    if (message == null) {
0113:                        message = "Unknown Reason";
0114:                    }
0115:
0116:                    if (e.getCause() instanceof  ValidationFailedException) {
0117:                        ((ValidationFailedException) e.getCause())
0118:                                .printDescriptiveError(System.out);
0119:                    } else {
0120:                        System.out.println("Migration Failed: " + message
0121:                                + generateLogLevelWarningMessage());
0122:                        LogFactory.getLogger().log(Level.SEVERE, message, e);
0123:                    }
0124:                    return;
0125:                }
0126:
0127:                if ("update".equals(main.command)) {
0128:                    System.out.println("Migration successful");
0129:                } else if (main.command.startsWith("rollback")
0130:                        && !main.command.endsWith("SQL")) {
0131:                    System.out.println("Rollback successful");
0132:                }
0133:            }
0134:
0135:            private static String generateLogLevelWarningMessage() {
0136:                Logger logger = LogFactory.getLogger();
0137:                if (logger == null || logger.getLevel() == null
0138:                        || (logger.getLevel().equals(Level.OFF))) {
0139:                    return "";
0140:                } else {
0141:                    return ".  For more information, use the --logLevel flag)";
0142:                }
0143:            }
0144:
0145:            /**
0146:             * On windows machines, it splits args on '=' signs.  Put it back like it was.
0147:             */
0148:            protected String[] fixupArgs(String[] args) {
0149:                List<String> fixedArgs = new ArrayList<String>();
0150:
0151:                for (int i = 0; i < args.length; i++) {
0152:                    String arg = args[i];
0153:                    if (arg.startsWith("--") && !arg.contains("=")) {
0154:                        String nextArg = null;
0155:                        if (i + 1 < args.length) {
0156:                            nextArg = args[i + 1];
0157:                        }
0158:                        if (nextArg != null && !nextArg.startsWith("--")
0159:                                && !isCommand(nextArg)) {
0160:                            arg = arg + "=" + nextArg;
0161:                            i++;
0162:                        }
0163:                    }
0164:                    fixedArgs.add(arg);
0165:                }
0166:
0167:                return fixedArgs.toArray(new String[fixedArgs.size()]);
0168:            }
0169:
0170:            protected List<String> checkSetup() {
0171:                List<String> messages = new ArrayList<String>();
0172:                if (command == null) {
0173:                    messages.add("Command not passed");
0174:                } else if (!isCommand(command)) {
0175:                    messages.add("Unknown command: " + command);
0176:                } else {
0177:                    if (username == null) {
0178:                        messages.add("--username is required");
0179:                    }
0180:                    if (url == null) {
0181:                        messages.add("--url is required");
0182:                    }
0183:
0184:                    if (isChangeLogRequired(command) && changeLogFile == null) {
0185:                        messages.add("--changeLog is required");
0186:                    }
0187:                }
0188:                return messages;
0189:            }
0190:
0191:            private boolean isChangeLogRequired(String command) {
0192:                return command.toLowerCase().startsWith("update")
0193:                        || command.toLowerCase().startsWith("rollback")
0194:                        || "validate".equals(command);
0195:            }
0196:
0197:            private boolean isCommand(String arg) {
0198:                return "migrate".equals(arg)
0199:                        || "migrateSQL".equalsIgnoreCase(arg)
0200:                        || "update".equalsIgnoreCase(arg)
0201:                        || "updateSQL".equalsIgnoreCase(arg)
0202:                        || "updateCount".equalsIgnoreCase(arg)
0203:                        || "updateCountSQL".equalsIgnoreCase(arg)
0204:                        || "rollback".equalsIgnoreCase(arg)
0205:                        || "rollbackToDate".equalsIgnoreCase(arg)
0206:                        || "rollbackCount".equalsIgnoreCase(arg)
0207:                        || "rollbackSQL".equalsIgnoreCase(arg)
0208:                        || "rollbackToDateSQL".equalsIgnoreCase(arg)
0209:                        || "rollbackCountSQL".equalsIgnoreCase(arg)
0210:                        || "futureRollbackSQL".equalsIgnoreCase(arg)
0211:                        || "tag".equalsIgnoreCase(arg)
0212:                        || "listLocks".equalsIgnoreCase(arg)
0213:                        || "dropAll".equalsIgnoreCase(arg)
0214:                        || "releaseLocks".equalsIgnoreCase(arg)
0215:                        || "status".equalsIgnoreCase(arg)
0216:                        || "validate".equalsIgnoreCase(arg)
0217:                        || "help".equalsIgnoreCase(arg)
0218:                        || "diff".equalsIgnoreCase(arg)
0219:                        || "diffChangeLog".equalsIgnoreCase(arg)
0220:                        || "generateChangeLog".equalsIgnoreCase(arg)
0221:                        || "clearCheckSums".equalsIgnoreCase(arg)
0222:                        || "dbDoc".equalsIgnoreCase(arg)
0223:                        || "changelogSync".equalsIgnoreCase(arg)
0224:                        || "changelogSyncSQL".equalsIgnoreCase(arg);
0225:            }
0226:
0227:            protected void parsePropertiesFile(InputStream propertiesInputStream)
0228:                    throws IOException, CommandLineParsingException {
0229:                Properties props = new Properties();
0230:                props.load(propertiesInputStream);
0231:
0232:                for (Map.Entry entry : props.entrySet()) {
0233:                    try {
0234:                        Field field = getClass().getDeclaredField(
0235:                                (String) entry.getKey());
0236:                        Object currentValue = field.get(this );
0237:
0238:                        if (currentValue == null) {
0239:                            String value = entry.getValue().toString().trim();
0240:                            if (field.getType().equals(Boolean.class)) {
0241:                                field.set(this , Boolean.valueOf(value));
0242:                            } else {
0243:                                field.set(this , value);
0244:                            }
0245:                        }
0246:                    } catch (Exception e) {
0247:                        throw new CommandLineParsingException(
0248:                                "Unknown parameter: '" + entry.getKey() + "'");
0249:                    }
0250:                }
0251:            }
0252:
0253:            protected void printHelp(List<String> errorMessages,
0254:                    PrintStream stream) {
0255:                stream.println("Errors:");
0256:                for (String message : errorMessages) {
0257:                    stream.println("  " + message);
0258:                }
0259:                stream.println();
0260:                printHelp(stream);
0261:            }
0262:
0263:            protected void printHelp(PrintStream stream) {
0264:                stream
0265:                        .println("Usage: java -jar liquibase.jar [options] [command]");
0266:                stream.println("");
0267:                stream.println("Standard Commands:");
0268:                stream
0269:                        .println(" update                         Updates database to current version");
0270:                stream
0271:                        .println(" updateSQL                      Writes SQL to update database to current");
0272:                stream
0273:                        .println("                                version to STDOUT");
0274:                stream
0275:                        .println(" updateCount <num>              Applies next NUM changes to the database");
0276:                stream
0277:                        .println(" updateSQL <num>                Writes SQL to apply next NUM changes");
0278:                stream
0279:                        .println("                                to the database");
0280:                stream
0281:                        .println(" rollback <tag>                 Rolls back the database to the the state is was");
0282:                stream
0283:                        .println("                                when the tag was applied");
0284:                stream
0285:                        .println(" rollbackSQL <tag>              Writes SQL to roll back the database to that");
0286:                stream
0287:                        .println("                                state it was in when the tag was applied");
0288:                stream.println("                                to STDOUT");
0289:                stream
0290:                        .println(" rollbackToDate <date/time>     Rolls back the database to the the state is was");
0291:                stream
0292:                        .println("                                at the given date/time.");
0293:                stream
0294:                        .println("                                Date Format: yyyy-MM-dd HH:mm:ss");
0295:                stream
0296:                        .println(" rollbackToDateSQL <date/time>  Writes SQL to roll back the database to that");
0297:                stream
0298:                        .println("                                state it was in at the given date/time version");
0299:                stream.println("                                to STDOUT");
0300:                stream
0301:                        .println(" rollbackCount <value>          Rolls back the last <value> change sets");
0302:                stream
0303:                        .println("                                applied to the database");
0304:                stream
0305:                        .println(" rollbackCountSQL <value>       Writes SQL to roll back the last");
0306:                stream
0307:                        .println("                                <value> change sets to STDOUT");
0308:                stream
0309:                        .println("                                applied to the database");
0310:                stream
0311:                        .println(" futureRollbackSQL              Writes SQL to roll back the database to the ");
0312:                stream
0313:                        .println("                                current state after the changes in the ");
0314:                stream
0315:                        .println("                                changeslog have been applied");
0316:                stream
0317:                        .println(" generateChangeLog              Writes Change Log XML to copy the current state");
0318:                stream
0319:                        .println("                                of the database to standard out");
0320:                stream.println("");
0321:                stream.println("Diff Commands");
0322:                stream
0323:                        .println(" diff [diff parameters]          Writes description of differences");
0324:                stream
0325:                        .println("                                 to standard out");
0326:                stream
0327:                        .println(" diffChangeLog [diff parameters] Writes Change Log XML to update");
0328:                stream
0329:                        .println("                                 the base database");
0330:                stream
0331:                        .println("                                 to the target database to standard out");
0332:                stream.println("");
0333:                stream.println("Documentation Commands");
0334:                stream
0335:                        .println(" dbDoc <outputDirectory>         Generates Javadoc-like documentation");
0336:                stream
0337:                        .println("                                 based on current database and change log");
0338:                stream.println("");
0339:                stream.println("Maintenance Commands");
0340:                stream
0341:                        .println(" tag <tag string>          'Tags' the current database state for future rollback");
0342:                stream
0343:                        .println(" status [--verbose]        Outputs count (list if --verbose) of unrun changesets");
0344:                stream
0345:                        .println(" validate                  Checks changelog for errors");
0346:                stream
0347:                        .println(" clearCheckSums            Removes all saved checksums from database log.");
0348:                stream
0349:                        .println("                           Useful for 'MD5Sum Check Failed' errors");
0350:                stream
0351:                        .println(" changelogSync             Mark all changes as executed in the database");
0352:                stream
0353:                        .println(" changelogSyncSQL          Writes SQL to mark all changes as executed ");
0354:                stream
0355:                        .println("                           in the database to STDOUT");
0356:                stream
0357:                        .println(" listLocks                 Lists who currently has locks on the");
0358:                stream.println("                           database changelog");
0359:                stream
0360:                        .println(" releaseLocks              Releases all locks on the database changelog");
0361:                stream
0362:                        .println(" dropAll                   Drop all database objects owned by user");
0363:                stream.println("");
0364:                stream.println("Required Parameters:");
0365:                stream
0366:                        .println(" --changeLogFile=<path and filename>        Migration file");
0367:                stream
0368:                        .println(" --username=<value>                         Database username");
0369:                stream
0370:                        .println(" --password=<value>                         Database password");
0371:                stream
0372:                        .println(" --url=<value>                              Database URL");
0373:                stream.println("");
0374:                stream.println("Optional Parameters:");
0375:                stream
0376:                        .println(" --classpath=<value>                        Classpath containing");
0377:                stream
0378:                        .println("                                            migration files and JDBC Driver");
0379:                stream
0380:                        .println(" --driver=<jdbc.driver.ClassName>           Database driver class name");
0381:                stream
0382:                        .println(" --databaseClass=<database.ClassName>       custom liquibase.database.Database");
0383:                stream
0384:                        .println("                                            implementation to use");
0385:                stream
0386:                        .println(" --defaultSchemaName=<name>                 Default database schema to use");
0387:                stream
0388:                        .println(" --contexts=<value>                         ChangeSet contexts to execute");
0389:                stream
0390:                        .println(" --defaultsFile=</path/to/file.properties>  File with default option values");
0391:                stream
0392:                        .println("                                            (default: ./liquibase.properties)");
0393:                stream
0394:                        .println(" --includeSystemClasspath=<true|false>      Include the system classpath");
0395:                stream
0396:                        .println("                                            in the LiquiBase classpath");
0397:                stream
0398:                        .println("                                            (default: true)");
0399:                stream
0400:                        .println(" --promptForNonLocalDatabase=<true|false>   Prompt if non-localhost");
0401:                stream
0402:                        .println("                                            databases (default: false)");
0403:                stream
0404:                        .println(" --logLevel=<level>                         Execution log level");
0405:                stream
0406:                        .println("                                            (finest, finer, fine, info,");
0407:                stream
0408:                        .println("                                            warning, severe)");
0409:                stream
0410:                        .println(" --currentDateTimeFunction=<value>          Overrides current date time function");
0411:                stream
0412:                        .println("                                            used in SQL.");
0413:                stream
0414:                        .println("                                            Useful for unsupported databases");
0415:                stream
0416:                        .println(" --help                                     Prints this message");
0417:                stream
0418:                        .println(" --version                                  Prints this version information");
0419:                stream.println("");
0420:                stream.println("Required Diff Parameters:");
0421:                stream
0422:                        .println(" --baseUsername=<value>                     Base Database username");
0423:                stream
0424:                        .println(" --basePassword=<value>                     Base Database password");
0425:                stream
0426:                        .println(" --baseUrl=<value>                          Base Database URL");
0427:                stream.println("");
0428:                stream.println("Optional Diff Parameters:");
0429:                stream
0430:                        .println(" --baseDriver=<jdbc.driver.ClassName>       Base Database driver class name");
0431:                stream.println("");
0432:                stream
0433:                        .println("Default value for parameters can be stored in a file called");
0434:                stream
0435:                        .println("'liquibase.properties' that is read from the current working directory.");
0436:                stream.println("");
0437:                stream.println("Full documentation is available at");
0438:                stream.println("http://www.liquibase.org/manual/command_line");
0439:                stream.println("");
0440:            }
0441:
0442:            public Main() {
0443:                //        options = createOptions();
0444:            }
0445:
0446:            protected void parseOptions(String[] args)
0447:                    throws CommandLineParsingException {
0448:                args = fixupArgs(args);
0449:
0450:                boolean seenCommand = false;
0451:                for (String arg : args) {
0452:                    if (isCommand(arg)) {
0453:                        this .command = arg;
0454:                        if (this .command.equalsIgnoreCase("migrate")) {
0455:                            this .command = "update";
0456:                        } else if (this .command.equalsIgnoreCase("migrateSQL")) {
0457:                            this .command = "updateSQL";
0458:                        }
0459:                        seenCommand = true;
0460:                    } else if (seenCommand) {
0461:                        commandParams.add(arg);
0462:                    } else if (arg.startsWith("--")) {
0463:                        String[] splitArg = splitArg(arg);
0464:
0465:                        String attributeName = splitArg[0];
0466:                        String value = splitArg[1];
0467:
0468:                        try {
0469:                            Field field = getClass().getDeclaredField(
0470:                                    attributeName);
0471:                            if (field.getType().equals(Boolean.class)) {
0472:                                field.set(this , Boolean.valueOf(value));
0473:                            } else {
0474:                                field.set(this , value);
0475:                            }
0476:                        } catch (Exception e) {
0477:                            throw new CommandLineParsingException(
0478:                                    "Unknown parameter: '" + attributeName
0479:                                            + "'");
0480:                        }
0481:                    } else {
0482:                        throw new CommandLineParsingException(
0483:                                "Parameters must start with a '--'");
0484:                    }
0485:                }
0486:
0487:            }
0488:
0489:            private String[] splitArg(String arg)
0490:                    throws CommandLineParsingException {
0491:                String[] splitArg = arg.split("=");
0492:                if (splitArg.length < 2) {
0493:                    throw new CommandLineParsingException("Could not parse '"
0494:                            + arg + "'");
0495:                } else if (splitArg.length > 2) {
0496:                    StringBuffer secondHalf = new StringBuffer();
0497:                    for (int j = 1; j < splitArg.length; j++) {
0498:                        secondHalf.append(splitArg[j]).append("=");
0499:                    }
0500:
0501:                    splitArg = new String[] { splitArg[0],
0502:                            secondHalf.toString().replaceFirst("=$", "") };
0503:                }
0504:
0505:                splitArg[0] = splitArg[0].replaceFirst("--", "");
0506:                return splitArg;
0507:            }
0508:
0509:            protected void applyDefaults() {
0510:                if (this .promptForNonLocalDatabase == null) {
0511:                    this .promptForNonLocalDatabase = Boolean.FALSE;
0512:                }
0513:                if (this .logLevel == null) {
0514:                    this .logLevel = "off";
0515:                }
0516:                if (this .includeSystemClasspath == null) {
0517:                    this .includeSystemClasspath = Boolean.TRUE;
0518:                }
0519:
0520:            }
0521:
0522:            protected void configureClassLoader()
0523:                    throws CommandLineParsingException {
0524:                final List<URL> urls = new ArrayList<URL>();
0525:                if (this .classpath != null) {
0526:                    String[] classpath;
0527:                    if (isWindows()) {
0528:                        classpath = this .classpath.split(";");
0529:                    } else {
0530:                        classpath = this .classpath.split(":");
0531:                    }
0532:
0533:                    for (String classpathEntry : classpath) {
0534:                        File classPathFile = new File(classpathEntry);
0535:                        if (!classPathFile.exists()) {
0536:                            throw new CommandLineParsingException(classPathFile
0537:                                    .getAbsolutePath()
0538:                                    + " does not exist");
0539:                        }
0540:                        try {
0541:                            if (classpathEntry.endsWith(".war")) {
0542:                                addWarFileClasspathEntries(classPathFile, urls);
0543:                            } else if (classpathEntry.endsWith(".ear")) {
0544:                                JarFile earZip = new JarFile(classPathFile);
0545:
0546:                                Enumeration<? extends JarEntry> entries = earZip
0547:                                        .entries();
0548:                                while (entries.hasMoreElements()) {
0549:                                    JarEntry entry = entries.nextElement();
0550:                                    if (entry.getName().toLowerCase().endsWith(
0551:                                            ".jar")) {
0552:                                        File jar = extract(earZip, entry);
0553:                                        urls.add(new URL("jar:" + jar.toURL()
0554:                                                + "!/"));
0555:                                        jar.deleteOnExit();
0556:                                    } else if (entry.getName().toLowerCase()
0557:                                            .endsWith("war")) {
0558:                                        File warFile = extract(earZip, entry);
0559:                                        addWarFileClasspathEntries(warFile,
0560:                                                urls);
0561:                                    }
0562:                                }
0563:
0564:                            } else {
0565:                                urls.add(new File(classpathEntry).toURL());
0566:                            }
0567:                        } catch (Exception e) {
0568:                            throw new CommandLineParsingException(e);
0569:                        }
0570:                    }
0571:                }
0572:                if (includeSystemClasspath) {
0573:                    classLoader = AccessController
0574:                            .doPrivileged(new PrivilegedAction<URLClassLoader>() {
0575:                                public URLClassLoader run() {
0576:                                    return new URLClassLoader(urls
0577:                                            .toArray(new URL[urls.size()]),
0578:                                            Thread.currentThread()
0579:                                                    .getContextClassLoader());
0580:                                }
0581:                            });
0582:
0583:                } else {
0584:                    classLoader = AccessController
0585:                            .doPrivileged(new PrivilegedAction<URLClassLoader>() {
0586:                                public URLClassLoader run() {
0587:                                    return new URLClassLoader(urls
0588:                                            .toArray(new URL[urls.size()]));
0589:                                }
0590:                            });
0591:                }
0592:            }
0593:
0594:            private void addWarFileClasspathEntries(File classPathFile,
0595:                    List<URL> urls) throws IOException {
0596:                URL url = new URL("jar:" + classPathFile.toURL()
0597:                        + "!/WEB-INF/classes/");
0598:                urls.add(url);
0599:                JarFile warZip = new JarFile(classPathFile);
0600:                Enumeration<? extends JarEntry> entries = warZip.entries();
0601:                while (entries.hasMoreElements()) {
0602:                    JarEntry entry = entries.nextElement();
0603:                    if (entry.getName().startsWith("WEB-INF/lib")
0604:                            && entry.getName().toLowerCase().endsWith(".jar")) {
0605:                        File jar = extract(warZip, entry);
0606:                        urls.add(new URL("jar:" + jar.toURL() + "!/"));
0607:                        jar.deleteOnExit();
0608:                    }
0609:                }
0610:            }
0611:
0612:            private File extract(JarFile jar, JarEntry entry)
0613:                    throws IOException {
0614:                // expand to temp dir and add to list
0615:                File tempFile = File.createTempFile("liquibase.tmp", null);
0616:                // read from jar and write to the tempJar file
0617:                BufferedInputStream inStream = null;
0618:
0619:                BufferedOutputStream outStream = null;
0620:                try {
0621:                    inStream = new BufferedInputStream(jar
0622:                            .getInputStream(entry));
0623:                    outStream = new BufferedOutputStream(new FileOutputStream(
0624:                            tempFile));
0625:                    int status;
0626:                    while ((status = inStream.read()) != -1) {
0627:                        outStream.write(status);
0628:                    }
0629:                } finally {
0630:                    if (outStream != null) {
0631:                        try {
0632:                            outStream.close();
0633:                        } catch (IOException ioe) {
0634:                            ;
0635:                        }
0636:                    }
0637:                    if (inStream != null) {
0638:                        try {
0639:                            inStream.close();
0640:                        } catch (IOException ioe) {
0641:                            ;
0642:                        }
0643:                    }
0644:                }
0645:
0646:                return tempFile;
0647:            }
0648:
0649:            protected void doMigration() throws Exception {
0650:                if ("help".equalsIgnoreCase(command)) {
0651:                    printHelp(System.out);
0652:                    return;
0653:                }
0654:
0655:                if ("finest".equalsIgnoreCase(logLevel)) {
0656:                    LogFactory.getLogger().setLevel(Level.FINEST);
0657:                } else if ("finer".equalsIgnoreCase(logLevel)) {
0658:                    LogFactory.getLogger().setLevel(Level.FINER);
0659:                } else if ("fine".equalsIgnoreCase(logLevel)) {
0660:                    LogFactory.getLogger().setLevel(Level.FINE);
0661:                } else if ("info".equalsIgnoreCase(logLevel)) {
0662:                    LogFactory.getLogger().setLevel(Level.INFO);
0663:                } else if ("warning".equalsIgnoreCase(logLevel)) {
0664:                    LogFactory.getLogger().setLevel(Level.WARNING);
0665:                } else if ("severe".equalsIgnoreCase(logLevel)) {
0666:                    LogFactory.getLogger().setLevel(Level.SEVERE);
0667:                } else if ("off".equalsIgnoreCase(logLevel)) {
0668:                    LogFactory.getLogger().setLevel(Level.OFF);
0669:                } else {
0670:                    throw new CommandLineParsingException("Unknown log level: "
0671:                            + logLevel);
0672:                }
0673:
0674:                FileSystemFileOpener fsOpener = new FileSystemFileOpener();
0675:                CommandLineFileOpener clOpener = new CommandLineFileOpener(
0676:                        classLoader);
0677:                Driver driver;
0678:                DatabaseFactory databaseFactory = DatabaseFactory.getInstance();
0679:                if (this .databaseClass != null) {
0680:                    databaseFactory.addDatabaseImplementation((Database) Class
0681:                            .forName(this .databaseClass, true, classLoader)
0682:                            .newInstance());
0683:                }
0684:
0685:                try {
0686:                    if (this .driver == null) {
0687:                        this .driver = databaseFactory.findDefaultDriver(url);
0688:                    }
0689:
0690:                    if (this .driver == null) {
0691:                        throw new RuntimeException(
0692:                                "Driver class was not specified and could not be determined from the url");
0693:                    }
0694:
0695:                    driver = (Driver) Class.forName(this .driver, true,
0696:                            classLoader).newInstance();
0697:                } catch (Exception e) {
0698:                    throw new RuntimeException("Cannot find database driver: "
0699:                            + e.getMessage());
0700:                }
0701:                Properties info = new Properties();
0702:                info.put("user", username);
0703:                if (password != null) {
0704:                    info.put("password", password);
0705:                }
0706:
0707:                Connection connection = driver.connect(url, info);
0708:                if (connection == null) {
0709:                    throw new JDBCException(
0710:                            "Connection could not be created to "
0711:                                    + url
0712:                                    + " with driver "
0713:                                    + driver.getClass().getName()
0714:                                    + ".  Possibly the wrong driver for the given database URL");
0715:                }
0716:
0717:                try {
0718:                    Database database = databaseFactory
0719:                            .findCorrectDatabaseImplementation(connection);
0720:                    database.setDefaultSchemaName(StringUtils
0721:                            .trimToNull(defaultSchemaName));
0722:
0723:                    if ("diff".equalsIgnoreCase(command)) {
0724:                        doDiff(database,
0725:                                createDatabaseFromCommandParams(commandParams));
0726:                        return;
0727:                    } else if ("diffChangeLog".equalsIgnoreCase(command)) {
0728:                        doDiffToChangeLog(database,
0729:                                createDatabaseFromCommandParams(commandParams));
0730:                        return;
0731:                    } else if ("generateChangeLog".equalsIgnoreCase(command)) {
0732:                        doGenerateChangeLog(database);
0733:                        return;
0734:                    }
0735:
0736:                    Liquibase liquibase = new Liquibase(changeLogFile,
0737:                            new CompositeFileOpener(fsOpener, clOpener),
0738:                            database);
0739:
0740:                    if ("listLocks".equalsIgnoreCase(command)) {
0741:                        liquibase.reportLocks(System.out);
0742:                        return;
0743:                    } else if ("releaseLocks".equalsIgnoreCase(command)) {
0744:                        LockHandler.getInstance(database).forceReleaseLock();
0745:                        System.out
0746:                                .println("Successfully released all database change log locks for "
0747:                                        + liquibase.getDatabase()
0748:                                                .getConnectionUsername()
0749:                                        + "@"
0750:                                        + liquibase.getDatabase()
0751:                                                .getConnectionURL());
0752:                        return;
0753:                    } else if ("tag".equalsIgnoreCase(command)) {
0754:                        liquibase.tag(commandParams.iterator().next());
0755:                        System.out.println("Successfully tagged "
0756:                                + liquibase.getDatabase()
0757:                                        .getConnectionUsername() + "@"
0758:                                + liquibase.getDatabase().getConnectionURL());
0759:                        return;
0760:                    } else if ("dropAll".equals(command)) {
0761:                        liquibase.dropAll();
0762:                        System.out.println("All objects dropped from "
0763:                                + liquibase.getDatabase()
0764:                                        .getConnectionUsername() + "@"
0765:                                + liquibase.getDatabase().getConnectionURL());
0766:                        return;
0767:                    } else if ("status".equalsIgnoreCase(command)) {
0768:                        boolean runVerbose = false;
0769:
0770:                        if (commandParams.contains("--verbose")) {
0771:                            runVerbose = true;
0772:                        }
0773:                        liquibase.reportStatus(runVerbose, contexts,
0774:                                getOutputWriter());
0775:                        return;
0776:                    } else if ("validate".equalsIgnoreCase(command)) {
0777:                        try {
0778:                            liquibase.validate();
0779:                        } catch (ValidationFailedException e) {
0780:                            e.printDescriptiveError(System.out);
0781:                            return;
0782:                        }
0783:                        System.out.println("No validation errors found");
0784:                        return;
0785:                    } else if ("clearCheckSums".equalsIgnoreCase(command)) {
0786:                        liquibase.clearCheckSums();
0787:                        return;
0788:                    } else if ("dbdoc".equalsIgnoreCase(command)) {
0789:                        if (commandParams.size() == 0) {
0790:                            throw new CommandLineParsingException(
0791:                                    "dbdoc requires an output directory");
0792:                        }
0793:                        if (changeLogFile == null) {
0794:                            throw new CommandLineParsingException(
0795:                                    "dbdoc requires a changeLog parameter");
0796:                        }
0797:                        liquibase.generateDocumentation(commandParams
0798:                                .iterator().next());
0799:                        return;
0800:                    }
0801:
0802:                    DateFormat dateFormat = new SimpleDateFormat(
0803:                            "yyyy-MM-dd HH:mm:ss");
0804:                    try {
0805:                        if ("update".equalsIgnoreCase(command)) {
0806:                            liquibase.update(contexts);
0807:                        } else if ("changelogSync".equalsIgnoreCase(command)) {
0808:                            liquibase.changeLogSync(contexts);
0809:                        } else if ("changelogSyncSQL".equalsIgnoreCase(command)) {
0810:                            liquibase
0811:                                    .changeLogSync(contexts, getOutputWriter());
0812:                        } else if ("updateCount".equalsIgnoreCase(command)) {
0813:                            liquibase.update(Integer.parseInt(commandParams
0814:                                    .iterator().next()), contexts);
0815:                        } else if ("updateCountSQL".equalsIgnoreCase(command)) {
0816:                            liquibase.update(Integer.parseInt(commandParams
0817:                                    .iterator().next()), contexts,
0818:                                    getOutputWriter());
0819:                        } else if ("updateSQL".equalsIgnoreCase(command)) {
0820:                            liquibase.update(contexts, getOutputWriter());
0821:                        } else if ("rollback".equalsIgnoreCase(command)) {
0822:                            if (commandParams == null) {
0823:                                throw new CommandLineParsingException(
0824:                                        "rollback requires a rollback tag");
0825:                            }
0826:                            liquibase.rollback(commandParams.iterator().next(),
0827:                                    contexts);
0828:                        } else if ("rollbackToDate".equalsIgnoreCase(command)) {
0829:                            if (commandParams == null) {
0830:                                throw new CommandLineParsingException(
0831:                                        "rollback requires a rollback date");
0832:                            }
0833:                            liquibase.rollback(dateFormat.parse(commandParams
0834:                                    .iterator().next()), contexts);
0835:                        } else if ("rollbackCount".equalsIgnoreCase(command)) {
0836:                            liquibase.rollback(Integer.parseInt(commandParams
0837:                                    .iterator().next()), contexts);
0838:
0839:                        } else if ("rollbackSQL".equalsIgnoreCase(command)) {
0840:                            if (commandParams == null) {
0841:                                throw new CommandLineParsingException(
0842:                                        "rollbackSQL requires a rollback tag");
0843:                            }
0844:                            liquibase.rollback(commandParams.iterator().next(),
0845:                                    contexts, getOutputWriter());
0846:                        } else if ("rollbackToDateSQL"
0847:                                .equalsIgnoreCase(command)) {
0848:                            if (commandParams == null) {
0849:                                throw new CommandLineParsingException(
0850:                                        "rollbackToDateSQL requires a rollback date");
0851:                            }
0852:                            liquibase.rollback(dateFormat.parse(commandParams
0853:                                    .iterator().next()), contexts,
0854:                                    getOutputWriter());
0855:                        } else if ("rollbackCountSQL".equalsIgnoreCase(command)) {
0856:                            if (commandParams == null) {
0857:                                throw new CommandLineParsingException(
0858:                                        "rollbackCountSQL requires a rollback tag");
0859:                            }
0860:
0861:                            liquibase.rollback(Integer.parseInt(commandParams
0862:                                    .iterator().next()), contexts,
0863:                                    getOutputWriter());
0864:                        } else if ("futureRollbackSQL"
0865:                                .equalsIgnoreCase(command)) {
0866:                            liquibase.futureRollbackSQL(contexts,
0867:                                    getOutputWriter());
0868:                        } else {
0869:                            throw new CommandLineParsingException(
0870:                                    "Unknown command: " + command);
0871:                        }
0872:                    } catch (ParseException e) {
0873:                        throw new CommandLineParsingException(
0874:                                "Unexpected date/time format.  Use 'yyyy-MM-dd HH:mm:ss'");
0875:                    }
0876:                } finally {
0877:                    try {
0878:                        connection.rollback();
0879:                        connection.close();
0880:                    } catch (SQLException e) {
0881:                        LogFactory.getLogger().log(Level.WARNING,
0882:                                "problem closing connection", e);
0883:                    }
0884:                }
0885:            }
0886:
0887:            private Database createDatabaseFromCommandParams(
0888:                    Set<String> commandParams)
0889:                    throws CommandLineParsingException, JDBCException {
0890:                String driver = null;
0891:                String url = null;
0892:                String username = null;
0893:                String password = null;
0894:                String defaultSchemaName = this .defaultSchemaName;
0895:
0896:                for (String param : commandParams) {
0897:                    String[] splitArg = splitArg(param);
0898:
0899:                    String attributeName = splitArg[0];
0900:                    String value = splitArg[1];
0901:                    if ("baseDriver".equalsIgnoreCase(attributeName)) {
0902:                        driver = value;
0903:                    } else if ("baseUrl".equalsIgnoreCase(attributeName)) {
0904:                        url = value;
0905:                    } else if ("baseUsername".equalsIgnoreCase(attributeName)) {
0906:                        username = value;
0907:                    } else if ("basePassword".equalsIgnoreCase(attributeName)) {
0908:                        password = value;
0909:                    } else if ("baseDefaultSchemaName"
0910:                            .equalsIgnoreCase(attributeName)) {
0911:                        defaultSchemaName = value;
0912:                    }
0913:                }
0914:
0915:                if (driver == null) {
0916:                    driver = DatabaseFactory.getInstance().findDefaultDriver(
0917:                            url);
0918:                }
0919:
0920:                Driver driverObject;
0921:                try {
0922:                    driverObject = (Driver) Class.forName(driver, true,
0923:                            classLoader).newInstance();
0924:                } catch (Exception e) {
0925:                    throw new RuntimeException("Cannot find database driver: "
0926:                            + e.getMessage());
0927:                }
0928:
0929:                Properties info = new Properties();
0930:                info.put("user", username);
0931:                info.put("password", password);
0932:
0933:                Connection connection;
0934:                try {
0935:                    connection = driverObject.connect(url, info);
0936:                } catch (SQLException e) {
0937:                    throw new JDBCException(
0938:                            "Connection could not be created to " + url + ": "
0939:                                    + e.getMessage(), e);
0940:                }
0941:                if (connection == null) {
0942:                    throw new JDBCException(
0943:                            "Connection could not be created to "
0944:                                    + url
0945:                                    + " with driver "
0946:                                    + driver.getClass().getName()
0947:                                    + ".  Possibly the wrong driver for the given database URL");
0948:                }
0949:
0950:                Database database = DatabaseFactory.getInstance()
0951:                        .findCorrectDatabaseImplementation(connection);
0952:                database.setDefaultSchemaName(defaultSchemaName);
0953:
0954:                return database;
0955:            }
0956:
0957:            private Writer getOutputWriter() {
0958:                return new OutputStreamWriter(System.out);
0959:            }
0960:
0961:            public boolean isWindows() {
0962:                return System.getProperty("os.name").startsWith("Windows ");
0963:            }
0964:
0965:            private void doDiff(Database baseDatabase, Database targetDatabase)
0966:                    throws JDBCException {
0967:                Diff diff = new Diff(baseDatabase, targetDatabase);
0968:                diff.addStatusListener(new OutDiffStatusListener());
0969:                DiffResult diffResult = diff.compare();
0970:
0971:                System.out.println("");
0972:                System.out.println("Diff Results:");
0973:                diffResult.printResult(System.out);
0974:            }
0975:
0976:            private void doDiffToChangeLog(Database baseDatabase,
0977:                    Database targetDatabase) throws JDBCException, IOException,
0978:                    ParserConfigurationException {
0979:                Diff diff = new Diff(baseDatabase, targetDatabase);
0980:                diff.addStatusListener(new OutDiffStatusListener());
0981:                DiffResult diffResult = diff.compare();
0982:
0983:                diffResult.printChangeLog(System.out, targetDatabase);
0984:            }
0985:
0986:            private void doGenerateChangeLog(Database originalDatabase)
0987:                    throws JDBCException, IOException,
0988:                    ParserConfigurationException {
0989:                Diff diff = new Diff(originalDatabase, defaultSchemaName);
0990:                diff.addStatusListener(new OutDiffStatusListener());
0991:                DiffResult diffResult = diff.compare();
0992:
0993:                PrintStream outputStream = System.out;
0994:
0995:                if (StringUtils.trimToNull(changeLogFile) != null) {
0996:                    File changeFile = new File(changeLogFile);
0997:                    outputStream = new PrintStream(changeFile);
0998:                }
0999:                diffResult.printChangeLog(outputStream, originalDatabase);
1000:            }
1001:
1002:            private static class OutDiffStatusListener implements 
1003:                    DiffStatusListener {
1004:                public void statusUpdate(String message) {
1005:                    System.err.println(message);
1006:                }
1007:            }
1008:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.