• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/exist-core/src/main/java/org/exist/launcher/ConfigurationUtility.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 *
24
 * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
25
 *       The original license header is included below.
26
 *
27
 * =====================================================================
28
 *
29
 * eXist-db Open Source Native XML Database
30
 * Copyright (C) 2001 The eXist-db Authors
31
 *
32
 * info@exist-db.org
33
 * http://www.exist-db.org
34
 *
35
 * This library is free software; you can redistribute it and/or
36
 * modify it under the terms of the GNU Lesser General Public
37
 * License as published by the Free Software Foundation; either
38
 * version 2.1 of the License, or (at your option) any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful,
41
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
43
 * Lesser General Public License for more details.
44
 *
45
 * You should have received a copy of the GNU Lesser General Public
46
 * License along with this library; if not, write to the Free Software
47
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
48
 */
49
package org.exist.launcher;
50

51
import org.exist.util.DatabaseConfigurationException;
52
import org.exist.util.FileUtils;
53

54
import javax.xml.stream.XMLInputFactory;
55
import javax.xml.stream.XMLStreamException;
56
import javax.xml.stream.XMLStreamReader;
57
import javax.xml.transform.*;
58
import javax.xml.transform.stream.StreamResult;
59
import javax.xml.transform.stream.StreamSource;
60
import java.io.IOException;
61
import java.io.InputStream;
62
import java.io.InputStreamReader;
63
import java.io.Writer;
64
import java.nio.file.*;
65
import java.text.SimpleDateFormat;
66
import java.util.Calendar;
67
import java.util.HashMap;
68
import java.util.Map;
69

70
import java.util.Properties;
71

72
import static java.nio.charset.StandardCharsets.UTF_8;
73

74
public class ConfigurationUtility {
×
75

76
    public static final String LAUNCHER_PROPERTIES_FILE_NAME = "launcher.properties";
77
    public static final String LAUNCHER_PROPERTY_MAX_MEM = "memory.max";
78
    public static final String LAUNCHER_PROPERTY_MIN_MEM = "memory.min";
79
    public static final String LAUNCHER_PROPERTY_VMOPTIONS = "vmoptions";
80
    public static final String LAUNCHER_PROPERTY_NEVER_INSTALL_SERVICE = "service.install.never";
81

82
    /**
83
     * We try to resolve any config file relative to an Elemental
84
     * config file indicated by the System Property {@link org.exist.util.ConfigurationHelper#PROP_EXIST_CONFIGURATION_FILE},
85
     * if such a file does not exist, then we try and resolve it from the user.home or EXIST_HOME.
86
     *
87
     * @param configFileName the name/relative path of the config file to lookup
88
     * @param shouldExist if the file should already exist
89
     *
90
     * @return the file path (may not exist!)
91
     */
92
    public static Path lookup(final String configFileName, final boolean shouldExist) {
93
        return org.exist.util.ConfigurationHelper.getFromSystemProperty()
×
94
                .filter(Files::exists)
×
95
                .map(existConfigFile -> existConfigFile.resolveSibling(configFileName))
×
96
                .filter(f -> !shouldExist || Files.exists(f))
×
97
                .orElseGet(() -> org.exist.util.ConfigurationHelper.lookup(configFileName));
×
98
    }
99

100
    public static boolean isFirstStart() {
101
        final Path propFile = lookup(LAUNCHER_PROPERTIES_FILE_NAME, false);
×
102
         return !Files.exists(propFile);
×
103
    }
104

105
    public static Map<String, Integer> getJettyPorts() throws DatabaseConfigurationException {
106
        final Map<String, Integer> ports = new HashMap<>();
×
107
        final Path jettyHttpConfig = lookup("jetty/jetty-http.xml", true);
×
108
        final Path jettyHttpsConfig = lookup("jetty/jetty-ssl.xml", true);
×
109
        getJettyPorts(ports, jettyHttpConfig);
×
110
        getJettyPorts(ports, jettyHttpsConfig);
×
111
        return ports;
×
112
    }
113

114
    private static void getJettyPorts(Map<String, Integer> ports, Path jettyConfig) throws DatabaseConfigurationException {
115
        if (Files.exists(jettyConfig)) {
×
116
            try {
117
                final XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(Files
×
118
                        .newBufferedReader(jettyConfig));
×
119
                while (reader.hasNext()) {
×
120
                    final int status = reader.next();
×
121
                    if (status == XMLStreamReader.START_ELEMENT && "SystemProperty".equals(reader.getLocalName())) {
×
122
                        final String name = reader.getAttributeValue(null, "name");
×
123
                        if (name != null && (name.equals("jetty.http.port") || name.equals("jetty.ssl.port"))) {
×
124
                            final String defaultValue = reader.getAttributeValue(null, "default");
×
125
                            if (defaultValue != null) {
×
126
                                try {
127
                                    ports.put(name, Integer.parseInt(defaultValue));
×
128
                                } catch(NumberFormatException e) {
×
129
                                    // skip
130
                                }
131
                            }
132
                        }
133
                    }
134
                }
135
            } catch (XMLStreamException | IOException e) {
×
136
                throw new DatabaseConfigurationException(e.getMessage(), e);
×
137
            }
138
        }
139
    }
×
140

141
    public static Properties loadProperties() {
142
        final Properties launcherProperties = new Properties();
×
143
        final java.nio.file.Path propFile = lookup(LAUNCHER_PROPERTIES_FILE_NAME, false);
×
144
        InputStream is = null;
×
145
        try {
146
            if (Files.isReadable(propFile)) {
×
147
                is = Files.newInputStream(propFile);
×
148
            }
149
            if (is == null) {
×
150
                is = Launcher.class.getResourceAsStream(LAUNCHER_PROPERTIES_FILE_NAME);
×
151
            }
152

153
            if (is != null) {
×
154
                launcherProperties.load(new InputStreamReader(is, UTF_8));
×
155
            }
156
        } catch (final IOException e) {
×
157
            System.err.println(LAUNCHER_PROPERTIES_FILE_NAME + " not found");
×
158
        } finally {
159
            if(is != null) {
×
160
                try {
161
                    is.close();
×
162
                } catch(final IOException ioe) {
×
163
                    ioe.printStackTrace();
×
164
                }
165
            }
166
        }
167
        return launcherProperties;
×
168
    }
169

170
    public static void saveProperties(final Properties properties) throws IOException {
171
        final Path propFile = lookup(LAUNCHER_PROPERTIES_FILE_NAME, false);
×
172
        final Properties launcherProperties = loadProperties();
×
173
        for (final String key: properties.stringPropertyNames()) {
×
174
            launcherProperties.setProperty(key, properties.getProperty(key));
×
175
        }
176

177
        System.out.println("Launcher properties: " + launcherProperties.toString());
×
178
        for (final String key: launcherProperties.stringPropertyNames()) {
×
179
            System.out.println(key + "=" + launcherProperties.getProperty(key));
×
180
        }
181
        System.out.println();
×
182

183
        try (final Writer writer = Files.newBufferedWriter(propFile)) {
×
184
            launcherProperties.store(writer, null);
×
185
        }
186
    }
×
187

188
    private static Path backupOriginal(final Path propFile) throws IOException {
189
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
×
190
        final String bakFileName = FileUtils.fileName(propFile) + ".orig." + sdf.format(Calendar.getInstance().getTime());
×
191
        final Path bakFile = propFile.resolveSibling(bakFileName);
×
192
        Files.copy(propFile, bakFile);
×
193
        return bakFile;
×
194
    }
195

196
    public static void saveConfiguration(String path, String xsl, Properties properties) throws IOException,
197
            TransformerException {
198
        final Path config = lookup(path, false);
×
199
        applyXSL(properties, config, xsl);
×
200
    }
×
201

202
    private static void applyXSL(Properties properties, Path config, String xsl) throws IOException,
203
            TransformerException {
204
        final Path orig = backupOriginal(config);
×
205
        final TransformerFactory factory = TransformerFactory.newInstance();
×
206
        final StreamSource xslSource = new StreamSource(ConfigurationUtility.class.getResourceAsStream(xsl));
×
207
        final Transformer transformer = factory.newTransformer(xslSource);
×
208
        final StreamSource xmlSource = new StreamSource(orig.toFile());
×
209
        final StreamResult output = new StreamResult(config.toFile());
×
210

211
        transformer.setErrorListener(new ErrorListener() {
×
212
            @Override
213
            public void warning(TransformerException exception) throws TransformerException {
214
                System.out.println(exception.getMessageAndLocation());
×
215
            }
×
216

217
            @Override
218
            public void error(TransformerException exception) throws TransformerException {
219
                System.out.println(exception.getMessageAndLocation());
×
220
            }
×
221

222
            @Override
223
            public void fatalError(TransformerException exception) throws TransformerException {
224
                System.out.println(exception.getMessageAndLocation());
×
225
            }
×
226
        });
227
        for (Map.Entry entry: properties.entrySet()) {
×
228
            transformer.setParameter(entry.getKey().toString(), entry.getValue());
×
229
        }
230
        transformer.transform(xmlSource, output);
×
231
    }
×
232
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc