View Javadoc

1   package org.apache.maven.continuum.management;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import com.sampullara.cli.Args;
23  import com.sampullara.cli.Argument;
24  import org.apache.log4j.BasicConfigurator;
25  import org.apache.log4j.Level;
26  import org.apache.log4j.Logger;
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.factory.ArtifactFactory;
29  import org.apache.maven.artifact.manager.WagonManager;
30  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
31  import org.apache.maven.artifact.repository.ArtifactRepository;
32  import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
33  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
34  import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
35  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
36  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
37  import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
38  import org.apache.maven.artifact.resolver.ArtifactResolver;
39  import org.apache.maven.artifact.resolver.DebugResolutionListener;
40  import org.apache.maven.artifact.resolver.ResolutionListener;
41  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
42  import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
43  import org.apache.maven.continuum.management.util.PlexusFileSystemXmlApplicationContext;
44  import org.apache.maven.settings.MavenSettingsBuilder;
45  import org.apache.maven.settings.Mirror;
46  import org.apache.maven.settings.Profile;
47  import org.apache.maven.settings.Proxy;
48  import org.apache.maven.settings.Repository;
49  import org.apache.maven.settings.Server;
50  import org.apache.maven.settings.Settings;
51  import org.apache.maven.wagon.repository.RepositoryPermissions;
52  import org.codehaus.plexus.PlexusContainer;
53  import org.codehaus.plexus.PlexusContainerException;
54  import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
55  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
56  import org.codehaus.plexus.spring.PlexusClassPathXmlApplicationContext;
57  import org.codehaus.plexus.spring.PlexusContainerAdapter;
58  import org.codehaus.plexus.util.xml.Xpp3Dom;
59  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
60  
61  import java.io.File;
62  import java.io.IOException;
63  import java.net.URL;
64  import java.net.URLClassLoader;
65  import java.util.ArrayList;
66  import java.util.Collection;
67  import java.util.Collections;
68  import java.util.Iterator;
69  import java.util.List;
70  import java.util.Map;
71  import java.util.Properties;
72  
73  /**
74   * An application for performing database upgrades from old Continuum and Redback versions. A suitable tool until it
75   * is natively incorporated into Continuum itself.
76   * @version $Id: DataManagementCli.java 805287 2009-08-18 06:32:41Z ctan $
77   */
78  public class DataManagementCli
79  {
80      private static final Logger LOGGER = Logger.getLogger( DataManagementCli.class );
81  
82      private static final String JAR_FILE_PREFIX = "jar:file:";
83  
84      private static final String FILE_PREFIX = "file:";
85  
86      private static final String SPRING_CONTEXT_LOC = "!/**/META-INF/spring-context.xml";
87  
88      private static final String PLEXUS_XML_LOC = "!/**/META-INF/plexus/components.xml";
89  
90      public static void main( String[] args )
91          throws Exception
92      {
93          Commands command = new Commands();
94  
95          DatabaseFormat databaseFormat;
96          OperationMode mode;
97          SupportedDatabase databaseType;
98  
99          try
100         {
101             Args.parse( command, args );
102             if ( command.help )
103             {
104                 Args.usage( command );
105                 return;
106             }
107             if ( command.version )
108             {
109                 System.out.print( "continuum-data-management version " + getVersion() );
110                 return;
111             }
112             databaseFormat = DatabaseFormat.valueOf( command.databaseFormat );
113             mode = OperationMode.valueOf( command.mode );
114             databaseType = SupportedDatabase.valueOf( command.databaseType );
115         }
116         catch ( IllegalArgumentException e )
117         {
118             System.err.println( e.getMessage() );
119             Args.usage( command );
120             return;
121         }
122 
123         if ( command.directory.exists() && !command.directory.isDirectory() )
124         {
125             System.err.println( command.directory + " already exists and is not a directory." );
126             Args.usage( command );
127             return;
128         }
129 
130         if ( !command.overwrite && mode == OperationMode.EXPORT && command.directory.exists() )
131         {
132             System.err.println(
133                 command.directory + " already exists and will not be overwritten unless the -overwrite flag is used." );
134             Args.usage( command );
135             return;
136         }
137 
138         if ( command.buildsJdbcUrl == null && command.usersJdbcUrl == null )
139         {
140             System.err.println( "You must specify one of -buildsJdbcUrl and -usersJdbcUrl" );
141             Args.usage( command );
142             return;
143         }
144 
145         if ( command.usersJdbcUrl != null && databaseFormat == DatabaseFormat.CONTINUUM_103 )
146         {
147             System.err.println( "The -usersJdbcUrl option can not be used with Continuum 1.0.3 databases" );
148             Args.usage( command );
149             return;
150         }
151 
152         if ( SupportedDatabase.OTHER.equals( databaseType ) )
153         {
154             if ( command.driverClass == null || command.artifactId == null || command.groupId == null ||
155                 command.artifactVersion == null || command.password == null || command.username == null )
156             {
157                 System.err.println(
158                     "If OTHER databaseType is selected, -driverClass, -artifactId, -groupId, -artifactVersion, -username and -password must be provided together" );
159                 Args.usage( command );
160                 return;
161             }
162             databaseType.defaultParams = new DatabaseParams( command.driverClass, command.groupId, command.artifactId,
163                                                              command.artifactVersion, command.username,
164                                                              command.password );
165         }
166 
167         BasicConfigurator.configure();
168         if ( command.debug )
169         {
170             Logger.getRootLogger().setLevel( Level.DEBUG );
171             Logger.getLogger( "JPOX" ).setLevel( Level.DEBUG );
172         }
173         else
174         {
175             Logger.getRootLogger().setLevel( Level.INFO );
176             Logger.getLogger( "JPOX" ).setLevel( Level.WARN );
177         }
178         
179         if ( command.settings != null && !command.settings.isFile() )
180         {
181             System.err.println( command.settings + " not exists or is not a file." );
182             Args.usage( command );
183             return;
184         }
185 
186         if ( command.buildsJdbcUrl != null )
187         {
188             LOGGER.info( "Processing Continuum database..." );
189             processDatabase( databaseType, databaseFormat, mode, command.buildsJdbcUrl, command.directory,
190                              command.settings, databaseFormat.getContinuumToolRoleHint(), "data-management-jdo",
191                              "continuum", command.strict );
192         }
193 
194         if ( command.usersJdbcUrl != null )
195         {
196             LOGGER.info( "Processing Redback database..." );
197             processDatabase( databaseType, databaseFormat, mode, command.usersJdbcUrl, command.directory,
198                              command.settings, databaseFormat.getRedbackToolRoleHint(), "data-management-redback-jdo",
199                              "redback", command.strict );
200         }
201     }
202 
203     private static void processDatabase( SupportedDatabase databaseType, DatabaseFormat databaseFormat,
204                                          OperationMode mode, String jdbcUrl, File directory, File setting,
205                                          String toolRoleHint, String managementArtifactId, String configRoleHint,
206                                          boolean strict )
207         throws PlexusContainerException, ComponentLookupException, ComponentLifecycleException,
208         ArtifactNotFoundException, ArtifactResolutionException, IOException
209     {
210         String applicationVersion = getVersion();
211 
212         DatabaseParams params = new DatabaseParams( databaseType.defaultParams );
213         params.setUrl( jdbcUrl );
214 
215         PlexusClassPathXmlApplicationContext classPathApplicationContext = new PlexusClassPathXmlApplicationContext(
216             new String[]{"classpath*:/META-INF/spring-context.xml", "classpath*:/META-INF/plexus/components.xml",
217             		"classpath*:/META-INF/plexus/plexus.xml"} );
218 
219         PlexusContainerAdapter container = new PlexusContainerAdapter();
220         container.setApplicationContext( classPathApplicationContext );
221 
222         initializeWagon( container, setting );
223 
224         List<Artifact> artifacts = new ArrayList<Artifact>();
225         artifacts.addAll(
226             downloadArtifact( container, params.getGroupId(), params.getArtifactId(),
227                                             params.getVersion(), setting ) );
228         artifacts.addAll(
229             downloadArtifact( container, "org.apache.continuum", managementArtifactId,
230                                             applicationVersion, setting ) );
231         artifacts.addAll( downloadArtifact( container, "jpox", "jpox", databaseFormat.getJpoxVersion(), setting ) );
232 
233         List<String> jars = new ArrayList<String>();
234 
235         // Little hack to make it work more nicely in the IDE
236         List<String> exclusions = new ArrayList<String>();
237         URLClassLoader cp = (URLClassLoader) DataManagementCli.class.getClassLoader();
238         List<URL> jarUrls = new ArrayList<URL>();
239 
240         for ( URL url : cp.getURLs() )
241         {
242             String urlEF = url.toExternalForm();
243             if ( urlEF.endsWith( "target/classes/" ) )
244             {
245                 int idEndIdx = urlEF.length() - 16;
246                 String id = urlEF.substring( urlEF.lastIndexOf( '/', idEndIdx - 1 ) + 1, idEndIdx );
247                 // continuum-legacy included because the IDE doesn't do the proper assembly of enhanced classes and JDO metadata
248                 if ( !"data-management-api".equals( id ) && !"data-management-cli".equals( id ) &&
249                     !"continuum-legacy".equals( id ) && !"continuum-model".equals( id ) &&
250                     !"redback-legacy".equals( id ) )
251                 {
252                     LOGGER.debug( "[IDE Help] Adding '" + id + "' as an exclusion and using one from classpath" );
253                     exclusions.add( "org.apache.continuum:" + id );
254                     jars.add( url.getPath() );
255                     jarUrls.add( url );
256                 }
257             }
258 
259             // Sometimes finds its way into the IDE. Make sure it is loaded in the extra classloader too
260             if ( urlEF.contains( "jpox-enhancer" ) )
261             {
262                 LOGGER.debug( "[IDE Help] Adding 'jpox-enhancer' as an exclusion and using one from classpath" );
263                 jars.add( url.getPath() );
264                 jarUrls.add( url );
265             }
266         }
267 
268         ArtifactFilter filter = new ExcludesArtifactFilter( exclusions );
269 
270         for ( Artifact a : artifacts )
271         {
272             if ( "jpox".equals( a.getGroupId() ) && "jpox".equals( a.getArtifactId() ) )
273             {
274                 if ( a.getVersion().equals( databaseFormat.getJpoxVersion() ) )
275                 {
276                     LOGGER.debug( "Adding artifact: " + a.getFile() );
277                     jars.add( JAR_FILE_PREFIX + a.getFile().getAbsolutePath() + SPRING_CONTEXT_LOC );
278                     jars.add( JAR_FILE_PREFIX + a.getFile().getAbsolutePath() + PLEXUS_XML_LOC );
279                     jarUrls.add( new URL( FILE_PREFIX + a.getFile().getAbsolutePath() ) );
280                 }
281             }
282             else if ( filter.include( a ) )
283             {
284                 LOGGER.debug( "Adding artifact: " + a.getFile() );
285                 jars.add( JAR_FILE_PREFIX + a.getFile().getAbsolutePath() + SPRING_CONTEXT_LOC );
286                 jars.add( JAR_FILE_PREFIX + a.getFile().getAbsolutePath() + PLEXUS_XML_LOC );
287                 jarUrls.add( new URL( FILE_PREFIX + a.getFile().getAbsolutePath() ) );
288             }
289         }
290 
291         URLClassLoader newClassLoader = new URLClassLoader( (URL[]) jarUrls.toArray( new URL[jarUrls.size()] ), cp );
292         Thread.currentThread().setContextClassLoader( newClassLoader );
293         classPathApplicationContext.setClassLoader( newClassLoader );
294 
295         PlexusFileSystemXmlApplicationContext fileSystemApplicationContext = new PlexusFileSystemXmlApplicationContext(
296              (String[]) jars.toArray( new String[jars.size()] ), classPathApplicationContext );
297         fileSystemApplicationContext.setClassLoader( newClassLoader );
298         container.setApplicationContext( fileSystemApplicationContext );
299 
300         DatabaseFactoryConfigurator configurator = (DatabaseFactoryConfigurator) container.lookup( 
301                                 DatabaseFactoryConfigurator.class.getName(), configRoleHint );
302         configurator.configure( params );
303 
304         DataManagementTool manager =
305             (DataManagementTool) container.lookup( DataManagementTool.class.getName(), toolRoleHint );
306 
307         if ( mode == OperationMode.EXPORT )
308         {
309             manager.backupDatabase( directory );
310         }
311         else if ( mode == OperationMode.IMPORT )
312         {
313             manager.eraseDatabase();
314             manager.restoreDatabase( directory, strict );
315         }
316     }
317 
318     private static void initializeWagon( PlexusContainerAdapter container, File setting )
319         throws ComponentLookupException, ComponentLifecycleException, IOException
320     {
321         WagonManager wagonManager = (WagonManager) container.lookup( WagonManager.ROLE );
322 
323         Settings settings = getSettings( container, setting );
324 
325         try
326         {
327             Proxy proxy = settings.getActiveProxy();
328 
329             if ( proxy != null )
330             {
331                 if ( proxy.getHost() == null )
332                 {
333                     throw new IOException( "Proxy in settings.xml has no host" );
334                 }
335 
336                 wagonManager.addProxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), proxy.getUsername(),
337                                        proxy.getPassword(), proxy.getNonProxyHosts() );
338             }
339 
340             for ( Iterator i = settings.getServers().iterator(); i.hasNext(); )
341             {
342                 Server server = (Server) i.next();
343 
344                 wagonManager.addAuthenticationInfo( server.getId(), server.getUsername(), server.getPassword(),
345                                                     server.getPrivateKey(), server.getPassphrase() );
346 
347                 wagonManager.addPermissionInfo( server.getId(), server.getFilePermissions(),
348                                                 server.getDirectoryPermissions() );
349 
350                 if ( server.getConfiguration() != null )
351                 {
352                     wagonManager.addConfiguration( server.getId(), (Xpp3Dom) server.getConfiguration() );
353                 }
354             }
355 
356             RepositoryPermissions defaultPermissions = new RepositoryPermissions();
357 
358             defaultPermissions.setDirectoryMode( "775" );
359 
360             defaultPermissions.setFileMode( "664" );
361 
362             wagonManager.setDefaultRepositoryPermissions( defaultPermissions );
363 
364             for ( Iterator i = settings.getMirrors().iterator(); i.hasNext(); )
365             {
366                 Mirror mirror = (Mirror) i.next();
367 
368                 wagonManager.addMirror( mirror.getId(), mirror.getMirrorOf(), mirror.getUrl() );
369             }
370         }
371         finally
372         {
373             container.release( wagonManager );
374         }
375 
376     }
377 
378     private static Collection<Artifact> downloadArtifact( PlexusContainer container, String groupId, String artifactId,
379                                                           String version, File setting )
380         throws ComponentLookupException, ArtifactNotFoundException, ArtifactResolutionException, IOException
381     {
382         ArtifactRepositoryFactory factory =
383             (ArtifactRepositoryFactory) container.lookup( ArtifactRepositoryFactory.ROLE );
384 
385         DefaultRepositoryLayout layout =
386             (DefaultRepositoryLayout) container.lookup( ArtifactRepositoryLayout.ROLE, "default" );
387 
388         ArtifactRepository localRepository =
389             factory.createArtifactRepository( "local", getLocalRepositoryURL( container, setting ), layout, null, null );
390 
391         List<ArtifactRepository> remoteRepositories = new ArrayList<ArtifactRepository>();
392         remoteRepositories.add(
393             factory.createArtifactRepository( "central", "http://repo1.maven.org/maven2", layout, null, null ) );
394         //Load extra repositories from active profile
395         
396         Settings settings = getSettings( container, setting );
397         List<String> profileIds = settings.getActiveProfiles();
398         Map<String, Profile> profilesAsMap = settings.getProfilesAsMap();
399         if ( profileIds != null && !profileIds.isEmpty() )
400         {
401             for ( String profileId : profileIds )
402             {
403                 Profile profile = profilesAsMap.get( profileId );
404                 if ( profile != null )
405                 {
406                     List<Repository> repos = profile.getRepositories();
407                     if ( repos != null && !repos.isEmpty() )
408                     {
409                         for ( Repository repo : repos )
410                         {
411                             remoteRepositories.add( factory.createArtifactRepository( repo.getId(), repo.getUrl(),
412                                                                                       layout, null, null ) );
413                         }
414                     }
415                 }
416             }
417         }
418         
419         ArtifactFactory artifactFactory = (ArtifactFactory) container.lookup( ArtifactFactory.ROLE );
420         Artifact artifact =
421             artifactFactory.createArtifact( groupId, artifactId, version, Artifact.SCOPE_RUNTIME, "jar" );
422         Artifact dummyArtifact = artifactFactory.createProjectArtifact( "dummy", "dummy", "1.0" );
423 
424         if ( artifact.isSnapshot() )
425         {
426             remoteRepositories.add( factory.createArtifactRepository( "apache.snapshots",
427                                                                       "http://people.apache.org/repo/m2-snapshot-repository",
428                                                                       layout, null, null ) );
429         }
430 
431         ArtifactResolver resolver = (ArtifactResolver) container.lookup( ArtifactResolver.ROLE );
432 
433         List<String> exclusions = new ArrayList<String>();
434         exclusions.add( "org.apache.continuum:data-management-api" );
435         exclusions.add( "org.codehaus.plexus:plexus-component-api" );
436         exclusions.add( "org.codehaus.plexus:plexus-container-default" );
437         exclusions.add( "org.slf4j:slf4j-api" );
438         exclusions.add( "log4j:log4j" );
439 
440         ArtifactFilter filter = new ExcludesArtifactFilter( exclusions );
441 
442         List<? extends ResolutionListener> listeners;
443         if ( LOGGER.isDebugEnabled() )
444         {
445             listeners = Collections.singletonList( new DebugResolutionListener( container.getLogger() ) );
446         }
447         else
448         {
449             listeners = Collections.emptyList();
450         }
451 
452         ArtifactMetadataSource source =
453             (ArtifactMetadataSource) container.lookup( ArtifactMetadataSource.ROLE, "maven" );
454         ArtifactResolutionResult result =
455             resolver.resolveTransitively( Collections.singleton( artifact ), dummyArtifact, Collections.emptyMap(),
456                                           localRepository, remoteRepositories, source, filter, listeners );
457 
458         return result.getArtifacts();
459     }
460 
461     private static String getLocalRepositoryURL( PlexusContainer container, File setting )
462         throws ComponentLookupException, IOException
463     {
464         String repositoryPath;
465         File settingsFile = new File( System.getProperty( "user.home" ), ".m2/settings.xml" );
466         if ( setting != null )
467         {
468             Settings settings = getSettings( container, setting );
469             repositoryPath = new File( settings.getLocalRepository() ).toURL().toString();
470         }
471         else if ( !settingsFile.exists() )
472         {
473             repositoryPath = new File( System.getProperty( "user.home" ), ".m2/repository" ).toURL().toString();
474         }
475         else
476         {
477             Settings settings = getSettings( container, null );
478             repositoryPath = new File( settings.getLocalRepository() ).toURL().toString();
479         }
480         return repositoryPath;
481     }
482 
483     private static Settings getSettings( PlexusContainer container, File setting )
484         throws ComponentLookupException, IOException
485     {
486         MavenSettingsBuilder mavenSettingsBuilder =
487             (MavenSettingsBuilder) container.lookup( MavenSettingsBuilder.class.getName() );
488         try
489         {
490             if ( setting != null )
491             {
492                 return mavenSettingsBuilder.buildSettings( setting, false );
493             }
494             else
495             {
496                 return mavenSettingsBuilder.buildSettings( false );
497             }
498         }
499         catch ( XmlPullParserException e )
500         {
501             e.printStackTrace();
502             throw new IOException( "Can't read settings.xml. " + e.getMessage() );
503         }
504     }
505 
506     private static String getVersion()
507         throws IOException
508     {
509         Properties properties = new Properties();
510         properties.load( DataManagementCli.class.getResourceAsStream(
511             "/META-INF/maven/org.apache.continuum/data-management-api/pom.properties" ) );
512         return properties.getProperty( "version" );
513     }
514 
515     private static class Commands
516     {
517 
518         @Argument(description = "Display help information", value = "help", alias = "h")
519         private boolean help;
520 
521         @Argument(description = "Display version information", value = "version", alias = "v")
522         private boolean version;
523 
524         @Argument(
525             description = "The JDBC URL for the Continuum database that contains the data to convert, or to import the data into",
526             value = "buildsJdbcUrl")
527         private String buildsJdbcUrl;
528 
529         @Argument(
530             description = "The JDBC URL for the Redback database that contains the data to convert, or to import the data into",
531             value = "usersJdbcUrl")
532         private String usersJdbcUrl;
533 
534         // TODO: ability to use the enum directly would be nice
535         @Argument(
536             description = "Format of the database. Valid values are CONTINUUM_103, CONTINUUM_109, CONTINUUM_11. Default is CONTINUUM_11.")
537         private String databaseFormat = DatabaseFormat.CONTINUUM_11.toString();
538 
539 /* TODO: not yet supported
540         @Argument(
541             description = "Format of the backup directory. Valid values are CONTINUUM_103, CONTINUUM_109, CONTINUUM_11. Default is CONTINUUM_11.")
542         private String dataFileFormat = DatabaseFormat.CONTINUUM_11.toString();
543 */
544 
545         @Argument(
546             description = "The directory to export the data to, or import the data from. Default is 'backups' in the current working directory.",
547             value = "directory")
548         private File directory = new File( "backups" );
549 
550         @Argument(
551             description = "Mode of operation. Valid values are IMPORT and EXPORT. Default is EXPORT.",
552             value = "mode")
553         private String mode = OperationMode.EXPORT.toString();
554 
555         @Argument(
556             description = "Whether to overwrite the designated directory if it already exists in export mode. Default is false.",
557             value = "overwrite")
558         private boolean overwrite;
559 
560         @Argument(
561             description = "The type of database to use. Currently supported values are DERBY_10_1. The default value is DERBY_10_1.",
562             value = "databaseType")
563         private String databaseType = SupportedDatabase.DERBY_10_1.toString();
564 
565         @Argument(description = "JDBC driver class", value = "driverClass", required = false)
566         private String driverClass;
567 
568         @Argument(description = "JDBC driver groupId", value = "groupId", required = false)
569         private String groupId;
570 
571         @Argument(description = "JDBC driver artifactId", value = "artifactId", required = false)
572         private String artifactId;
573 
574         @Argument(description = "Artifact version of the JDBC driver class",
575                   value = "artifactVersion",
576                   required = false)
577         private String artifactVersion;
578 
579         @Argument(description = "Username", value = "username", required = false)
580         private String username;
581 
582         @Argument(description = "Password", value = "password", required = false)
583         private String password;
584 
585         @Argument(
586             description = "Turn on debugging information. Default is off.",
587             value = "debug")
588         private boolean debug;
589         
590         @Argument( description = "Alternate path for the user settings file", value = "settings", required = false, alias = "s" )
591         private File settings;
592 
593         @Argument(description = "Run on strict mode. Default is false.", value="strict")
594         private boolean strict;
595     }
596 
597     private enum OperationMode
598     {
599         IMPORT, EXPORT
600     }
601 
602     private enum SupportedDatabase
603     {
604         DERBY_10_1( new DatabaseParams( "org.apache.derby.jdbc.EmbeddedDriver", "org.apache.derby", "derby", "10.1.3.1",
605                                         "sa", "" ) ),
606 
607         OTHER( new DatabaseParams( null, null, null, null, null, null ) );
608 
609         private DatabaseParams defaultParams;
610 
611         SupportedDatabase( DatabaseParams defaultParams )
612         {
613             this.defaultParams = defaultParams;
614         }
615     }
616 }