001/*
002MIT License
003
004Copyright (c) 2020 FBSQL Team
005
006Permission is hereby granted, free of charge, to any person obtaining a copy
007of this software and associated documentation files (the "Software"), to deal
008in the Software without restriction, including without limitation the rights
009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010copies of the Software, and to permit persons to whom the Software is
011furnished to do so, subject to the following conditions:
012
013The above copyright notice and this permission notice shall be included in all
014copies or substantial portions of the Software.
015
016THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022SOFTWARE.
023
024Home:   https://fbsql.github.io
025E-Mail: fbsql.team@gmail.com
026*/
027
028package org.fbsql_server;
029
030import java.io.File;
031import java.io.IOException;
032import java.nio.charset.StandardCharsets;
033import java.nio.file.FileVisitResult;
034import java.nio.file.Files;
035import java.nio.file.Path;
036import java.nio.file.Paths;
037import java.nio.file.SimpleFileVisitor;
038import java.nio.file.StandardCopyOption;
039import java.nio.file.attribute.BasicFileAttributes;
040import java.sql.Driver;
041import java.sql.DriverManager;
042import java.sql.SQLException;
043import java.util.HashMap;
044import java.util.List;
045import java.util.Map;
046import java.util.ServiceLoader;
047
048import org.fbsql.servlet.DbServlet;
049import org.fbsql.servlet.SqlParseUtils;
050
051public class Main {
052
053        /**
054         * Called from start.sh script
055         *
056         * @param args
057         * @throws IOException
058         */
059        public static void main(String[] args) throws IOException {
060
061                String fbsql_home_dir = System.getenv(DbServlet.FBSQL_HOME_DIR_ENV_NAME);
062                if (fbsql_home_dir == null)
063                        fbsql_home_dir = System.getProperty("user.home");
064                new File(fbsql_home_dir).mkdirs();
065
066                /* Process application settings directory (child of user home directory) */
067                String appDir        = fbsql_home_dir + "/fbsql";  // *** BRANDING ARTIFACT *** //
068                String logsDir       = appDir + "/logs";
069                String configDir     = appDir + "/config";
070                String fbsqlConfDir  = configDir + "/init";
071                String tomcatDir     = configDir + "/tomcat";
072                String tomcatConfDir = tomcatDir + "/conf";
073                String tomcatBinDir  = tomcatDir + "/bin";
074                String tomcatROOTDir = tomcatDir + "/webapps/ROOT";
075                String jreConfDir    = configDir + "/jre/conf";
076
077                Path appDirPath = Paths.get(appDir);
078
079                if (Files.exists(appDirPath) && Files.isDirectory(appDirPath)) {
080                        /* Java Runtime Environment (JRE) configuration (optional) */
081                        Path jreConfDirPath = Paths.get(jreConfDir);
082
083                        if (Files.exists(jreConfDirPath) && Files.isDirectory(jreConfDirPath))
084                                copyDir(jreConfDir, "jre/conf");
085
086                        Path tomcatConfDirPath = Paths.get(tomcatConfDir);
087
088                        /* Patch conf/logging.properties file */
089                        Path   loggingPropertiesPath    = Paths.get(tomcatConfDir, "logging.properties");
090                        String loggingPropertiesContent = new String(Files.readAllBytes(loggingPropertiesPath), StandardCharsets.UTF_8);
091                        loggingPropertiesContent = loggingPropertiesContent.replace("${catalina.base}/logs", logsDir);
092                        Files.write(loggingPropertiesPath, loggingPropertiesContent.getBytes(StandardCharsets.UTF_8));
093
094                        /* Patch conf/server.xml file */
095                        Path   serverXmlPath    = Paths.get(tomcatConfDir, "server.xml");
096                        String serverXmlContent = new String(Files.readAllBytes(serverXmlPath), StandardCharsets.UTF_8);
097                        serverXmlContent = serverXmlContent.replace("directory=\"logs\"", "directory=" + '"' + logsDir + '"');
098                        Files.write(serverXmlPath, serverXmlContent.getBytes(StandardCharsets.UTF_8));
099
100                        /* setenv.sh */
101                        // copy setenv.sh if not exits from server to user home directory
102                        Path tomcatBinDirPath = Paths.get(tomcatBinDir);
103                        Path setenvPath       = Paths.get(tomcatBinDir, "setenv.sh");
104                        if (!Files.exists(setenvPath)) {
105                                Path serverSetenvPath = Paths.get("bin/setenv.sh");
106                                Files.copy(serverSetenvPath, tomcatBinDirPath.resolve(serverSetenvPath.getFileName()), StandardCopyOption.COPY_ATTRIBUTES);
107                        }
108
109                        /* Custom Apache Tomcat configuration (optional) */
110                        if (Files.exists(tomcatConfDirPath) && Files.isDirectory(tomcatConfDirPath))
111                                copyDir(tomcatConfDir, "conf");
112
113                        /* public files index.html etc. (optional) */
114                        Path tomcatROOTDirPath = Paths.get(tomcatROOTDir);
115                        if (Files.exists(tomcatROOTDirPath) && Files.isDirectory(tomcatROOTDirPath))
116                                copyDir(tomcatROOTDir, "webapps/ROOT");
117                }
118
119                System.out.println("    • Config directory: " + configDir);
120                System.out.println("    • Logs directory  : " + logsDir);
121                System.out.println("    • JDBC drivers:");
122                ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
123                for (Driver driver : loadedDrivers) {
124                        try {
125                                DriverManager.registerDriver(driver);
126                                String driverClassName = driver.getClass().getName();
127                                String driveName       = driver.toString();
128                                String s               = "      • " + driverClassName;
129                                if (!driveName.startsWith(driverClassName + "@")) // we print only meaningful name 
130                                        s += " (" + driveName + ")";
131                                System.out.println(s);
132                        } catch (SQLException e) {
133                                // ignore
134                        }
135                }
136                System.out.println("    • Connectors:");
137                Path fbsqlConfDirPath = Paths.get(fbsqlConfDir);
138
139                Map<String /* connection name */, List<String /* SQL statements */>> initSqlMap         = new HashMap<>();
140                Map<String /* connection name */, String /* parent directory */>     parentDirectoryMap = new HashMap<>();
141                SqlParseUtils.processInitSqlFiles(new File(fbsqlConfDirPath.toString()), initSqlMap, parentDirectoryMap);
142                for (String /* connection name */ instanceName : initSqlMap.keySet())
143                        System.out.println("      • " + instanceName);
144
145                int instancesCount = initSqlMap.size();
146                if (instancesCount == 0)
147                        System.out.println("No instances found");
148                System.out.println();
149                System.out.println();
150        }
151
152        private static boolean copyDir(String src, String dest) throws IOException {
153                Path      sourcePath = Paths.get(src);  // source
154                Path      targetPath = Paths.get(dest); // target
155                boolean[] copied     = new boolean[1];
156                Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
157                        @Override
158                        public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException {
159                                Files.createDirectories(targetPath.resolve(sourcePath.relativize(dir)));
160                                return FileVisitResult.CONTINUE;
161                        }
162
163                        @Override
164                        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
165                                Files.copy(file, targetPath.resolve(sourcePath.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
166                                copied[0] = true;
167                                return FileVisitResult.CONTINUE;
168                        }
169                });
170                return copied[0];
171        }
172}
173
174/*
175Please contact FBSQL Team by E-Mail fbsql.team@gmail.com
176or visit https://fbsql.github.io if you need additional
177information or have any questions.
178*/
179
180/* EOF */