View Javadoc

1   /* $Id: Dump.java,v 1.7 2006/01/10 16:36:57 psionides Exp $ */
2   package net.sourceforge.jdbdump.dump;
3   
4   import java.io.IOException;
5   import java.io.ObjectInputStream;
6   import java.io.Serializable;
7   import java.util.Vector;
8   
9   import net.sourceforge.jdbdump.connect.DatabaseConnector;
10  
11  import org.apache.log4j.Logger;
12  
13  /***
14   * Represents the entire database structure downloaded into memory.
15   * <br /><br />
16   * A typical process of dumping a database looks like the following:
17   * <ol>
18   * <li>gui class creates a DatabaseConnector and connects it using connect()</li>
19   * <li>gui calls DatabaseConnector.dump(), which creates a Dump</li>
20   * <li>then it calls DumpFileManager.exportDump(dump), which saves it and its data to a file</li>
21   * <li>finally, it disconnects DatabaseConnector using disconnect()</li>
22   * </ol>
23   * And a process of restoring a database looks like the following:
24   * <ol>
25   * <li>gui class creates a DatabaseConnector and connects it using connect()</li>
26   * <li>then it calls DumpFileManager.importDump() which reads the dump back from a file</li>
27   * <li>then it calls DatabaseConnector.restore(dump), which uploads the dump and its data
28   *     into a database</li>
29   * <li>finally, it disconnects DatabaseConnector using disconnect(), and closes the input
30   *     file using Dump.closeFileReader()</li>
31   * </ol>
32   * <br />
33   * It is important to know that when the dump object is constructed, either by dump() or importDump(),
34   * it doesn't mean that it already contains all the data it needs. To minimize memory usage, Dump
35   * stores only database structure, but not its data. The data is read from a file or database later,
36   * in exportDump() or restore(), and copied on the fly to the destination place. So, when a Dump is
37   * created by dump(), the Connection object which was used to create is must be available until all
38   * the data is downloaded in exportDump(); and when a Dump is created by importDump(), the
39   * file input stream used to load it must not be closed until the data is downloaded in
40   * restore().
41   * <br /><br />
42   * In both cases, the data is read by the same methods initializeData() and getDataLine() (see Table
43   * class). A Table knows where to get the data from by checking the "mode" in which its parent Dump
44   * is, which can be either "database read mode" or "file read mode". It can be set by calling
45   * setDatabaseReader(Connection c) or setFileReader(ObjectInputStream s) respectively, and can be checked
46   * by isReadingFromDatabase() method.
47   * 
48   * @see Table
49   * @see DatabaseConnector
50   * @see DumpFileManager
51   * @author jsuder
52   */
53  
54  public class Dump implements Serializable {
55  
56  	/*** ID used in serialization process. */
57  	private static final long serialVersionUID = 8861226762920104092L;
58  
59  	/*** A list of all tables in the database. */
60  	private Vector<Table> tables;
61  
62  	/*** A reference to a DatabaseConnector which created this dump, needed to download data later. */
63  	private transient DatabaseConnector databaseReader;
64  
65  	/*** A reference to an open file input stream, from which the data will be read later. */
66  	private transient ObjectInputStream fileReader;
67  	
68  	/*** True if data should be read from the database and written into a file, false if it's
69  	 * the opposite. */
70  	private transient boolean readFromDatabase = false;
71  	
72  	/*** A log4j logger for this class. */
73  	private static Logger logger = Logger.getLogger(Dump.class);
74  
75  	/***
76  	 * Creates a new empty dump, which will be later filled with tables, views and other stuff...
77  	 */
78  	
79  	public Dump() {
80  		tables = new Vector<Table>();
81  		this.databaseReader = null;
82  		this.fileReader = null;
83  	}
84  	
85  	/***
86  	 * Returns a list of all tables stored in the dump object.
87  	 * @return a list of tables
88  	 */
89  	
90  	public Vector<Table> getTables() {
91  		return tables;
92  	}
93  	
94  	/***
95  	 * Returns a DatabaseConnector used to download table data after the dump is
96  	 * created, if the dump is set in "read from database" mode (by calling
97  	 * setDatabaseReader()). Otherwise, returns null. 
98  	 * @return a DatabaseConnector which created this dump
99  	 */
100 
101 	public DatabaseConnector getDatabaseReader() {
102 		if (!readFromDatabase) {
103 			databaseReader = null;
104 		}
105 		return databaseReader;
106 	}
107 	
108 	/***
109 	 * Returns a stream which can be used to read records of table data from a backup
110 	 * file, if the dump is set in "read from file" mode (by calling setFileReader()).
111 	 * Otherwise, returns null. 
112 	 * @return an input stream reading records from a backup file
113 	 */
114 
115 	public ObjectInputStream getFileReader() {
116 		if (readFromDatabase) {
117 			fileReader = null;
118 		}
119 		return fileReader;
120 	}
121 	
122 	/***
123 	 * Sets the dump in "database read mode", and sets the used DatabaseConnector to
124 	 * the one given in argument. 
125 	 * @param connection a DatabaseConnector which should be used to read data later
126 	 */
127 
128 	public void setDatabaseReader(DatabaseConnector connection) {
129 		this.databaseReader = connection;
130 		readFromDatabase = true;
131 	}
132 
133 	/***
134 	 * Sets the dump in "file read mode", and sets the used file input stream
135 	 * the one given in argument. 
136 	 * @param stream an open file input stream which should be used to read data later
137 	 */
138 
139 	public void setFileReader(ObjectInputStream stream) {
140 		this.fileReader = stream;
141 		readFromDatabase = false;
142 	}
143 	
144 	/***
145 	 * Closes the file from which dump data has been read. Should be done after all the
146 	 * data is read in DatabaseConnector.restore(), but not earlier.
147 	 */
148 	
149 	public void closeFileReader() {
150 		try {
151 			fileReader.close();
152 		} catch (IOException e) {
153 			logger.warn("Couldn't close fileReader: " + e);
154 		}
155 		fileReader = null;
156 	}
157 	
158 	/***
159 	 * Tells if the dump is currently in "database read mode" or "file read mode".
160 	 * @return true if it is in "database read mode"
161 	 */
162 
163 	public boolean isReadingFromDatabase() {
164 		return readFromDatabase;
165 	}
166 
167 	/***
168 	 * Reads a dump from a file using serialization and initializes it and its tables.
169 	 * @param in an input stream from which the dump will be read
170 	 * @throws IOException if the object can't be read from the file
171 	 * @throws ClassNotFoundException if the saved object format doesn't match this class 
172 	 */
173 	
174 	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
175 		in.defaultReadObject();
176 		this.databaseReader = null;
177 		this.fileReader = null;
178 		this.readFromDatabase = false;
179 		for (Table t : tables) {
180 			t.setDump(this);
181 		}
182 	}
183 }