View Javadoc
1   /*
2    * Prometheus: Application Framework
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.prometheus.threads;
18  
19  import io.github.tonywasher.joceanus.gordianknot.util.GordianUtilities;
20  import io.github.tonywasher.joceanus.metis.preference.MetisPreferenceManager;
21  import io.github.tonywasher.joceanus.metis.toolkit.MetisToolkit;
22  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
23  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
24  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataSet;
25  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValuesFormatter;
26  import io.github.tonywasher.joceanus.prometheus.exc.PrometheusDataException;
27  import io.github.tonywasher.joceanus.prometheus.preference.PrometheusBackup.PrometheusBackupPreferenceKey;
28  import io.github.tonywasher.joceanus.prometheus.preference.PrometheusBackup.PrometheusBackupPreferences;
29  import io.github.tonywasher.joceanus.prometheus.security.PrometheusSecurityPasswordManager;
30  import io.github.tonywasher.joceanus.prometheus.toolkit.PrometheusToolkit;
31  import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataControl;
32  import io.github.tonywasher.joceanus.tethys.api.thread.TethysUIThread;
33  import io.github.tonywasher.joceanus.tethys.api.thread.TethysUIThreadManager;
34  
35  import java.io.File;
36  
37  /**
38   * LoaderThread extension to create an XML backup.
39   */
40  public class PrometheusThreadCreateXMLFile
41          implements TethysUIThread<Void> {
42      /**
43       * Buffer length.
44       */
45      private static final int BUFFER_LEN = 100;
46  
47      /**
48       * Number 10.
49       */
50      private static final int TEN = 10;
51  
52      /**
53       * File indicator.
54       */
55      private static final String SUFFIX_FILE = "XML";
56  
57      /**
58       * Data Control.
59       */
60      private final PrometheusDataControl theControl;
61  
62      /**
63       * Is this a Secure backup?
64       */
65      private final boolean isSecure;
66  
67      /**
68       * Constructor (Event Thread).
69       *
70       * @param pControl data control
71       * @param pSecure  is this a secure backup
72       */
73      public PrometheusThreadCreateXMLFile(final PrometheusDataControl pControl,
74                                           final boolean pSecure) {
75          isSecure = pSecure;
76          theControl = pControl;
77      }
78  
79      @Override
80      public String getTaskName() {
81          return isSecure
82                  ? PrometheusThreadId.CREATEXML.toString()
83                  : PrometheusThreadId.CREATEXTRACT.toString();
84      }
85  
86      @Override
87      public Void performTask(final TethysUIThreadManager pManager) throws OceanusException {
88          /* Access the thread manager */
89          final PrometheusToolkit myPromToolkit = (PrometheusToolkit) pManager.getThreadData();
90          final PrometheusSecurityPasswordManager myPasswordMgr = myPromToolkit.getPasswordManager();
91          boolean doDelete = false;
92          File myFile = null;
93  
94          /* Catch Exceptions */
95          try {
96              /* Initialise the status window */
97              pManager.initTask(getTaskName());
98  
99              /* Access the Backup preferences */
100             final MetisPreferenceManager myMgr = theControl.getPreferenceManager();
101             final PrometheusBackupPreferences myProperties = myMgr.getPreferenceSet(PrometheusBackupPreferences.class);
102 
103             /* Determine the archive name */
104             final String myBackupDir = myProperties.getStringValue(PrometheusBackupPreferenceKey.BACKUPDIR);
105             final String myPrefix = myProperties.getStringValue(PrometheusBackupPreferenceKey.BACKUPPFIX);
106             final boolean doTimeStamp = myProperties.getBooleanValue(PrometheusBackupPreferenceKey.BACKUPTIME);
107 
108             /* Create the name of the file */
109             final StringBuilder myName = new StringBuilder(BUFFER_LEN);
110             myName.append(myBackupDir);
111             myName.append(File.separator);
112             myName.append(myPrefix);
113             myName.append(SUFFIX_FILE);
114 
115             /* If we are doing time-stamps */
116             if (doTimeStamp) {
117                 /* Obtain the current date/time */
118                 final OceanusDate myNow = new OceanusDate();
119 
120                 myName.append(myNow.getYear());
121                 if (myNow.getMonth() < TEN) {
122                     myName.append('0');
123                 }
124                 myName.append(myNow.getMonth());
125                 if (myNow.getDay() < TEN) {
126                     myName.append('0');
127                 }
128                 myName.append(myNow.getDay());
129             }
130 
131             /* Set the standard backup name */
132             myFile = new File(myName.toString() + (isSecure
133                     ? GordianUtilities.SECUREZIPFILE_EXT
134                     : GordianUtilities.ZIPFILE_EXT));
135 
136             /* Access the data */
137             final PrometheusDataSet myOldData = theControl.getData();
138 
139             /* Create a new formatter */
140             final PrometheusDataValuesFormatter myFormatter = new PrometheusDataValuesFormatter(pManager, myPasswordMgr);
141 
142             /* Create backup */
143             if (isSecure) {
144                 myFormatter.createBackup(myOldData, myFile);
145             } else {
146                 myFormatter.createExtract(myOldData, myFile);
147             }
148 
149             /* If this is a secure backup */
150             if (isSecure) {
151                 /* File created, so delete on error */
152                 doDelete = true;
153 
154                 /* Check for cancellation */
155 
156                 /* Initialise the status window */
157                 pManager.initTask("Reading Backup");
158 
159                 /* Load workbook */
160                 final PrometheusDataSet myNewData = theControl.getNewData();
161                 myFormatter.loadZipFile(myNewData, myFile);
162 
163                 /* Initialise the security, from the original data */
164                 myNewData.initialiseSecurity(pManager, myOldData);
165 
166                 /* Initialise the status window */
167                 pManager.initTask("Verifying Backup");
168 
169                 /* Create a difference set between the two data copies */
170                 final PrometheusDataSet myDiff = myNewData.getDifferenceSet(pManager, myOldData);
171 
172                 /* If the difference set is non-empty */
173                 if (!myDiff.isEmpty()) {
174                     /* Throw an exception */
175                     throw new PrometheusDataException(myDiff, "Backup is inconsistent");
176                 }
177 
178                 /* OK so switch off flag */
179                 doDelete = false;
180             }
181 
182         } finally {
183             /* Try to delete the file if required */
184             if (doDelete) {
185                 MetisToolkit.cleanUpFile(myFile);
186             }
187         }
188 
189         /* Return nothing */
190         return null;
191     }
192 }