001/*
002 * #%L
003 * Netarchivesuite - archive
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023package dk.netarkivet.archive.tools;
024
025import java.io.BufferedReader;
026import java.io.File;
027import java.io.FileReader;
028import java.io.IOException;
029import java.sql.Date;
030
031import dk.netarkivet.archive.arcrepositoryadmin.AdminData;
032import dk.netarkivet.archive.arcrepositoryadmin.ReplicaCacheDatabase;
033import dk.netarkivet.common.exceptions.IOFailure;
034import dk.netarkivet.common.tools.SimpleCmdlineTool;
035import dk.netarkivet.common.tools.ToolRunnerBase;
036
037/**
038 * Method for reestablishing the admin database from a 'admin.data' file.
039 */
040@SuppressWarnings({"deprecation"})
041public class ReestablishAdminDatabase extends ToolRunnerBase {
042    /**
043     * The number of instances required for how many lines to ingest into the database between printing out, to tell how
044     * far we have come.
045     */
046    private static final int PRINT_INTERVAL = 10000;
047
048    /**
049     * Main method. Instantiates the tool and runs it.
050     *
051     * @param argv The list of arguments.
052     */
053    public static void main(String[] argv) {
054        ReestablishAdminDatabase instance = new ReestablishAdminDatabase();
055        instance.runTheTool(argv);
056    }
057
058    /**
059     * Create an instance of the actual ReestablishAdminDatabaseTool.
060     *
061     * @return an instance of ReestablishAdminDatabaseTool.
062     */
063    protected SimpleCmdlineTool makeMyTool() {
064        return new ReestablishAdminDatabaseTool();
065    }
066
067    /**
068     * The implementation of SimpleCmdlineTool for ReestablishAdminDatabase.
069     */
070    private static class ReestablishAdminDatabaseTool implements SimpleCmdlineTool {
071        /** The access to the database. */
072        private ReplicaCacheDatabase rcd;
073        /** The admin data file to convert into the database. */
074        private File adminFile;
075        /** The default name of the admin data file, if none is given. */
076        private static final String DEFAULT_ADMIN_DATA = "admin.data";
077        /** The 'last modified' date for the admin.data file. */
078        private Date fileDate;
079
080        /**
081         * Method for testing validating the arguments.
082         *
083         * @param args The list of arguments given to the tool.
084         * @return Whether the arguments are valid.
085         */
086        public boolean checkArgs(String... args) {
087            // Check if more than 1 argument is given
088            if (args.length > 1) {
089                System.err.println("Can handle at most 1 argument.");
090                return false;
091            }
092            // Get file dependent on argument
093            File checkFile;
094            if (args.length < 1) {
095                checkFile = new File(DEFAULT_ADMIN_DATA);
096                System.out.println("Using default admin.data: " + checkFile.getAbsolutePath());
097            } else {
098                checkFile = new File(args[0]);
099                System.out.println("Using given admin.data: " + checkFile.getAbsolutePath());
100            }
101            // Check whether the file exists and is a file (not directory).
102            if (!checkFile.isFile()) {
103                System.err.println("The file '" + checkFile.getAbsolutePath() + "' is not a valid file.");
104                return false;
105            }
106            // check whether the file can be read.
107            if (!checkFile.canRead()) {
108                System.err.println("Cannot read the file '" + checkFile.getAbsolutePath() + "'");
109                return false;
110            }
111
112            // Ensure that the database is empty.
113            if (!ReplicaCacheDatabase.getInstance().isEmpty()) {
114                System.err.println("The database is not empty.");
115                return false;
116            }
117
118            return true;
119        }
120
121        /**
122         * Write the parameters for this tool. It optionally takes the admin.data file as argument. If this argument is
123         * not given, then it is assumed to be located in the folder where the tool is run.
124         *
125         * @return The parameters for this tool.
126         */
127        @Override
128        public String listParameters() {
129            return "[admin.data]";
130        }
131
132        /**
133         * Execution of the tool. Retrieves the lines of the admin file, and inserts them into the database. Also
134         * updates the date for date for the filelist and checksumslist updates based on the 'last modified' date of the
135         * admin file.
136         *
137         * @param args The arguments for the tool.
138         */
139        @Override
140        public void run(String... args) {
141            // read and handle each line individually.
142            BufferedReader in = null;
143            long badlines = 0;
144            long linesRead = 0;
145            try {
146                try {
147                    in = new BufferedReader(new FileReader(adminFile));
148                    String line = in.readLine();
149                    linesRead++;
150                    if (!line.contains(AdminData.VERSION_NUMBER)) {
151                        System.err.println("The first line in Admin.data "
152                                + "tells the version. Expected 0.4, but got: " + line + ". Continues any way.");
153                    } else {
154                        System.out.println("Reading admin.data version " + line);
155                    }
156                    while ((line = in.readLine()) != null) {
157                        linesRead++;
158                        if (!rcd.insertAdminEntry(line)) {
159                            // bad lines
160                            badlines++;
161                            System.err.println("Bad line(#" + badlines + "): ");
162                            System.err.println(line);
163                        }
164                        if ((linesRead % PRINT_INTERVAL) == 0) {
165                            System.out.println("[" + new java.util.Date() + "] Processed " + linesRead
166                                    + " admin data lines");
167                        }
168                    }
169                } finally {
170                    if (in != null) {
171                        in.close();
172                    }
173                }
174            } catch (IOException e) {
175                String msg = "An error occurred during reading the admin data " + "file " + adminFile.getAbsolutePath();
176                throw new IOFailure(msg, e);
177            }
178
179            // update the filelist and checksumlist dates for the replicas.
180            rcd.setAdminDate(fileDate);
181            System.out.println("[" + new java.util.Date() + "] "
182                    + "ReestablishAdminDatabase tool finished ingest of file '" + adminFile.getAbsolutePath() + "'.");
183        }
184
185        /**
186         * Sets up the variables for the tool based on the arguments. Retrieves the admin data file and the last
187         * modified date for this file.
188         *
189         * @param args The arguments for the tool.
190         */
191        @Override
192        public void setUp(String... args) {
193            if (args.length < 1) {
194                adminFile = new File(DEFAULT_ADMIN_DATA);
195            } else {
196                adminFile = new File(args[0]);
197            }
198
199            // retrieve the last modified date for the file.
200            fileDate = new Date(adminFile.lastModified());
201
202            // initialize the connection to the database.
203            rcd = ReplicaCacheDatabase.getInstance();
204        }
205
206        /**
207         * Method for cleaning up afterwards. Closes the connection to the database.
208         */
209        @Override
210        public void tearDown() {
211            rcd.cleanup();
212        }
213    }
214}