View Javadoc
1   package com.atlassian.dbexporter;
2   
3   import com.atlassian.activeobjects.spi.ImportExportException;
4   import com.atlassian.dbexporter.importer.ImportConfiguration;
5   import com.atlassian.dbexporter.importer.Importer;
6   import com.atlassian.dbexporter.importer.NoOpImporter;
7   import com.atlassian.dbexporter.node.NodeParser;
8   import com.atlassian.dbexporter.node.NodeStreamReader;
9   import com.atlassian.dbexporter.progress.ProgressMonitor;
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  import java.util.List;
14  
15  import static com.atlassian.dbexporter.DatabaseInformations.database;
16  import static com.atlassian.dbexporter.importer.ImporterUtils.checkStartNode;
17  import static com.atlassian.dbexporter.node.NodeBackup.RootNode;
18  import static com.google.common.base.Preconditions.checkArgument;
19  import static com.google.common.base.Preconditions.checkNotNull;
20  import static com.google.common.collect.Lists.newArrayList;
21  
22  /**
23   * <p>Loads the data from a platform-independent backup file into the database.</p>
24   * <p>What data is actually imported in the database depends heavily on both, the backup provided, and also the
25   * importers that are passed-in</p>
26   *
27   * @author Erik van Zijst
28   * @author Samuel Le Berrigaud
29   */
30  public final class DbImporter {
31      private final Logger logger = LoggerFactory.getLogger(this.getClass());
32  
33      private final ImportExportErrorService errorService;
34      private final List<Importer> importers;
35  
36      public DbImporter(ImportExportErrorService errorService, final Importer... importers) {
37          this(errorService, newArrayList(checkNotNull(importers)));
38      }
39  
40      public DbImporter(ImportExportErrorService errorService, final List<Importer> importers) {
41          this.errorService = checkNotNull(errorService);
42          checkArgument(!checkNotNull(importers).isEmpty(), "DbImporter must be created with at least one importer!");
43          this.importers = importers;
44      }
45  
46      /**
47       * Imports the XML document read from the stream
48       *
49       * @param streamReader  the XML stream reader
50       * @param configuration the import configuration
51       * @throws IllegalStateException if the backup XML stream is not formatted as expected.
52       * @throws ImportExportException or one of its sub-types if an unexpected exception happens during the import.
53       */
54      public void importData(NodeStreamReader streamReader, ImportConfiguration configuration) {
55          final ProgressMonitor monitor = configuration.getProgressMonitor();
56          final DatabaseInformations.Database database = database(configuration.getDatabaseInformation());
57  
58          monitor.begin(database);
59  
60          final NodeParser node = RootNode.get(streamReader);
61          logger.debug("Root node is {}", node);
62  
63          checkStartNode(node, RootNode.NAME);
64          node.getNextNode();//  starting with the first node
65  
66          final Context context = new Context();
67  
68          logger.debug("Starting import from node {}", node);
69          do {
70              getImporter(node).importNode(node, configuration, context);
71          }
72          while (!(node.getName().equals(RootNode.NAME) && node.isClosed()));
73  
74          monitor.end(database);
75      }
76  
77      private Importer getImporter(NodeParser node) {
78          for (Importer importer : importers) {
79              if (importer.supports(node)) {
80                  logger.debug("Found importer {} for node {}", importer, node);
81                  return importer;
82              }
83          }
84          final NoOpImporter noOpImporter = new NoOpImporter(errorService);
85          logger.debug("Didn't find any importer for node {}, using {}", node, noOpImporter);
86          return noOpImporter;
87      }
88  }