001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.apps.git;
029
030import org.opencms.main.CmsSystemInfo;
031import org.opencms.main.OpenCms;
032
033import java.io.File;
034import java.io.FileInputStream;
035import java.io.IOException;
036import java.util.ArrayList;
037import java.util.Arrays;
038import java.util.Collection;
039import java.util.Map.Entry;
040import java.util.Properties;
041
042/** Access to a single git configuration file. */
043public class CmsGitConfiguration {
044
045    /** The system module export path. */
046    private static final String SYSTEM_MODULE_EXPORTPATH = OpenCms.getSystemInfo().getPackagesRfsPath()
047        + CmsSystemInfo.FOLDER_MODULES;
048
049    /** The variable under which the default commit message is set. */
050    private static final String DEFAULT_COMMIT_MESSAGE = "COMMIT_MESSAGE";
051    /** The variable under which the default commit mode is set. */
052    private static final String DEFAULT_COMMIT_MODE = "GIT_COMMIT";
053    /** The variable under which the default copy and unzip behavior is set. */
054    private static final String DEFAULT_COPY_AND_UNZIP = "COPY_AND_UNZIP";
055    /** The variable under which the default exclude libs option is set. */
056    private static final String DEFAULT_EXCLUDE_LIBS = "DEFAULT_EXCLUDE_LIBS";
057    /** The variable under which the export mode is set. */
058    private static final String DEFAULT_EXPORT_MODE = "MODULE_EXPORT_MODE";
059    /** The variable under which the default git user email is set. */
060    private static final String DEFAULT_GIT_USER_EMAIL = "GIT_USER_EMAIL";
061    /** The variable under which the default git user name is set. */
062    private static final String DEFAULT_GIT_USER_NAME = "GIT_USER_NAME";
063    /** The variable under which the default commit mode is set. */
064    private static final String DEFAULT_IGNORE_UNCLEAN = "GIT_IGNORE_UNCLEAN";
065    /** The variable under wich the default module export path is set. */
066    private static final String DEFAULT_MODULE_EXPORT_PATH = "MODULE_EXPORT_FOLDER";
067    /** The variable under which the default modules are listed in the configuration file. */
068    private static final String DEFAULT_MODULES_TO_EXPORT = "DEFAULT_MODULES_TO_EXPORT";
069    /** The variable under which the default pull mode is set for pulling after the commit. */
070    private static final String DEFAULT_PULL_MODE_AFTER = "GIT_PULL_AFTER";
071    /** The variable under which the default pull mode is set for pulling before any other action. */
072    private static final String DEFAULT_PULL_MODE_BEFORE = "GIT_PULL_BEFORE";
073    /** The variable under which the default push mode is set. */
074    private static final String DEFAULT_PUSH_MODE = "GIT_PUSH";
075    /** The variable under which the repository path is set. */
076    private static final String DEFAULT_REPOSITORY_PATH = "REPOSITORY_HOME";
077    /** The variable under which the resources sub-folder for the modules is configured. */
078    private static final String DEFAULT_MODULE_RESOURCES_SUBFOLDER = "MODULE_RESOURCES_SUBFOLDER";
079    /** The variable under which the module path of the repository is configured. */
080    private static final String DEFAULT_MODULE_PATH = "MODULE_PATH";
081
082    /** The commit message as configured. */
083    private String m_defaultCommitMessage = "Autocommit of exported modules.";
084    /** The default commit mode. */
085    private boolean m_defaultCommitMode;
086    /** The default copy and unzip mode. */
087    private boolean m_defaultCopyAndUnzip;
088    /** Flag, indicating if the lib/ folders of the modules should be removed before the commit. */
089    private boolean m_defaultExcludeLibs;
090    /** The export mode as configured - is ignored if the system export folder is chosen. */
091    private int m_defaultExportMode;
092    /** The git user email as configured. */
093    private String m_defaultGitUserEmail;
094    /** The git user name as configured. */
095    private String m_defaultGitUserName;
096    /** Flag, indicating if execution of the script should go on for an unclean repository. */
097    private boolean m_defaultIgnoreUnclean;
098    /** The default module export path as configured. */
099    private String m_defaultModuleExportPath = "";
100    /** The pull mode as configured. */
101    private boolean m_defaultPullModeAfter;
102    /** The pull mode as configured. */
103    private boolean m_defaultPullModeBefore;
104    /** The push mode as configured. */
105    private boolean m_defaultPushMode;
106    /** Collection of the modules to export and check in, as configured in the config file. */
107    private Collection<String> m_configuredModules = new ArrayList<String>();
108    /** The path to the folder containing the modules. */
109    private String m_modulesPath;
110    /** The configured resources sub folder of a module. */
111    private String m_resourcesSubfolder;
112    /** The repository path as configured. */
113    private String m_repositoryPath = "";
114
115    /** Flag, indicating if the config-file is missing. */
116    private boolean m_isValid;
117
118    /** The configuration file. */
119    private File m_configFile;
120
121    /**
122     * Default constructor to wrap a configuration file.
123     * @param configFile the configuration file.
124     */
125    CmsGitConfiguration(final File configFile) {
126
127        m_configFile = configFile;
128        readConfigFile();
129    }
130
131    /**
132     * Returns the wrapped configuration file.
133     * @return the wrapped configuration file.
134     */
135    public File getConfigurationFile() {
136
137        return m_configFile;
138    }
139
140    /** Returns the modules specified in the config file.
141     * @return the modules specified in the config file.
142     */
143    public Collection<String> getConfiguredModules() {
144
145        return m_configuredModules;
146    }
147
148    /** Returns a flag, indicating if automatic commit is enabled by default.
149     * @return a flag, indicating if automatic commit is enabled by default.
150     */
151    public boolean getDefaultAutoCommit() {
152
153        return m_defaultCommitMode;
154    }
155
156    /** Returns a flag, indicating if automatic pulling after the commit is enabled by default.
157     * @return a flag, indicating if automatic pulling after the commit is enabled by default.
158     */
159    public boolean getDefaultAutoPullAfter() {
160
161        return m_defaultPullModeAfter;
162    }
163
164    /** Returns a flag, indicating if automatic pulling first is enabled by default.
165     * @return a flag, indicating if automatic pulling first is enabled by default.
166     */
167    public boolean getDefaultAutoPullBefore() {
168
169        return m_defaultPullModeBefore;
170    }
171
172    /** Returns a flag, indicating if automatic pushing is enabled by default.
173     * @return a flag, indicating if automatic pushing is enabled by default.
174     */
175    public boolean getDefaultAutoPush() {
176
177        return m_defaultPushMode;
178    }
179
180    /** Returns the default commit message.
181     * @return the default commit message.
182     */
183    public String getDefaultCommitMessage() {
184
185        return m_defaultCommitMessage;
186    }
187
188    /** Returns the default copy-and-unzip flag.
189     * @return the default copy-and-unzip flag.
190     */
191    public boolean getDefaultCopyAndUnzip() {
192
193        return m_defaultCopyAndUnzip;
194    }
195
196    /** Returns the default exclude libs flag.
197     * @return the default exclude libs flag.
198     */
199    public boolean getDefaultExcludeLibs() {
200
201        return m_defaultExcludeLibs;
202    }
203
204    /** Returns the configured default git user email, or <code>null</code> if the email is by default not adjusted at all.
205     * @return the configured default git user email, or <code>null</code> if the email is by default not adjusted at all.
206     */
207    public String getDefaultGitUserEmail() {
208
209        return m_defaultGitUserEmail;
210    }
211
212    /** Returns the configured default git user name, or <code>null</code> if the name is by default not adjusted at all.
213     * @return the configured default git user name, or <code>null</code> if the name is by default not adjusted at all.
214     */
215    public String getDefaultGitUserName() {
216
217        return m_defaultGitUserName;
218    }
219
220    /** Returns the default ignore-unclean flag.
221     * @return the default ignore-unclean flag.
222     */
223    public boolean getDefaultIngoreUnclean() {
224
225        return m_defaultIgnoreUnclean;
226    }
227
228    /** Returns the export mode.
229     * @return the export mode.
230     */
231    public int getExportMode() {
232
233        return m_defaultModuleExportPath.isEmpty() ? 1 : m_defaultExportMode;
234    }
235
236    /**
237     * Returns the path to the config file that is wrapped.
238     * @return the path to the config file that is wrapped.
239     */
240    public String getFilePath() {
241
242        if (null != m_configFile) {
243            return m_configFile.getAbsolutePath();
244        }
245        return null;
246    }
247
248    /** Returns the RFS path where module .zip-files are read before check in.
249     * @return the RFS path where module .zip-files are read before check in.
250     */
251    public String getModuleExportPath() {
252
253        return m_defaultModuleExportPath.isEmpty() ? SYSTEM_MODULE_EXPORTPATH : m_defaultModuleExportPath;
254    }
255
256    /**
257     * Returns the path to where modules are stored in the repository.
258     * @return the path to where modules are stored in the repository.
259     */
260    public String getModulesPath() {
261
262        return m_modulesPath;
263    }
264
265    /** Returns the name of the configuration.
266     * @return the name of the configuration.
267     */
268    public String getName() {
269
270        if ((null != m_configFile) && (null != m_configFile.getName())) {
271            return m_configFile.getName();
272        }
273        return "<invalid configuration>";
274    }
275
276    /** Returns the path to the home directory of the repository where the modules are checked in.
277     * @return the path to the home directory of the repository where the modules are checked in.
278     */
279    public String getRepositoryPath() {
280
281        return m_repositoryPath;
282    }
283
284    /**
285     * Returns the subfolder where module resources are placed inside the modules main folder in the repository.
286     * @return the subfolder where module resources are placed inside the modules main folder in the repository.
287     */
288    public String getResourcesSubFolder() {
289
290        return m_resourcesSubfolder;
291    }
292
293    /** Returns a flag, indicating if the config file could be read.
294     * @return a flag, indicating if the config file could be read.
295     */
296    public boolean isValid() {
297
298        return m_isValid;
299    }
300
301    /** Helper to read a line from the config file.
302     * @param propValue the property value
303     * @return the value of the variable set at this line.
304     */
305    private String getValueFromProp(final String propValue) {
306
307        String value = propValue;
308        // remove quotes
309        value = value.trim();
310        if ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'"))) {
311            value = value.substring(1, value.length() - 1);
312        }
313        return value;
314    }
315
316    /** Reads the config file and stores configured values in member variables. */
317    private void readConfigFile() {
318
319        m_isValid = false;
320        if ((null != m_configFile) && m_configFile.exists()) {
321            if (m_configFile.canRead()) {
322                Properties props = new Properties();
323                try (FileInputStream input = new FileInputStream(m_configFile)) {
324                    props.load(input);
325                    for (Entry<Object, Object> entry : props.entrySet()) {
326                        String key = (String)entry.getKey();
327                        String propValue = (String)entry.getValue();
328                        if (key.equals(DEFAULT_MODULES_TO_EXPORT)) {
329                            String value = getValueFromProp(propValue).trim();
330                            if (value.contains(",")) {
331                                m_configuredModules = Arrays.asList(value.split(" *, *"));
332                            } else {
333                                m_configuredModules = Arrays.asList(value.split(" +"));
334                            }
335                        }
336
337                        if (key.equals(DEFAULT_MODULE_PATH)) {
338                            m_modulesPath = getValueFromProp(propValue).trim();
339                        }
340
341                        if (key.equals(DEFAULT_MODULE_RESOURCES_SUBFOLDER)) {
342                            m_resourcesSubfolder = getValueFromProp(propValue).trim();
343                        }
344
345                        if (key.equals(DEFAULT_PULL_MODE_BEFORE)) {
346                            String value = getValueFromProp(propValue);
347                            value = value.trim();
348                            if (value.equals("1")) {
349                                m_defaultPullModeBefore = true;
350                            }
351                        }
352                        if (key.equals(DEFAULT_PULL_MODE_AFTER)) {
353                            String value = getValueFromProp(propValue);
354                            value = value.trim();
355                            if (value.equals("1")) {
356                                m_defaultPullModeAfter = true;
357                            }
358                        }
359                        if (key.equals(DEFAULT_PUSH_MODE)) {
360                            String value = getValueFromProp(propValue);
361                            value = value.trim();
362                            if (value.equals("1")) {
363                                m_defaultPushMode = true;
364                            }
365                        }
366                        if (key.equals(DEFAULT_MODULE_EXPORT_PATH)) {
367                            String value = getValueFromProp(propValue);
368                            m_defaultModuleExportPath = value.trim();
369                        }
370                        if (key.equals(DEFAULT_REPOSITORY_PATH)) {
371                            String value = getValueFromProp(propValue);
372                            m_repositoryPath = value.trim();
373                        }
374                        if (key.equals(DEFAULT_EXPORT_MODE)) {
375                            String value = getValueFromProp(propValue);
376                            m_defaultExportMode = (value.trim().equals("1")) ? 1 : 0;
377                        }
378                        if (key.equals(DEFAULT_COMMIT_MESSAGE)) {
379                            String value = getValueFromProp(propValue);
380                            m_defaultCommitMessage = value;
381                        }
382                        if (key.equals(DEFAULT_GIT_USER_NAME)) {
383                            String value = getValueFromProp(propValue);
384                            m_defaultGitUserName = value;
385                        }
386                        if (key.equals(DEFAULT_GIT_USER_EMAIL)) {
387                            String value = getValueFromProp(propValue);
388                            m_defaultGitUserEmail = value;
389                        }
390                        if (key.equals(DEFAULT_EXCLUDE_LIBS)) {
391                            String value = getValueFromProp(propValue);
392                            m_defaultExcludeLibs = (value.trim().equals("1")) ? true : false;
393                        }
394                        if (key.equals(DEFAULT_COMMIT_MODE)) {
395                            String value = getValueFromProp(propValue);
396                            m_defaultCommitMode = (value.trim().equals("1")) ? true : false;
397                        }
398                        if (key.equals(DEFAULT_IGNORE_UNCLEAN)) {
399                            String value = getValueFromProp(propValue);
400                            m_defaultIgnoreUnclean = (value.trim().equals("1")) ? true : false;
401                        }
402                        if (key.equals(DEFAULT_COPY_AND_UNZIP)) {
403                            String value = getValueFromProp(propValue);
404                            m_defaultCopyAndUnzip = (value.trim().equals("1")) ? true : false;
405                        }
406                    }
407                    m_isValid = true;
408                } catch (IOException e) {
409                    e.printStackTrace();
410                }
411            }
412        }
413    }
414
415}