001/*
002 * #%L
003 * Netarchivesuite - deploy
004 * %%
005 * Copyright (C) 2005 - 2018 The Royal Danish 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.deploy;
024
025import java.io.File;
026import java.io.FileWriter;
027import java.io.IOException;
028import java.nio.charset.Charset;
029
030import org.dom4j.Document;
031import org.dom4j.DocumentException;
032import org.dom4j.Element;
033import org.dom4j.io.SAXReader;
034
035import dk.netarkivet.common.exceptions.ArgumentNotValid;
036import dk.netarkivet.common.utils.FileUtils;
037
038/**
039 * Class for combining the different setting files into a complete settings file. The different settings are listed
040 * here: {@link Constants#BUILD_SETTING_FILES}
041 * <p>
042 * This is used when updating the deploy/deploy-core/src/main/resources/dk/netarkivet/deploy/complete_settings.xml before a new release of Netarchivesuite.
043 * From your IDE, run this program (dk.netarkivet.deploy.BuildCompleteSettings) with no arguments.
044 * And then copy then output-file 'complete_settings.xml' to deploy/deploy-core/src/main/resources/dk/netarkivet/deploy/complete_settings.xml
045 * Finally commit the changes to github.
046 */
047public final class BuildCompleteSettings {
048    /**
049     * Private constructor to disallow instantiation of this class.
050     */
051    private BuildCompleteSettings() {
052    }
053    /** The default path to the output file. */
054    public static final String defaultCompleteSettingsPath = "complete_settings.xml";
055    
056    /**
057     * Run the program. This loads and merges all the different settings files into a single outputfile.
058     *
059     * @param args Optional argument for name of complete settings file. E.g. /home/myUser/myDir/default_settings.xml, otherwise the default "complete_settings.xml" is used
060     * @throws IOException For input/output errors.
061     */
062    public static void main(String[] args) {
063        if (args.length < 1) {
064            buildCompleteSettings(defaultCompleteSettingsPath);
065        } else {
066            buildCompleteSettings(args[0]);
067        }
068    }
069
070    public static void buildCompleteSettings(String completeSettingsPath) {
071        ArgumentNotValid.checkNotNullOrEmpty(completeSettingsPath, "completeSettingsPath");
072        File completeSettingsFile = new File(completeSettingsPath);
073        System.out.println("Writing complete settings to file: " + completeSettingsFile.getAbsolutePath());
074        XmlStructure settings = null;
075        for (String path : Constants.BUILD_SETTING_FILES) {
076            System.out.println("Adding settingfile '" + path + "' to completesettings file");
077            File tmpFile = FileUtils.getResourceFileFromClassPath(path);
078            if (settings == null) {
079                settings = new XmlStructure(tmpFile, Charset.defaultCharset().name());
080            } else {
081                Element elem = retrieveXmlSettingsTree(tmpFile);
082                if (elem != null) {
083                    settings.overWrite(elem);
084                } else {
085                    throw new ArgumentNotValid("No settings found at: " + tmpFile.getAbsolutePath());
086                }
087            }
088        }
089
090        try {
091            FileWriter fw = new FileWriter(new File(completeSettingsPath));
092            fw.append(settings.getXML());
093            fw.append(Constants.NEWLINE);
094            fw.close();
095        } catch (IOException e) {
096            throw new RuntimeException("Failed to write new settings", e);
097        }
098        System.out.println("Complete settings successfully written to file: " + completeSettingsFile.getAbsolutePath());
099    }
100
101    /**
102     * Retrieves the main element from the file.
103     *
104     * @param settingFile The file to load into an Element. This has to be a temporary file, since it is deleted
105     * afterwards.
106     * @return The root of the XML structure of the settings file. Returns null if problems occurred during reading.
107     */
108    private static Element retrieveXmlSettingsTree(File settingFile) {
109        try {
110            Document doc;
111            SAXReader reader = new SAXReader();
112            if (settingFile.canRead()) {
113                doc = reader.read(settingFile);
114                settingFile.deleteOnExit();
115                return doc.getRootElement();
116            } else {
117                System.out.println("Cannot read file: " + settingFile.getAbsolutePath());
118            }
119        } catch (DocumentException e) {
120            System.err.println("Problems with file: " + settingFile.getAbsolutePath() + " : " + e);
121
122        }
123        return null;
124    }
125}