8242302: Refactor jpackage native code
Reviewed-by: herrick, almatvee, erikj
This commit is contained in:
parent
90ada6a314
commit
0c56c3511a
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,48 +27,43 @@ include LibCommon.gmk
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Output app launcher library in resources dir, and symbols in the object dir
|
|
||||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_APPLAUNCHER, \
|
|
||||||
NAME := applauncher, \
|
|
||||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
|
||||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libapplauncher, \
|
|
||||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
|
||||||
OPTIMIZATION := LOW, \
|
|
||||||
CFLAGS := $(CXXFLAGS_JDKLIB) $(X_CFLAGS), \
|
|
||||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
|
||||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
|
|
||||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
|
||||||
LIBS := $(LIBCXX), \
|
|
||||||
LIBS_windows := user32.lib shell32.lib advapi32.lib ole32.lib, \
|
|
||||||
LIBS_linux := -ldl -lpthread, \
|
|
||||||
LIBS_macosx := -ldl -framework Cocoa, \
|
|
||||||
))
|
|
||||||
|
|
||||||
$(BUILD_LIB_APPLAUNCHER): $(call FindLib, java.base, java)
|
|
||||||
|
|
||||||
TARGETS += $(BUILD_LIB_APPLAUNCHER)
|
|
||||||
|
|
||||||
JPACKAGE_APPLAUNCHER_SRC := \
|
JPACKAGE_APPLAUNCHER_SRC := \
|
||||||
$(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/jpackageapplauncher
|
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, applauncher) \
|
||||||
|
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, common)
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(call isTargetOs, windows), true)
|
||||||
|
JpackageWithStaticCrt = \
|
||||||
|
$(filter-out -MD, $1) -MT
|
||||||
|
else
|
||||||
|
JpackageWithStaticCrt = \
|
||||||
|
$1
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
JPACKAGE_OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources
|
||||||
|
JPACKAGE_CXXFLAGS_windows := -EHsc -DUNICODE -D_UNICODE
|
||||||
|
|
||||||
# Output app launcher executable in resources dir, and symbols in the object dir
|
# Output app launcher executable in resources dir, and symbols in the object dir
|
||||||
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHEREXE, \
|
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHEREXE, \
|
||||||
NAME := jpackageapplauncher, \
|
NAME := jpackageapplauncher, \
|
||||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncher, \
|
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncher, \
|
||||||
SRC := $(JPACKAGE_APPLAUNCHER_SRC), \
|
SRC := $(JPACKAGE_APPLAUNCHER_SRC), \
|
||||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||||
OPTIMIZATION := LOW, \
|
OPTIMIZATION := LOW, \
|
||||||
CFLAGS := $(CFLAGS_JDKEXE), \
|
CXXFLAGS := $(call JpackageWithStaticCrt, $(CXXFLAGS_JDKEXE)) \
|
||||||
CXXFLAGS := $(CXXFLAGS_JDKEXE), \
|
$(addprefix -I, $(JPACKAGE_APPLAUNCHER_SRC)), \
|
||||||
CFLAGS_windows := -EHsc -DLAUNCHERC -DUNICODE -D_UNICODE, \
|
CXXFLAGS_windows := $(JPACKAGE_CXXFLAGS_windows), \
|
||||||
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
||||||
LIBS_macosx := -framework Cocoa, \
|
LIBS_macosx := -framework Cocoa, \
|
||||||
LIBS := $(LIBCXX), \
|
LIBS := $(LIBCXX), \
|
||||||
LIBS_linux := -ldl, \
|
LIBS_linux := -ldl, \
|
||||||
LIBS_windows := user32.lib shell32.lib advapi32.lib, \
|
|
||||||
))
|
))
|
||||||
|
|
||||||
|
$(BUILD_JPACKAGE_APPLAUNCHEREXE): $(call FindLib, java.base, java)
|
||||||
|
|
||||||
TARGETS += $(BUILD_JPACKAGE_APPLAUNCHEREXE)
|
TARGETS += $(BUILD_JPACKAGE_APPLAUNCHEREXE)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -78,12 +73,11 @@ ifeq ($(call isTargetOs, windows), true)
|
|||||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_JPACKAGE, \
|
$(eval $(call SetupJdkLibrary, BUILD_LIB_JPACKAGE, \
|
||||||
NAME := jpackage, \
|
NAME := jpackage, \
|
||||||
OPTIMIZATION := LOW, \
|
OPTIMIZATION := LOW, \
|
||||||
CFLAGS := $(CXXFLAGS_JDKLIB), \
|
EXTRA_SRC := jdk.incubator.jpackage:common, \
|
||||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(JPACKAGE_CXXFLAGS_windows), \
|
||||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
|
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
|
||||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||||
LIBS := $(LIBCXX), \
|
LIBS := $(LIBCXX), \
|
||||||
LIBS_windows := user32.lib shell32.lib advapi32.lib ole32.lib, \
|
|
||||||
))
|
))
|
||||||
|
|
||||||
TARGETS += $(BUILD_LIB_JPACKAGE)
|
TARGETS += $(BUILD_LIB_JPACKAGE)
|
||||||
@ -92,11 +86,11 @@ ifeq ($(call isTargetOs, windows), true)
|
|||||||
# Output library in resources dir, and symbols in the object dir
|
# Output library in resources dir, and symbols in the object dir
|
||||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_WIXHELPER, \
|
$(eval $(call SetupJdkLibrary, BUILD_LIB_WIXHELPER, \
|
||||||
NAME := wixhelper, \
|
NAME := wixhelper, \
|
||||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libwixhelper, \
|
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libwixhelper, \
|
||||||
OPTIMIZATION := LOW, \
|
OPTIMIZATION := LOW, \
|
||||||
CFLAGS := $(CXXFLAGS_JDKLIB), \
|
CXXFLAGS := $(call JpackageWithStaticCrt, $(CXXFLAGS_JDKLIB)) \
|
||||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE -MT, \
|
$(JPACKAGE_CXXFLAGS_windows), \
|
||||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \
|
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \
|
||||||
LIBS := $(LIBCXX), \
|
LIBS := $(LIBCXX), \
|
||||||
LIBS_windows := msi.lib Shlwapi.lib User32.lib, \
|
LIBS_windows := msi.lib Shlwapi.lib User32.lib, \
|
||||||
@ -104,17 +98,18 @@ ifeq ($(call isTargetOs, windows), true)
|
|||||||
|
|
||||||
TARGETS += $(BUILD_LIB_WIXHELPER)
|
TARGETS += $(BUILD_LIB_WIXHELPER)
|
||||||
|
|
||||||
|
JPACKAGE_MSIWRAPPER_SRC := \
|
||||||
|
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, msiwrapper) \
|
||||||
|
$(call FindSrcDirsForComponent, jdk.incubator.jpackage, common)
|
||||||
|
|
||||||
# Build exe installer wrapper for msi installer
|
# Build exe installer wrapper for msi installer
|
||||||
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_MSIWRAPPER, \
|
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_MSIWRAPPER, \
|
||||||
NAME := msiwrapper, \
|
NAME := msiwrapper, \
|
||||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/msiwrapper, \
|
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/msiwrapper, \
|
||||||
SRC := $(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/msiwrapper, \
|
SRC := $(JPACKAGE_MSIWRAPPER_SRC), \
|
||||||
EXTRA_FILES := $(addprefix $(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/libjpackage/, \
|
CXXFLAGS := $(call JpackageWithStaticCrt, $(CXXFLAGS_JDKEXE)) \
|
||||||
FileUtils.cpp Log.cpp WinSysInfo.cpp tstrings.cpp WinErrorHandling.cpp ErrorHandling.cpp), \
|
$(addprefix -I, $(JPACKAGE_MSIWRAPPER_SRC)) $(JPACKAGE_CXXFLAGS_windows), \
|
||||||
CFLAGS := $(CXXFLAGS_JDKEXE) -MT \
|
|
||||||
$(addprefix -I$(TOPDIR)/src/jdk.incubator.jpackage/$(OPENJDK_TARGET_OS)/native/, msiwrapper libjpackage), \
|
|
||||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
|
||||||
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
||||||
LIBS := $(LIBCXX), \
|
LIBS := $(LIBCXX), \
|
||||||
))
|
))
|
||||||
@ -124,16 +119,15 @@ ifeq ($(call isTargetOs, windows), true)
|
|||||||
# Build non-console version of launcher
|
# Build non-console version of launcher
|
||||||
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHERWEXE, \
|
$(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHERWEXE, \
|
||||||
NAME := jpackageapplauncherw, \
|
NAME := jpackageapplauncherw, \
|
||||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources, \
|
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncherw, \
|
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncherw, \
|
||||||
SRC := $(JPACKAGE_APPLAUNCHER_SRC), \
|
SRC := $(BUILD_JPACKAGE_APPLAUNCHEREXE_SRC), \
|
||||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
TOOLCHAIN := $(BUILD_JPACKAGE_APPLAUNCHEREXE_TOOLCHAIN), \
|
||||||
OPTIMIZATION := LOW, \
|
OPTIMIZATION := $(BUILD_JPACKAGE_APPLAUNCHEREXE_OPTIMIZATION), \
|
||||||
CFLAGS := $(CXXFLAGS_JDKEXE), \
|
CXXFLAGS := $(BUILD_JPACKAGE_APPLAUNCHEREXE_CXXFLAGS), \
|
||||||
CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
|
CXXFLAGS_windows := $(BUILD_JPACKAGE_APPLAUNCHEREXE_CXXFLAGS_windows) -DJP_LAUNCHERW, \
|
||||||
LDFLAGS := $(LDFLAGS_JDKEXE), \
|
LDFLAGS := $(BUILD_JPACKAGE_APPLAUNCHEREXE_LDFLAGS), \
|
||||||
LIBS := $(LIBCXX), \
|
LIBS := $(BUILD_JPACKAGE_APPLAUNCHEREXE_LIBS), \
|
||||||
LIBS_windows := user32.lib shell32.lib advapi32.lib, \
|
|
||||||
))
|
))
|
||||||
|
|
||||||
TARGETS += $(BUILD_JPACKAGE_APPLAUNCHERWEXE)
|
TARGETS += $(BUILD_JPACKAGE_APPLAUNCHERWEXE)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -40,7 +40,6 @@ import static jdk.incubator.jpackage.internal.StandardBundlerParam.*;
|
|||||||
|
|
||||||
public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
|
public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
|
||||||
|
|
||||||
private static final String LIBRARY_NAME = "libapplauncher.so";
|
|
||||||
final static String DEFAULT_ICON = "java32.png";
|
final static String DEFAULT_ICON = "java32.png";
|
||||||
|
|
||||||
private final ApplicationLayout appLayout;
|
private final ApplicationLayout appLayout;
|
||||||
@ -109,11 +108,6 @@ public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
|
|||||||
// create the primary launcher
|
// create the primary launcher
|
||||||
createLauncherForEntryPoint(params, null);
|
createLauncherForEntryPoint(params, null);
|
||||||
|
|
||||||
// Copy library to the launcher folder
|
|
||||||
try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
|
|
||||||
writeEntry(is_lib, appLayout.dllDirectory().resolve(LIBRARY_NAME));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the additional launchers, if any
|
// create the additional launchers, if any
|
||||||
List<Map<String, ? super Object>> entryPoints
|
List<Map<String, ? super Object>> entryPoints
|
||||||
= StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
|
= StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,39 +23,36 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PLATFORM_DEFS_H
|
#include "AppLauncher.h"
|
||||||
#define PLATFORM_DEFS_H
|
#include "FileUtils.h"
|
||||||
|
#include "UnixSysInfo.h"
|
||||||
|
|
||||||
// Define Windows compatibility requirements XP or later
|
|
||||||
#define WINVER 0x0600
|
|
||||||
#define _WIN32_WINNT 0x0600
|
|
||||||
|
|
||||||
#include <Windows.h>
|
namespace {
|
||||||
#include <tchar.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#include <process.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
void launchApp() {
|
||||||
|
setlocale(LC_ALL, "en_US.utf8");
|
||||||
|
|
||||||
#ifndef WINDOWS
|
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||||
#define WINDOWS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef std::wstring TString;
|
// Launcher should be in "bin" subdirectory of app image.
|
||||||
#define StringLength wcslen
|
const tstring appImageRoot = FileUtils::dirname(
|
||||||
|
FileUtils::dirname(launcherPath));
|
||||||
|
|
||||||
#define TRAILING_PATHSEPARATOR '\\'
|
AppLauncher()
|
||||||
#define BAD_TRAILING_PATHSEPARATOR '/'
|
.setImageRoot(appImageRoot)
|
||||||
#define PATH_SEPARATOR ';'
|
.addJvmLibName(_T("lib/libjli.so"))
|
||||||
#define BAD_PATH_SEPARATOR ':'
|
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("lib/app"))
|
||||||
|
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||||
|
<< _T("lib/runtime"))
|
||||||
|
.launch();
|
||||||
|
}
|
||||||
|
|
||||||
typedef ULONGLONG TPlatformNumber;
|
} // namespace
|
||||||
typedef DWORD TProcessID;
|
|
||||||
|
|
||||||
typedef void* Module;
|
|
||||||
typedef void* Procedure;
|
|
||||||
|
|
||||||
#endif // PLATFORM_DEFS_H
|
int main(int argc, char *argv[]) {
|
||||||
|
SysInfo::argc = argc;
|
||||||
|
SysInfo::argv = argv;
|
||||||
|
return AppLauncher::launch(std::nothrow, launchApp);
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
namespace SysInfo {
|
||||||
|
|
||||||
|
tstring getProcessModulePath() {
|
||||||
|
const char* path = "/proc/self/exe";
|
||||||
|
char buffer[PATH_MAX] = { 0 };
|
||||||
|
ssize_t len = readlink(path, buffer, sizeof(buffer));
|
||||||
|
if (len < 0) {
|
||||||
|
JP_THROW(tstrings::any() << "readlink(" << path
|
||||||
|
<< ") failed. Error: " << lastCRTError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return tstring(buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace SysInfo
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <string>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef bool (*start_launcher)(int argc, char* argv[]);
|
|
||||||
typedef void (*stop_launcher)();
|
|
||||||
|
|
||||||
#define MAX_PATH 1024
|
|
||||||
|
|
||||||
std::string GetProgramPath() {
|
|
||||||
ssize_t len = 0;
|
|
||||||
std::string result;
|
|
||||||
char buffer[MAX_PATH] = {0};
|
|
||||||
|
|
||||||
if ((len = readlink("/proc/self/exe", buffer, MAX_PATH - 1)) != -1) {
|
|
||||||
buffer[len] = '\0';
|
|
||||||
result = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
int result = 1;
|
|
||||||
setlocale(LC_ALL, "en_US.utf8");
|
|
||||||
void* library = NULL;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string programPath = GetProgramPath();
|
|
||||||
std::string libraryName = dirname((char*)programPath.c_str());
|
|
||||||
libraryName += "/../lib/libapplauncher.so";
|
|
||||||
library = dlopen(libraryName.c_str(), RTLD_LAZY);
|
|
||||||
|
|
||||||
if (library == NULL) {
|
|
||||||
fprintf(stderr, "dlopen failed: %s\n", dlerror());
|
|
||||||
fprintf(stderr, "%s not found.\n", libraryName.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (library != NULL) {
|
|
||||||
start_launcher start = (start_launcher)dlsym(library, "start_launcher");
|
|
||||||
stop_launcher stop = (stop_launcher)dlsym(library, "stop_launcher");
|
|
||||||
|
|
||||||
if (start != NULL && stop != NULL) {
|
|
||||||
if (start(argc, argv) == true) {
|
|
||||||
result = 0;
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "cannot find start_launcher and stop_launcher in libapplauncher.so");
|
|
||||||
}
|
|
||||||
|
|
||||||
dlclose(library);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LINUXPLATFORM_H
|
|
||||||
#define LINUXPLATFORM_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "PosixPlatform.h"
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xatom.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
class LinuxPlatform : virtual public Platform, PosixPlatform {
|
|
||||||
private:
|
|
||||||
pthread_t FMainThread;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual TString getTmpDirString();
|
|
||||||
|
|
||||||
public:
|
|
||||||
LinuxPlatform(void);
|
|
||||||
virtual ~LinuxPlatform(void);
|
|
||||||
|
|
||||||
TString GetPackageAppDirectory();
|
|
||||||
TString GetPackageLauncherDirectory();
|
|
||||||
TString GetPackageRuntimeBinDirectory();
|
|
||||||
|
|
||||||
virtual void ShowMessage(TString title, TString description);
|
|
||||||
virtual void ShowMessage(TString description);
|
|
||||||
|
|
||||||
virtual TCHAR* ConvertStringToFileSystemString(
|
|
||||||
TCHAR* Source, bool &release);
|
|
||||||
virtual TCHAR* ConvertFileSystemStringToString(
|
|
||||||
TCHAR* Source, bool &release);
|
|
||||||
|
|
||||||
virtual TString GetPackageRootDirectory();
|
|
||||||
virtual TString GetAppDataDirectory();
|
|
||||||
virtual TString GetAppName();
|
|
||||||
|
|
||||||
virtual TString GetModuleFileName();
|
|
||||||
|
|
||||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath);
|
|
||||||
|
|
||||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName);
|
|
||||||
|
|
||||||
virtual bool IsMainThread();
|
|
||||||
virtual TPlatformNumber GetMemorySize();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //LINUXPLATFORM_H
|
|
@ -65,7 +65,6 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
|||||||
private static final ResourceBundle I18N = ResourceBundle.getBundle(
|
private static final ResourceBundle I18N = ResourceBundle.getBundle(
|
||||||
"jdk.incubator.jpackage.internal.resources.MacResources");
|
"jdk.incubator.jpackage.internal.resources.MacResources");
|
||||||
|
|
||||||
private static final String LIBRARY_NAME = "libapplauncher.dylib";
|
|
||||||
private static final String TEMPLATE_BUNDLE_ICON = "java.icns";
|
private static final String TEMPLATE_BUNDLE_ICON = "java.icns";
|
||||||
private static final String OS_TYPE_CODE = "APPL";
|
private static final String OS_TYPE_CODE = "APPL";
|
||||||
private static final String TEMPLATE_INFO_PLIST_LITE =
|
private static final String TEMPLATE_INFO_PLIST_LITE =
|
||||||
@ -265,11 +264,9 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
|||||||
|
|
||||||
// create the main app launcher
|
// create the main app launcher
|
||||||
try (InputStream is_launcher =
|
try (InputStream is_launcher =
|
||||||
getResourceAsStream("jpackageapplauncher");
|
getResourceAsStream("jpackageapplauncher")) {
|
||||||
InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
|
|
||||||
// Copy executable and library to MacOS folder
|
// Copy executable and library to MacOS folder
|
||||||
writeEntry(is_launcher, executable);
|
writeEntry(is_launcher, executable);
|
||||||
writeEntry(is_lib, macOSDir.resolve(LIBRARY_NAME));
|
|
||||||
}
|
}
|
||||||
executable.toFile().setExecutable(true, false);
|
executable.toFile().setExecutable(true, false);
|
||||||
// generate main app launcher config file
|
// generate main app launcher config file
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AppLauncher.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "UnixSysInfo.h"
|
||||||
|
#include "JvmLauncher.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Jvm* jvmLauncher = 0;
|
||||||
|
|
||||||
|
void launchJvm() {
|
||||||
|
// On Mac JLI_Launch() spawns a new thread that actually starts the JVM.
|
||||||
|
// This new thread simply re-runs launcher's main() function with
|
||||||
|
// arguments passed into JLI_Launch() call.
|
||||||
|
// Jvm::launch() calls JLI_Launch() triggering thread spawning.
|
||||||
|
jvmLauncher->launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initJvmLauncher() {
|
||||||
|
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||||
|
|
||||||
|
// Launcher should be in "Contents/MacOS" subdirectory of app image.
|
||||||
|
// However, don't strip "Contents" folder from launcher path, so that app
|
||||||
|
// image root directory would be set to "Contents" subfolder of app image.
|
||||||
|
const tstring appImageRoot = FileUtils::dirname(
|
||||||
|
FileUtils::dirname(launcherPath));
|
||||||
|
|
||||||
|
// Create JVM launcher and save in global variable.
|
||||||
|
jvmLauncher = AppLauncher()
|
||||||
|
.setImageRoot(appImageRoot)
|
||||||
|
.addJvmLibName(_T("Contents/Home/lib/libjli.dylib"))
|
||||||
|
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
|
||||||
|
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||||
|
<< _T("runtime"))
|
||||||
|
.createJvmLauncher();
|
||||||
|
|
||||||
|
// Kick start JVM launching. The function wouldn't return!
|
||||||
|
launchJvm();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
setlocale(LC_ALL, "en_US.utf8");
|
||||||
|
if (jvmLauncher) {
|
||||||
|
// This is the call from the thread spawned by JVM.
|
||||||
|
// Skip initialization phase as we have done this already in the first
|
||||||
|
// call of main().
|
||||||
|
// Besides we should ignore main() arguments because these are the
|
||||||
|
// arguments passed into JLI_Launch() call and not the arguments with
|
||||||
|
// which the launcher was started.
|
||||||
|
return AppLauncher::launch(std::nothrow, launchJvm);
|
||||||
|
}
|
||||||
|
|
||||||
|
SysInfo::argc = argc;
|
||||||
|
SysInfo::argv = argv;
|
||||||
|
return AppLauncher::launch(std::nothrow, initJvmLauncher);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
namespace SysInfo {
|
||||||
|
|
||||||
|
tstring getProcessModulePath() {
|
||||||
|
std::vector<char> buffer;
|
||||||
|
uint32_t bufferSize = 0;
|
||||||
|
do {
|
||||||
|
int len = _NSGetExecutablePath(buffer.data(), &bufferSize);
|
||||||
|
if (len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
JP_THROW(tstrings::any() << "_NSGetExecutablePath() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.resize(bufferSize);
|
||||||
|
} while (true);
|
||||||
|
tstring reply = tstring(buffer.data(),
|
||||||
|
buffer.size() - 1 /* don't count trailing '0' */);
|
||||||
|
return FileUtils::toAbsolutePath(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace SysInfo
|
@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
typedef bool (*start_launcher)(int argc, char* argv[]);
|
|
||||||
typedef void (*stop_launcher)();
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
#if !__has_feature(objc_arc)
|
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int result = 1;
|
|
||||||
|
|
||||||
@try {
|
|
||||||
setlocale(LC_ALL, "en_US.utf8");
|
|
||||||
|
|
||||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
|
||||||
NSString *mainBundlePath = [mainBundle bundlePath];
|
|
||||||
NSString *libraryName = [mainBundlePath stringByAppendingPathComponent:@"Contents/MacOS/libapplauncher.dylib"];
|
|
||||||
|
|
||||||
void* library = dlopen([libraryName UTF8String], RTLD_LAZY);
|
|
||||||
|
|
||||||
if (library == NULL) {
|
|
||||||
NSLog(@"%@ not found.\n", libraryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (library != NULL) {
|
|
||||||
start_launcher start =
|
|
||||||
(start_launcher)dlsym(library, "start_launcher");
|
|
||||||
stop_launcher stop =
|
|
||||||
(stop_launcher)dlsym(library, "stop_launcher");
|
|
||||||
|
|
||||||
if (start != NULL && stop != NULL) {
|
|
||||||
if (start(argc, argv) == true) {
|
|
||||||
result = 0;
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
} else if (start == NULL) {
|
|
||||||
NSLog(@"start_launcher not found in %@.\n", libraryName);
|
|
||||||
} else {
|
|
||||||
NSLog(@"stop_launcher not found in %@.\n", libraryName);
|
|
||||||
}
|
|
||||||
dlclose(library);
|
|
||||||
}
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
NSLog(@"%@: %@", exception, [exception callStackSymbols]);
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
|
||||||
[pool drain];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MACPLATFORM_H
|
|
||||||
#define MACPLATFORM_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "PosixPlatform.h"
|
|
||||||
|
|
||||||
class MacPlatform : virtual public Platform, PosixPlatform {
|
|
||||||
private:
|
|
||||||
bool UsePListForConfigFile();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual TString getTmpDirString();
|
|
||||||
|
|
||||||
public:
|
|
||||||
MacPlatform(void);
|
|
||||||
virtual ~MacPlatform(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void ShowMessage(TString title, TString description);
|
|
||||||
virtual void ShowMessage(TString description);
|
|
||||||
|
|
||||||
virtual TCHAR* ConvertStringToFileSystemString(
|
|
||||||
TCHAR* Source, bool &release);
|
|
||||||
virtual TCHAR* ConvertFileSystemStringToString(
|
|
||||||
TCHAR* Source, bool &release);
|
|
||||||
|
|
||||||
virtual TString GetPackageRootDirectory();
|
|
||||||
virtual TString GetAppDataDirectory();
|
|
||||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath);
|
|
||||||
virtual TString GetAppName();
|
|
||||||
|
|
||||||
TString GetPackageAppDirectory();
|
|
||||||
TString GetPackageLauncherDirectory();
|
|
||||||
TString GetPackageRuntimeBinDirectory();
|
|
||||||
|
|
||||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName);
|
|
||||||
virtual TString GetModuleFileName();
|
|
||||||
|
|
||||||
virtual bool IsMainThread();
|
|
||||||
virtual TPlatformNumber GetMemorySize();
|
|
||||||
|
|
||||||
virtual std::map<TString, TString> GetKeys();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // MACPLATFORM_H
|
|
@ -1,505 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
#include "MacPlatform.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "Package.h"
|
|
||||||
#include "PropertyFile.h"
|
|
||||||
#include "IniFile.h"
|
|
||||||
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <mach-o/dyld.h>
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <AppKit/NSRunningApplication.h>
|
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#include <CoreFoundation/CFString.h>
|
|
||||||
|
|
||||||
#ifdef __OBJC__
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#endif //__OBJC__
|
|
||||||
|
|
||||||
#define MAC_JPACKAGE_TMP_DIR \
|
|
||||||
"/Library/Application Support/Java/JPackage/tmp"
|
|
||||||
|
|
||||||
NSString* StringToNSString(TString Value) {
|
|
||||||
NSString* result = [NSString stringWithCString : Value.c_str()
|
|
||||||
encoding : [NSString defaultCStringEncoding]];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSystemStringToString::FileSystemStringToString(const TCHAR* value) {
|
|
||||||
bool release = false;
|
|
||||||
PlatformString lvalue = PlatformString(value);
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
TCHAR* buffer = platform.ConvertFileSystemStringToString(lvalue, release);
|
|
||||||
FData = buffer;
|
|
||||||
|
|
||||||
if (buffer != NULL && release == true) {
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSystemStringToString::operator TString() {
|
|
||||||
return FData;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringToFileSystemString::StringToFileSystemString(const TString &value) {
|
|
||||||
FRelease = false;
|
|
||||||
PlatformString lvalue = PlatformString(value);
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
FData = platform.ConvertStringToFileSystemString(lvalue, FRelease);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringToFileSystemString::~StringToFileSystemString() {
|
|
||||||
if (FRelease == true) {
|
|
||||||
delete[] FData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringToFileSystemString::operator TCHAR* () {
|
|
||||||
return FData;
|
|
||||||
}
|
|
||||||
|
|
||||||
MacPlatform::MacPlatform(void) : Platform(), PosixPlatform() {
|
|
||||||
}
|
|
||||||
|
|
||||||
MacPlatform::~MacPlatform(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetPackageAppDirectory() {
|
|
||||||
return FilePath::IncludeTrailingSeparator(
|
|
||||||
GetPackageRootDirectory()) + _T("app");
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetPackageLauncherDirectory() {
|
|
||||||
return FilePath::IncludeTrailingSeparator(
|
|
||||||
GetPackageRootDirectory()) + _T("MacOS");
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetPackageRuntimeBinDirectory() {
|
|
||||||
return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) +
|
|
||||||
_T("runtime/Contents/Home/bin");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacPlatform::UsePListForConfigFile() {
|
|
||||||
return FilePath::FileExists(GetConfigFileName()) == false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacPlatform::ShowMessage(TString Title, TString Description) {
|
|
||||||
NSString *ltitle = StringToNSString(Title);
|
|
||||||
NSString *ldescription = StringToNSString(Description);
|
|
||||||
|
|
||||||
NSLog(@"%@:%@", ltitle, ldescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacPlatform::ShowMessage(TString Description) {
|
|
||||||
TString appname = GetModuleFileName();
|
|
||||||
appname = FilePath::ExtractFileName(appname);
|
|
||||||
ShowMessage(appname, Description);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::getTmpDirString() {
|
|
||||||
return TString(MAC_JPACKAGE_TMP_DIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR* MacPlatform::ConvertStringToFileSystemString(TCHAR* Source,
|
|
||||||
bool &release) {
|
|
||||||
TCHAR* result = NULL;
|
|
||||||
release = false;
|
|
||||||
CFStringRef StringRef = CFStringCreateWithCString(kCFAllocatorDefault,
|
|
||||||
Source, kCFStringEncodingUTF8);
|
|
||||||
|
|
||||||
if (StringRef != NULL) {
|
|
||||||
@ try {
|
|
||||||
CFIndex length =
|
|
||||||
CFStringGetMaximumSizeOfFileSystemRepresentation(StringRef);
|
|
||||||
result = new char[length + 1];
|
|
||||||
if (result != NULL) {
|
|
||||||
if (CFStringGetFileSystemRepresentation(StringRef,
|
|
||||||
result, length)) {
|
|
||||||
release = true;
|
|
||||||
} else {
|
|
||||||
delete[] result;
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@finally
|
|
||||||
{
|
|
||||||
CFRelease(StringRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR* MacPlatform::ConvertFileSystemStringToString(TCHAR* Source,
|
|
||||||
bool &release) {
|
|
||||||
TCHAR* result = NULL;
|
|
||||||
release = false;
|
|
||||||
CFStringRef StringRef = CFStringCreateWithFileSystemRepresentation(
|
|
||||||
kCFAllocatorDefault, Source);
|
|
||||||
|
|
||||||
if (StringRef != NULL) {
|
|
||||||
@ try {
|
|
||||||
CFIndex length = CFStringGetLength(StringRef);
|
|
||||||
|
|
||||||
if (length > 0) {
|
|
||||||
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(
|
|
||||||
length, kCFStringEncodingUTF8);
|
|
||||||
|
|
||||||
result = new char[maxSize + 1];
|
|
||||||
if (result != NULL) {
|
|
||||||
if (CFStringGetCString(StringRef, result, maxSize,
|
|
||||||
kCFStringEncodingUTF8) == true) {
|
|
||||||
release = true;
|
|
||||||
} else {
|
|
||||||
delete[] result;
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@finally
|
|
||||||
{
|
|
||||||
CFRelease(StringRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetPackageRootDirectory() {
|
|
||||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
|
||||||
NSString *mainBundlePath = [mainBundle bundlePath];
|
|
||||||
NSString *contentsPath =
|
|
||||||
[mainBundlePath stringByAppendingString : @"/Contents"];
|
|
||||||
TString result = [contentsPath UTF8String];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetAppDataDirectory() {
|
|
||||||
TString result;
|
|
||||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(
|
|
||||||
NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
|
||||||
NSString *applicationSupportDirectory = [paths firstObject];
|
|
||||||
result = [applicationSupportDirectory UTF8String];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetBundledJavaLibraryFileName(TString RuntimePath) {
|
|
||||||
TString result;
|
|
||||||
|
|
||||||
// first try lib/, then lib/jli
|
|
||||||
result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
|
||||||
_T("Contents/Home/lib/libjli.dylib");
|
|
||||||
|
|
||||||
if (FilePath::FileExists(result) == false) {
|
|
||||||
result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
|
||||||
_T("Contents/Home/lib/jli/libjli.dylib");
|
|
||||||
|
|
||||||
if (FilePath::FileExists(result) == false) {
|
|
||||||
// cannot find
|
|
||||||
NSLog(@"Cannot find libjli.dysym!");
|
|
||||||
result = _T("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetAppName() {
|
|
||||||
NSString *appName = [[NSProcessInfo processInfo] processName];
|
|
||||||
TString result = [appName UTF8String];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PosixProcess::Cleanup() {
|
|
||||||
if (FOutputHandle != 0) {
|
|
||||||
close(FOutputHandle);
|
|
||||||
FOutputHandle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FInputHandle != 0) {
|
|
||||||
close(FInputHandle);
|
|
||||||
FInputHandle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigaction(SIGINT, &savintr, (struct sigaction *) 0);
|
|
||||||
sigaction(SIGQUIT, &savequit, (struct sigaction *) 0);
|
|
||||||
sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *) 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PIPE_READ 0
|
|
||||||
#define PIPE_WRITE 1
|
|
||||||
|
|
||||||
bool PosixProcess::Execute(const TString Application,
|
|
||||||
const std::vector<TString> Arguments, bool AWait) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FRunning == false) {
|
|
||||||
FRunning = true;
|
|
||||||
|
|
||||||
int handles[2];
|
|
||||||
|
|
||||||
if (pipe(handles) == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sigaction sa;
|
|
||||||
sa.sa_handler = SIG_IGN;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
sigemptyset(&savintr.sa_mask);
|
|
||||||
sigemptyset(&savequit.sa_mask);
|
|
||||||
sigaction(SIGINT, &sa, &savintr);
|
|
||||||
sigaction(SIGQUIT, &sa, &savequit);
|
|
||||||
sigaddset(&sa.sa_mask, SIGCHLD);
|
|
||||||
sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock);
|
|
||||||
|
|
||||||
FChildPID = fork();
|
|
||||||
|
|
||||||
// PID returned by vfork is 0 for the child process and the
|
|
||||||
// PID of the child process for the parent.
|
|
||||||
if (FChildPID == -1) {
|
|
||||||
// Error
|
|
||||||
TString message = PlatformString::Format(
|
|
||||||
_T("Error: Unable to create process %s"),
|
|
||||||
Application.data());
|
|
||||||
throw Exception(message);
|
|
||||||
} else if (FChildPID == 0) {
|
|
||||||
Cleanup();
|
|
||||||
TString command = Application;
|
|
||||||
|
|
||||||
for (std::vector<TString>::const_iterator iterator =
|
|
||||||
Arguments.begin(); iterator != Arguments.end();
|
|
||||||
iterator++) {
|
|
||||||
command += TString(_T(" ")) + *iterator;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("%s\n", command.data());
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
dup2(handles[PIPE_READ], STDIN_FILENO);
|
|
||||||
dup2(handles[PIPE_WRITE], STDOUT_FILENO);
|
|
||||||
|
|
||||||
close(handles[PIPE_READ]);
|
|
||||||
close(handles[PIPE_WRITE]);
|
|
||||||
|
|
||||||
execl("/bin/sh", "sh", "-c", command.data(), (char *) 0);
|
|
||||||
|
|
||||||
_exit(127);
|
|
||||||
} else {
|
|
||||||
FOutputHandle = handles[PIPE_READ];
|
|
||||||
FInputHandle = handles[PIPE_WRITE];
|
|
||||||
|
|
||||||
if (AWait == true) {
|
|
||||||
ReadOutput();
|
|
||||||
Wait();
|
|
||||||
Cleanup();
|
|
||||||
FRunning = false;
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppendPListArrayToIniFile(NSDictionary *infoDictionary,
|
|
||||||
IniFile *result, TString Section) {
|
|
||||||
NSString *sectionKey =
|
|
||||||
[NSString stringWithUTF8String : PlatformString(Section).toMultibyte()];
|
|
||||||
NSDictionary *array = [infoDictionary objectForKey : sectionKey];
|
|
||||||
|
|
||||||
for (id option in array) {
|
|
||||||
if ([option isKindOfClass : [NSString class]]) {
|
|
||||||
TString arg = [option UTF8String];
|
|
||||||
|
|
||||||
TString name;
|
|
||||||
TString value;
|
|
||||||
|
|
||||||
if (Helpers::SplitOptionIntoNameValue(arg, name, value) == true) {
|
|
||||||
result->Append(Section, name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppendPListDictionaryToIniFile(NSDictionary *infoDictionary,
|
|
||||||
IniFile *result, TString Section, bool FollowSection = true) {
|
|
||||||
NSDictionary *dictionary = NULL;
|
|
||||||
|
|
||||||
if (FollowSection == true) {
|
|
||||||
NSString *sectionKey = [NSString stringWithUTF8String : PlatformString(
|
|
||||||
Section).toMultibyte()];
|
|
||||||
dictionary = [infoDictionary objectForKey : sectionKey];
|
|
||||||
} else {
|
|
||||||
dictionary = infoDictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (id key in dictionary) {
|
|
||||||
id option = [dictionary valueForKey : key];
|
|
||||||
|
|
||||||
if ([key isKindOfClass : [NSString class]] &&
|
|
||||||
[option isKindOfClass : [NSString class]]) {
|
|
||||||
TString name = [key UTF8String];
|
|
||||||
TString value = [option UTF8String];
|
|
||||||
result->Append(Section, name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert parts of the info.plist to the INI format the rest of the jpackage
|
|
||||||
// uses unless a jpackage config file exists.
|
|
||||||
ISectionalPropertyContainer* MacPlatform::GetConfigFile(TString FileName) {
|
|
||||||
IniFile* result = new IniFile();
|
|
||||||
if (result == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UsePListForConfigFile() == false) {
|
|
||||||
result->LoadFromFile(FileName);
|
|
||||||
} else {
|
|
||||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
|
||||||
NSDictionary *infoDictionary = [mainBundle infoDictionary];
|
|
||||||
std::map<TString, TString> keys = GetKeys();
|
|
||||||
|
|
||||||
// JPackage options.
|
|
||||||
AppendPListDictionaryToIniFile(infoDictionary, result,
|
|
||||||
keys[CONFIG_SECTION_APPLICATION], false);
|
|
||||||
|
|
||||||
// jvmargs
|
|
||||||
AppendPListArrayToIniFile(infoDictionary, result,
|
|
||||||
keys[CONFIG_SECTION_JAVAOPTIONS]);
|
|
||||||
|
|
||||||
// Generate AppCDS Cache
|
|
||||||
AppendPListDictionaryToIniFile(infoDictionary, result,
|
|
||||||
keys[CONFIG_SECTION_APPCDSJAVAOPTIONS]);
|
|
||||||
AppendPListDictionaryToIniFile(infoDictionary, result,
|
|
||||||
keys[CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS]);
|
|
||||||
|
|
||||||
// args
|
|
||||||
AppendPListArrayToIniFile(infoDictionary, result,
|
|
||||||
keys[CONFIG_SECTION_ARGOPTIONS]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString GetModuleFileNameOSX() {
|
|
||||||
Dl_info module_info;
|
|
||||||
if (dladdr(reinterpret_cast<void*> (GetModuleFileNameOSX),
|
|
||||||
&module_info) == 0) {
|
|
||||||
// Failed to find the symbol we asked for.
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
return TString(module_info.dli_fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString MacPlatform::GetModuleFileName() {
|
|
||||||
TString result;
|
|
||||||
DynamicBuffer<TCHAR> buffer(MAX_PATH);
|
|
||||||
uint32_t size = buffer.GetSize();
|
|
||||||
|
|
||||||
if (_NSGetExecutablePath(buffer.GetData(), &size) == 0) {
|
|
||||||
result = FileSystemStringToString(buffer.GetData());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacPlatform::IsMainThread() {
|
|
||||||
bool result = (pthread_main_np() == 1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TPlatformNumber MacPlatform::GetMemorySize() {
|
|
||||||
unsigned long long memory = [[NSProcessInfo processInfo] physicalMemory];
|
|
||||||
|
|
||||||
// Convert from bytes to megabytes.
|
|
||||||
TPlatformNumber result = memory / 1048576;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<TString, TString> MacPlatform::GetKeys() {
|
|
||||||
std::map<TString, TString> keys;
|
|
||||||
|
|
||||||
if (UsePListForConfigFile() == false) {
|
|
||||||
return Platform::GetKeys();
|
|
||||||
} else {
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_VERSION,
|
|
||||||
_T("app.version")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINJAR_KEY,
|
|
||||||
_T("JavaMainJarName")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_MAINMODULE_KEY,
|
|
||||||
_T("JavaMainModuleName")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_MAINCLASSNAME_KEY, _T("JavaMainClassName")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_CLASSPATH_KEY, _T("JavaAppClasspath")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(APP_NAME_KEY,
|
|
||||||
_T("CFBundleName")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(JAVA_RUNTIME_KEY,
|
|
||||||
_T("JavaRuntime")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(JPACKAGE_APP_DATA_DIR,
|
|
||||||
_T("CFBundleIdentifier")));
|
|
||||||
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_SPLASH_KEY,
|
|
||||||
_T("app.splash")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_MEMORY,
|
|
||||||
_T("app.memory")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_DEBUG,
|
|
||||||
_T("app.debug")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_APPLICATION_INSTANCE, _T("app.application.instance")));
|
|
||||||
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_SECTION_APPLICATION, _T("Application")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_SECTION_JAVAOPTIONS, _T("JavaOptions")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_SECTION_APPCDSJAVAOPTIONS, _T("AppCDSJavaOptions")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS,
|
|
||||||
_T("AppCDSGenerateCacheJavaOptions")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(
|
|
||||||
CONFIG_SECTION_ARGOPTIONS, _T("ArgOptions")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLATFORM_DEFS_H
|
|
||||||
#define PLATFORM_DEFS_H
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#ifndef MAC
|
|
||||||
#define MAC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _T(x) x
|
|
||||||
|
|
||||||
typedef char TCHAR;
|
|
||||||
typedef std::string TString;
|
|
||||||
#define StringLength strlen
|
|
||||||
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
#define TRAILING_PATHSEPARATOR '/'
|
|
||||||
#define BAD_TRAILING_PATHSEPARATOR '\\'
|
|
||||||
#define PATH_SEPARATOR ':'
|
|
||||||
#define BAD_PATH_SEPARATOR ';'
|
|
||||||
#define MAX_PATH 1000
|
|
||||||
|
|
||||||
typedef long TPlatformNumber;
|
|
||||||
typedef pid_t TProcessID;
|
|
||||||
|
|
||||||
#define HMODULE void*
|
|
||||||
|
|
||||||
typedef void* Module;
|
|
||||||
typedef void* Procedure;
|
|
||||||
|
|
||||||
|
|
||||||
// StringToFileSystemString is a stack object. It's usage is
|
|
||||||
// simply inline to convert a
|
|
||||||
// TString to a file system string. Example:
|
|
||||||
//
|
|
||||||
// return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
|
|
||||||
//
|
|
||||||
class StringToFileSystemString {
|
|
||||||
// Prohibit Heap-Based StringToFileSystemString
|
|
||||||
private:
|
|
||||||
static void *operator new(size_t size);
|
|
||||||
static void operator delete(void *ptr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TCHAR* FData;
|
|
||||||
bool FRelease;
|
|
||||||
|
|
||||||
public:
|
|
||||||
StringToFileSystemString(const TString &value);
|
|
||||||
~StringToFileSystemString();
|
|
||||||
|
|
||||||
operator TCHAR* ();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// FileSystemStringToString is a stack object. It's usage is
|
|
||||||
// simply inline to convert a
|
|
||||||
// file system string to a TString. Example:
|
|
||||||
//
|
|
||||||
// DynamicBuffer<TCHAR> buffer(MAX_PATH);
|
|
||||||
// if (readlink("/proc/self/exe", buffer.GetData(), MAX_PATH) != -1)
|
|
||||||
// result = FileSystemStringToString(buffer.GetData());
|
|
||||||
//
|
|
||||||
class FileSystemStringToString {
|
|
||||||
// Prohibit Heap-Based FileSystemStringToString
|
|
||||||
private:
|
|
||||||
static void *operator new(size_t size);
|
|
||||||
static void operator delete(void *ptr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TString FData;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileSystemStringToString(const TCHAR* value);
|
|
||||||
|
|
||||||
operator TString ();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PLATFORM_DEFS_H
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -120,12 +120,11 @@ public abstract class AbstractAppImageBuilder {
|
|||||||
// legacy way and the main class string must be
|
// legacy way and the main class string must be
|
||||||
// of the format com/foo/Main
|
// of the format com/foo/Main
|
||||||
if (mainJar != null) {
|
if (mainJar != null) {
|
||||||
out.println("app.mainjar=" + getCfgAppDir()
|
out.println("app.classpath=" + getCfgAppDir()
|
||||||
+ mainJar.toPath().getFileName().toString());
|
+ mainJar.toPath().getFileName().toString());
|
||||||
}
|
}
|
||||||
if (mainClass != null) {
|
if (mainClass != null) {
|
||||||
out.println("app.mainclass="
|
out.println("app.mainclass=" + mainClass);
|
||||||
+ mainClass.replace("\\", "/"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,26 +132,20 @@ public abstract class AbstractAppImageBuilder {
|
|||||||
out.println("[JavaOptions]");
|
out.println("[JavaOptions]");
|
||||||
List<String> jvmargs = JAVA_OPTIONS.fetchFrom(params);
|
List<String> jvmargs = JAVA_OPTIONS.fetchFrom(params);
|
||||||
for (String arg : jvmargs) {
|
for (String arg : jvmargs) {
|
||||||
out.println(arg);
|
out.println("java-options=" + arg);
|
||||||
}
|
}
|
||||||
Path modsDir = getAppModsDir();
|
Path modsDir = getAppModsDir();
|
||||||
|
|
||||||
if (modsDir != null && modsDir.toFile().exists()) {
|
if (modsDir != null && modsDir.toFile().exists()) {
|
||||||
out.println("--module-path");
|
out.println("java-options=" + "--module-path");
|
||||||
out.println(getCfgAppDir().replace("\\","/") + "mods");
|
out.println("java-options=" + getCfgAppDir().replace("\\","/") + "mods");
|
||||||
}
|
}
|
||||||
|
|
||||||
out.println();
|
out.println();
|
||||||
out.println("[ArgOptions]");
|
out.println("[ArgOptions]");
|
||||||
List<String> args = ARGUMENTS.fetchFrom(params);
|
List<String> args = ARGUMENTS.fetchFrom(params);
|
||||||
for (String arg : args) {
|
for (String arg : args) {
|
||||||
if (arg.endsWith("=") &&
|
out.println("arguments=" + arg);
|
||||||
(arg.indexOf("=") == arg.lastIndexOf("="))) {
|
|
||||||
out.print(arg.substring(0, arg.length() - 1));
|
|
||||||
out.println("\\=");
|
|
||||||
} else {
|
|
||||||
out.println(arg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "AppLauncher.h"
|
||||||
|
#include "JvmLauncher.h"
|
||||||
|
#include "CfgFile.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Dll.h"
|
||||||
|
#include "Toolbox.h"
|
||||||
|
#include "SysInfo.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
AppLauncher::AppLauncher() {
|
||||||
|
launcherPath = SysInfo::getProcessModulePath();
|
||||||
|
args = SysInfo::getCommandArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct find_jvmlib {
|
||||||
|
find_jvmlib(const tstring& v): runtimePath(v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator () (const tstring& jvmLibName) const {
|
||||||
|
const tstring path = FileUtils::mkpath() << runtimePath << jvmLibName;
|
||||||
|
return FileUtils::isFileExists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const tstring& runtimePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
tstring findJvmLib(const CfgFile& cfgFile, const tstring& defaultRuntimePath,
|
||||||
|
const tstring_array& jvmLibNames) {
|
||||||
|
const CfgFile::Properties& appOptions = cfgFile.getProperties(
|
||||||
|
SectionName::Application);
|
||||||
|
|
||||||
|
const CfgFile::Properties::const_iterator runtimePathProp = appOptions.find(
|
||||||
|
PropertyName::runtime);
|
||||||
|
tstring runtimePath;
|
||||||
|
if (runtimePathProp != appOptions.end()) {
|
||||||
|
runtimePath = CfgFile::asString(*runtimePathProp);
|
||||||
|
} else {
|
||||||
|
runtimePath = defaultRuntimePath;
|
||||||
|
LOG_TRACE(tstrings::any()
|
||||||
|
<< "Property \"" << PropertyName::runtime.name()
|
||||||
|
<< "\" not found in \"" << SectionName::Application.name()
|
||||||
|
<< "\" section of launcher config file."
|
||||||
|
<< " Using Java runtime from \""
|
||||||
|
<< runtimePath << "\" directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
const tstring_array::const_iterator jvmLibNameEntry = std::find_if(
|
||||||
|
jvmLibNames.begin(),
|
||||||
|
jvmLibNames.end(),
|
||||||
|
find_jvmlib(runtimePath));
|
||||||
|
|
||||||
|
if (jvmLibNameEntry == jvmLibNames.end()) {
|
||||||
|
JP_THROW(tstrings::any() << "Failed to find JVM in \""
|
||||||
|
<< runtimePath
|
||||||
|
<< "\" directory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileUtils::mkpath() << runtimePath << *jvmLibNameEntry;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Jvm* AppLauncher::createJvmLauncher() const {
|
||||||
|
const tstring cfgFilePath = FileUtils::mkpath()
|
||||||
|
<< appDirPath
|
||||||
|
<< FileUtils::basename(FileUtils::replaceSuffix(
|
||||||
|
launcherPath, _T(".cfg")));
|
||||||
|
|
||||||
|
LOG_TRACE(tstrings::any() << "Launcher config file path: \""
|
||||||
|
<< cfgFilePath << "\"");
|
||||||
|
|
||||||
|
CfgFile::Macros macros;
|
||||||
|
macros[_T("$APPDIR")] = appDirPath;
|
||||||
|
macros[_T("$BINDIR")] = FileUtils::dirname(launcherPath);
|
||||||
|
macros[_T("$ROOTDIR")] = imageRoot;
|
||||||
|
|
||||||
|
CfgFile cfgFile = CfgFile::load(cfgFilePath).expandMacros(macros);
|
||||||
|
|
||||||
|
if (!args.empty()) {
|
||||||
|
// Override default launcher arguments.
|
||||||
|
cfgFile.setPropertyValue(SectionName::ArgOptions,
|
||||||
|
PropertyName::arguments, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Jvm> jvm(new Jvm());
|
||||||
|
|
||||||
|
(*jvm)
|
||||||
|
.setPath(findJvmLib(cfgFile, defaultRuntimePath, jvmLibNames))
|
||||||
|
.addArgument(launcherPath)
|
||||||
|
.initFromConfigFile(cfgFile);
|
||||||
|
|
||||||
|
return jvm.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AppLauncher::launch() const {
|
||||||
|
std::unique_ptr<Jvm>(createJvmLauncher())->launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const std::string* theLastErrorMsg = 0;
|
||||||
|
|
||||||
|
NopLogAppender nopLogAppender;
|
||||||
|
|
||||||
|
class StandardLogAppender : public LogAppender {
|
||||||
|
public:
|
||||||
|
virtual void append(const LogEvent& v) {
|
||||||
|
std::cerr << "[" << v.logLevel << "] "
|
||||||
|
<< v.fileName
|
||||||
|
<< ":" << v.lineNum
|
||||||
|
<< ": " << v.message
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
} standardLogAppender;
|
||||||
|
|
||||||
|
class LastErrorLogAppender : public LogAppender {
|
||||||
|
public:
|
||||||
|
virtual void append(const LogEvent& v) {
|
||||||
|
std::cerr << AppLauncher::lastErrorMsg() << std::endl;
|
||||||
|
}
|
||||||
|
} lastErrorLogAppender;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
LogAppender& AppLauncher::defaultLastErrorLogAppender() {
|
||||||
|
return lastErrorLogAppender;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string AppLauncher::lastErrorMsg() {
|
||||||
|
if (theLastErrorMsg) {
|
||||||
|
return *theLastErrorMsg;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AppLauncher::isWithLogging() {
|
||||||
|
// If JPACKAGE_DEBUG environment variable is set to "true"
|
||||||
|
// logging is enabled.
|
||||||
|
return SysInfo::getEnvVariable(
|
||||||
|
std::nothrow, _T("JPACKAGE_DEBUG")) == _T("true");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class ResetLastErrorMsgAtEndOfScope {
|
||||||
|
public:
|
||||||
|
~ResetLastErrorMsgAtEndOfScope() {
|
||||||
|
JP_NO_THROW(theLastErrorMsg = 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SetLoggerAtEndOfScope {
|
||||||
|
public:
|
||||||
|
SetLoggerAtEndOfScope(
|
||||||
|
std::unique_ptr<WithExtraLogAppender>& withLogAppender,
|
||||||
|
LogAppender* lastErrorLogAppender):
|
||||||
|
withLogAppender(withLogAppender),
|
||||||
|
lastErrorLogAppender(lastErrorLogAppender) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~SetLoggerAtEndOfScope() {
|
||||||
|
JP_TRY;
|
||||||
|
std::unique_ptr<WithExtraLogAppender> other(
|
||||||
|
new WithExtraLogAppender(*lastErrorLogAppender));
|
||||||
|
withLogAppender.swap(other);
|
||||||
|
JP_CATCH_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<WithExtraLogAppender>& withLogAppender;
|
||||||
|
LogAppender* lastErrorLogAppender;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int AppLauncher::launch(const std::nothrow_t&,
|
||||||
|
LauncherFunc func, LogAppender* lastErrorLogAppender) {
|
||||||
|
if (isWithLogging()) {
|
||||||
|
Logger::defaultLogger().setAppender(standardLogAppender);
|
||||||
|
} else {
|
||||||
|
Logger::defaultLogger().setAppender(nopLogAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
if (!lastErrorLogAppender) {
|
||||||
|
lastErrorLogAppender = &defaultLastErrorLogAppender();
|
||||||
|
}
|
||||||
|
std::unique_ptr<WithExtraLogAppender> withLogAppender;
|
||||||
|
std::string errorMsg;
|
||||||
|
const ResetLastErrorMsgAtEndOfScope resetLastErrorMsg;
|
||||||
|
|
||||||
|
JP_TRY;
|
||||||
|
|
||||||
|
// This will temporary change log appenders of the default logger
|
||||||
|
// to save log messages in the default and additional log appenders.
|
||||||
|
// Log appenders config of the default logger will be restored to
|
||||||
|
// the original state at function exit automatically.
|
||||||
|
const SetLoggerAtEndOfScope setLogger(withLogAppender, lastErrorLogAppender);
|
||||||
|
func();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// The point of all these redefines is to save the last raw error message in
|
||||||
|
// 'AppLauncher::theLastErrorMsg' variable.
|
||||||
|
// By default error messages are saved in exception instances with the details
|
||||||
|
// of error origin (source file, function name, line number).
|
||||||
|
// We don't want these details in user error messages. However we still want to
|
||||||
|
// save full information about the last error in the default log appender.
|
||||||
|
#undef JP_HANDLE_ERROR
|
||||||
|
#undef JP_HANDLE_UNKNOWN_ERROR
|
||||||
|
#undef JP_CATCH_EXCEPTIONS
|
||||||
|
#define JP_HANDLE_ERROR(e) \
|
||||||
|
do { \
|
||||||
|
errorMsg = (tstrings::any() << e.what()).str(); \
|
||||||
|
theLastErrorMsg = &errorMsg; \
|
||||||
|
reportError(JP_SOURCE_CODE_POS, e); \
|
||||||
|
} while(0)
|
||||||
|
#define JP_HANDLE_UNKNOWN_ERROR \
|
||||||
|
do { \
|
||||||
|
errorMsg = "Unknown error"; \
|
||||||
|
theLastErrorMsg = &errorMsg; \
|
||||||
|
reportUnknownError(JP_SOURCE_CODE_POS); \
|
||||||
|
} while(0)
|
||||||
|
#define JP_CATCH_EXCEPTIONS \
|
||||||
|
catch (const JpErrorBase& e) { \
|
||||||
|
errorMsg = (tstrings::any() << e.rawMessage()).str(); \
|
||||||
|
theLastErrorMsg = &errorMsg; \
|
||||||
|
try { \
|
||||||
|
throw; \
|
||||||
|
} catch (const std::runtime_error& e) { \
|
||||||
|
reportError(JP_SOURCE_CODE_POS, e); \
|
||||||
|
} \
|
||||||
|
} catch (const std::runtime_error& e) { \
|
||||||
|
errorMsg = lastCRTError(); \
|
||||||
|
theLastErrorMsg = &errorMsg; \
|
||||||
|
reportError(JP_SOURCE_CODE_POS, e); \
|
||||||
|
} \
|
||||||
|
JP_CATCH_UNKNOWN_EXCEPTION
|
||||||
|
|
||||||
|
JP_CATCH_ALL;
|
||||||
|
|
||||||
|
#undef JP_HANDLE_ERROR
|
||||||
|
#undef JP_HANDLE_UNKNOWN_ERROR
|
||||||
|
#undef JP_CATCH_EXCEPTIONS
|
||||||
|
#define JP_HANDLE_ERROR(e) JP_REPORT_ERROR(e)
|
||||||
|
#define JP_HANDLE_UNKNOWN_ERROR JP_REPORT_UNKNOWN_ERROR
|
||||||
|
#define JP_CATCH_EXCEPTIONS JP_DEFAULT_CATCH_EXCEPTIONS
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AppLauncher_h
|
||||||
|
#define AppLauncher_h
|
||||||
|
|
||||||
|
#include "tstrings.h"
|
||||||
|
|
||||||
|
class Jvm;
|
||||||
|
class LogAppender;
|
||||||
|
|
||||||
|
class AppLauncher {
|
||||||
|
public:
|
||||||
|
AppLauncher();
|
||||||
|
|
||||||
|
AppLauncher& setImageRoot(const tstring& v) {
|
||||||
|
imageRoot = v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppLauncher& setDefaultRuntimePath(const tstring& v) {
|
||||||
|
defaultRuntimePath = v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppLauncher& setAppDir(const tstring& v) {
|
||||||
|
appDirPath = v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppLauncher& addJvmLibName(const tstring& v) {
|
||||||
|
jvmLibNames.push_back(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Jvm* createJvmLauncher() const;
|
||||||
|
|
||||||
|
void launch() const;
|
||||||
|
|
||||||
|
static LogAppender& defaultLastErrorLogAppender();
|
||||||
|
|
||||||
|
static bool isWithLogging();
|
||||||
|
|
||||||
|
typedef void (*LauncherFunc) ();
|
||||||
|
|
||||||
|
static int launch(const std::nothrow_t&, LauncherFunc func,
|
||||||
|
LogAppender* lastErrorLogAppender = 0);
|
||||||
|
|
||||||
|
static std::string lastErrorMsg();
|
||||||
|
|
||||||
|
private:
|
||||||
|
tstring_array args;
|
||||||
|
tstring launcherPath;
|
||||||
|
tstring defaultRuntimePath;
|
||||||
|
tstring appDirPath;
|
||||||
|
tstring imageRoot;
|
||||||
|
tstring_array jvmLibNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AppLauncher_h
|
295
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.cpp
Normal file
295
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.cpp
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kludge_c++11.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "CfgFile.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Toolbox.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
|
const CfgFile::Properties& CfgFile::getProperties(
|
||||||
|
const SectionName& sectionName) const {
|
||||||
|
const PropertyMap::const_iterator entry = data.find(sectionName);
|
||||||
|
if (entry != data.end()) {
|
||||||
|
return entry->second;
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CfgFile& CfgFile::setPropertyValue(const SectionName& sectionName,
|
||||||
|
const PropertyName& name, const tstring_array& value) {
|
||||||
|
PropertyMap::iterator entry = data.find(sectionName);
|
||||||
|
if (entry != data.end()) {
|
||||||
|
entry->second[name] = value;
|
||||||
|
} else {
|
||||||
|
Properties props;
|
||||||
|
props[name] = value;
|
||||||
|
data[sectionName] = props;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
tstring expandMacros(const tstring& str, const CfgFile::Macros& macros) {
|
||||||
|
tstring reply = str;
|
||||||
|
CfgFile::Macros::const_iterator it = macros.begin();
|
||||||
|
const CfgFile::Macros::const_iterator end = macros.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
reply = tstrings::replace(reply, it->first, it->second);
|
||||||
|
}
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
CfgFile CfgFile::expandMacros(const Macros& macros) const {
|
||||||
|
CfgFile copyCfgFile = *this;
|
||||||
|
|
||||||
|
PropertyMap::iterator mapIt = copyCfgFile.data.begin();
|
||||||
|
const PropertyMap::iterator mapEnd = copyCfgFile.data.end();
|
||||||
|
for (; mapIt != mapEnd; ++mapIt) {
|
||||||
|
Properties::iterator propertyIt = mapIt->second.begin();
|
||||||
|
const Properties::iterator propertyEnd = mapIt->second.end();
|
||||||
|
for (; propertyIt != propertyEnd; ++propertyIt) {
|
||||||
|
tstring_array::iterator strIt = propertyIt->second.begin();
|
||||||
|
const tstring_array::iterator strEnd = propertyIt->second.end();
|
||||||
|
for (; strIt != strEnd; ++strIt) {
|
||||||
|
tstring newValue;
|
||||||
|
while ((newValue = ::expandMacros(*strIt, macros)) != *strIt) {
|
||||||
|
strIt->swap(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return copyCfgFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const CfgFile::SectionName* getSectionName(const tstring& str);
|
||||||
|
const CfgFile::PropertyName* getPropertyName(const tstring& str);
|
||||||
|
|
||||||
|
const CfgFile::SectionName UnknownSection = CfgFile::SectionName(_T(""));
|
||||||
|
|
||||||
|
|
||||||
|
class PurgeSection {
|
||||||
|
public:
|
||||||
|
PurgeSection(CfgFile::SectionName& sectionName,
|
||||||
|
CfgFile::Properties& sectionData,
|
||||||
|
CfgFile::PropertyMap& cfgFileData):
|
||||||
|
sectionName(sectionName), sectionData(sectionData),
|
||||||
|
cfgFileData(cfgFileData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator ()() {
|
||||||
|
if (sectionName != UnknownSection && !sectionData.empty()) {
|
||||||
|
std::swap(cfgFileData[sectionName], sectionData);
|
||||||
|
sectionName = UnknownSection;
|
||||||
|
sectionData.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CfgFile::SectionName& sectionName;
|
||||||
|
CfgFile::Properties& sectionData;
|
||||||
|
CfgFile::PropertyMap& cfgFileData;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddProperty {
|
||||||
|
public:
|
||||||
|
AddProperty(const CfgFile::SectionName& sectionName,
|
||||||
|
CfgFile::Properties& sectionData): sectionName(sectionName),
|
||||||
|
sectionData(sectionData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator ()(const tstring& name, const tstring& value) {
|
||||||
|
if (sectionName != UnknownSection) {
|
||||||
|
const CfgFile::PropertyName *known = getPropertyName(name);
|
||||||
|
if (known) {
|
||||||
|
sectionData[*known].push_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CfgFile::SectionName& sectionName;
|
||||||
|
CfgFile::Properties& sectionData;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namepsace
|
||||||
|
|
||||||
|
CfgFile CfgFile::load(const tstring& path) {
|
||||||
|
std::ifstream input(path.c_str());
|
||||||
|
if (!input.good()) {
|
||||||
|
JP_THROW(tstrings::any() << "Error opening \"" << path << "\" file: "
|
||||||
|
<< lastCRTError());
|
||||||
|
}
|
||||||
|
|
||||||
|
CfgFile cfgFile;
|
||||||
|
|
||||||
|
SectionName sectionName = UnknownSection;
|
||||||
|
Properties sectionData;
|
||||||
|
|
||||||
|
PurgeSection purgeSection(sectionName, sectionData, cfgFile.data);
|
||||||
|
|
||||||
|
AddProperty addProperty(sectionName, sectionData);
|
||||||
|
|
||||||
|
std::string utf8line;
|
||||||
|
int lineno = 0;
|
||||||
|
while (std::getline(input, utf8line)) {
|
||||||
|
++lineno;
|
||||||
|
const tstring line = tstrings::any(utf8line).tstr();
|
||||||
|
|
||||||
|
if (line.empty() || _T(';') == *line.begin()) {
|
||||||
|
// Empty line or comment, ignore.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_T('[') == *line.begin()) {
|
||||||
|
const size_t endIdx = line.find_last_of(_T(']'));
|
||||||
|
if (endIdx == tstring::npos) {
|
||||||
|
JP_THROW(tstrings::any() << "Error parsing [" << path
|
||||||
|
<< "] file at " << lineno << ": Missing ']' character");
|
||||||
|
}
|
||||||
|
|
||||||
|
purgeSection();
|
||||||
|
|
||||||
|
// Section begin.
|
||||||
|
const SectionName *knownName = getSectionName(line.substr(1, endIdx - 1));
|
||||||
|
if (knownName) {
|
||||||
|
sectionName = *knownName;
|
||||||
|
} else {
|
||||||
|
sectionName = UnknownSection;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sepIdx = 0;
|
||||||
|
do {
|
||||||
|
sepIdx = line.find_first_of(_T('='), sepIdx);
|
||||||
|
if (sepIdx == tstring::npos) {
|
||||||
|
addProperty(line, tstring());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sepIdx != 0 && line[sepIdx - 1] == '\\') {
|
||||||
|
sepIdx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
addProperty(line.substr(0, sepIdx), line.substr(sepIdx + 1));
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.eof()) {
|
||||||
|
// Failed to process file up to the end.
|
||||||
|
JP_THROW(tstrings::any() << "Failed to read \"" << path
|
||||||
|
<< "\" file up to the end: " << lastCRTError());
|
||||||
|
}
|
||||||
|
|
||||||
|
purgeSection();
|
||||||
|
|
||||||
|
return cfgFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring join(const tstring_array& values, const tstring::value_type delimiter) {
|
||||||
|
return tstrings::join(values.begin(), values.end(), tstring(1, delimiter));
|
||||||
|
}
|
||||||
|
|
||||||
|
tstring CfgFile::asString(Properties::const_reference property) {
|
||||||
|
return *property.second.rbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
tstring CfgFile::asPathList(Properties::const_reference property) {
|
||||||
|
return join(property.second, FileUtils::pathSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define JP_ALL_SECTIONS \
|
||||||
|
JP_SECTION(Application); \
|
||||||
|
JP_SECTION(JavaOptions); \
|
||||||
|
JP_SECTION(AppCDSJavaOptions); \
|
||||||
|
JP_SECTION(AppCDSGenerateCacheJavaOptions); \
|
||||||
|
JP_SECTION(ArgOptions);
|
||||||
|
|
||||||
|
namespace SectionName {
|
||||||
|
#define JP_SECTION(name) const CfgFile::SectionName name(_T(#name))
|
||||||
|
JP_ALL_SECTIONS
|
||||||
|
#undef JP_SECTION
|
||||||
|
} // namespace SectionName
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const CfgFile::SectionName* getSectionName(const tstring& str) {
|
||||||
|
#define JP_SECTION(name) while (str == _T(#name)) { return &SectionName::name; }
|
||||||
|
JP_ALL_SECTIONS
|
||||||
|
#undef JP_SECTION
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef JP_ALL_SECTIONS
|
||||||
|
|
||||||
|
|
||||||
|
#define JP_ALL_PROPERTIES \
|
||||||
|
JP_PROPERTY(version, "app.version"); \
|
||||||
|
JP_PROPERTY(mainjar, "app.mainjar"); \
|
||||||
|
JP_PROPERTY(mainmodule, "app.mainmodule"); \
|
||||||
|
JP_PROPERTY(mainclass, "app.mainclass"); \
|
||||||
|
JP_PROPERTY(classpath, "app.classpath"); \
|
||||||
|
JP_PROPERTY(modulepath, "app.modulepath"); \
|
||||||
|
JP_PROPERTY(runtime, "app.runtime"); \
|
||||||
|
JP_PROPERTY(splash, "app.splash"); \
|
||||||
|
JP_PROPERTY(memory, "app.memory"); \
|
||||||
|
JP_PROPERTY(arguments, "arguments"); \
|
||||||
|
JP_PROPERTY(javaOptions, "java-options"); \
|
||||||
|
|
||||||
|
namespace PropertyName {
|
||||||
|
#define JP_PROPERTY(varName, name) const CfgFile::PropertyName varName(_T(name))
|
||||||
|
JP_ALL_PROPERTIES
|
||||||
|
#undef JP_PROPERTY
|
||||||
|
} // namespace PropertyName
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const CfgFile::PropertyName* getPropertyName(const tstring& str) {
|
||||||
|
#define JP_PROPERTY(varName, name) while (str == _T(name)) { return &PropertyName::varName; }
|
||||||
|
JP_ALL_PROPERTIES
|
||||||
|
#undef JP_PROPERTY
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#undef JP_ALL_PROPERTIES
|
131
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.h
Normal file
131
src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.h
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CfgFile_h
|
||||||
|
#define CfgFile_h
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "tstrings.h"
|
||||||
|
|
||||||
|
|
||||||
|
class CfgFile {
|
||||||
|
public:
|
||||||
|
template <class Tag> class Id {
|
||||||
|
public:
|
||||||
|
Id(const tstring::const_pointer str) : str(str) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (const Id& other) const {
|
||||||
|
return tstring(str) == tstring(other.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator != (const Id& other) const {
|
||||||
|
return !operator == (other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator < (const Id& other) const {
|
||||||
|
return tstring(str) < tstring(other.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
tstring name() const {
|
||||||
|
return tstring(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tstring::const_pointer str;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PropertyNameTag {};
|
||||||
|
typedef Id<PropertyNameTag> PropertyName;
|
||||||
|
|
||||||
|
class SectionNameTag {};
|
||||||
|
typedef Id<SectionNameTag> SectionName;
|
||||||
|
|
||||||
|
typedef std::map<PropertyName, tstring_array> Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns properties of the given section.
|
||||||
|
*/
|
||||||
|
const Properties& getProperties(const SectionName& sectionName) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets new value of the given property in the given section.
|
||||||
|
*/
|
||||||
|
CfgFile& setPropertyValue(const SectionName& sectionName,
|
||||||
|
const PropertyName& name, const tstring& value) {
|
||||||
|
tstring_array ctnr;
|
||||||
|
ctnr.push_back(value);
|
||||||
|
return setPropertyValue(sectionName, name, ctnr);
|
||||||
|
}
|
||||||
|
|
||||||
|
CfgFile& setPropertyValue(const SectionName& sectionName,
|
||||||
|
const PropertyName& name, const tstring_array& value);
|
||||||
|
|
||||||
|
typedef std::map<tstring, tstring> Macros;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns copy of this instance with the given macros expanded.
|
||||||
|
*/
|
||||||
|
CfgFile expandMacros(const Macros& macros) const;
|
||||||
|
|
||||||
|
static CfgFile load(const tstring& path);
|
||||||
|
|
||||||
|
static tstring asString(Properties::const_reference property);
|
||||||
|
|
||||||
|
static tstring asPathList(Properties::const_reference property);
|
||||||
|
|
||||||
|
typedef std::map<SectionName, Properties> PropertyMap;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertyMap data;
|
||||||
|
Properties empty;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace SectionName {
|
||||||
|
extern const CfgFile::SectionName Application;
|
||||||
|
extern const CfgFile::SectionName JavaOptions;
|
||||||
|
extern const CfgFile::SectionName AppCDSJavaOptions;
|
||||||
|
extern const CfgFile::SectionName AppCDSGenerateCacheJavaOptions;
|
||||||
|
extern const CfgFile::SectionName ArgOptions;
|
||||||
|
} // namespace SectionName
|
||||||
|
|
||||||
|
namespace PropertyName {
|
||||||
|
extern const CfgFile::PropertyName version;
|
||||||
|
extern const CfgFile::PropertyName mainjar;
|
||||||
|
extern const CfgFile::PropertyName mainmodule;
|
||||||
|
extern const CfgFile::PropertyName mainclass;
|
||||||
|
extern const CfgFile::PropertyName classpath;
|
||||||
|
extern const CfgFile::PropertyName modulepath;
|
||||||
|
extern const CfgFile::PropertyName runtime;
|
||||||
|
extern const CfgFile::PropertyName splash;
|
||||||
|
extern const CfgFile::PropertyName memory;
|
||||||
|
extern const CfgFile::PropertyName arguments;
|
||||||
|
extern const CfgFile::PropertyName javaOptions;
|
||||||
|
} // namespace AppPropertyName
|
||||||
|
|
||||||
|
#endif // CfgFile_h
|
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <jni.h>
|
||||||
|
#include "JvmLauncher.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Dll.h"
|
||||||
|
#include "CfgFile.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "Toolbox.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
|
Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) {
|
||||||
|
const CfgFile::Properties& appOptions = cfgFile.getProperties(
|
||||||
|
SectionName::Application);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const CfgFile::Properties::const_iterator modulepath = appOptions.find(
|
||||||
|
PropertyName::modulepath);
|
||||||
|
if (modulepath != appOptions.end()) {
|
||||||
|
tstring_array::const_iterator it = modulepath->second.begin();
|
||||||
|
const tstring_array::const_iterator end = modulepath->second.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
addArgument(_T("--module-path"));
|
||||||
|
addArgument(*it);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const CfgFile::Properties::const_iterator classpath = appOptions.find(
|
||||||
|
PropertyName::classpath);
|
||||||
|
if (classpath != appOptions.end()) {
|
||||||
|
addArgument(_T("-classpath"));
|
||||||
|
addArgument(CfgFile::asPathList(*classpath));
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const CfgFile::Properties::const_iterator splash = appOptions.find(
|
||||||
|
PropertyName::splash);
|
||||||
|
if (splash != appOptions.end()) {
|
||||||
|
const tstring splashPath = CfgFile::asString(*splash);
|
||||||
|
if (FileUtils::isFileExists(splashPath)) {
|
||||||
|
addArgument(_T("-splash"));
|
||||||
|
addArgument(splashPath);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(tstrings::any()
|
||||||
|
<< "Splash property ignored. File \""
|
||||||
|
<< splashPath << "\" not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const CfgFile::Properties& section = cfgFile.getProperties(
|
||||||
|
SectionName::JavaOptions);
|
||||||
|
const CfgFile::Properties::const_iterator javaOptions = section.find(
|
||||||
|
PropertyName::javaOptions);
|
||||||
|
if (javaOptions != section.end()) {
|
||||||
|
tstring_array::const_iterator it = javaOptions->second.begin();
|
||||||
|
const tstring_array::const_iterator end = javaOptions->second.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
addArgument(*it);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
// No validation of data in config file related to how Java app should be
|
||||||
|
// launched intentionally.
|
||||||
|
// Just read what is in config file and put on jvm's command line as is.
|
||||||
|
|
||||||
|
do { // Run modular app
|
||||||
|
const CfgFile::Properties::const_iterator mainmodule = appOptions.find(
|
||||||
|
PropertyName::mainmodule);
|
||||||
|
if (mainmodule != appOptions.end()) {
|
||||||
|
addArgument(_T("-m"));
|
||||||
|
addArgument(CfgFile::asString(*mainmodule));
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
do { // Run main class
|
||||||
|
const CfgFile::Properties::const_iterator mainclass = appOptions.find(
|
||||||
|
PropertyName::mainclass);
|
||||||
|
if (mainclass != appOptions.end()) {
|
||||||
|
addArgument(CfgFile::asString(*mainclass));
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
do { // Run jar
|
||||||
|
const CfgFile::Properties::const_iterator mainjar = appOptions.find(
|
||||||
|
PropertyName::mainjar);
|
||||||
|
if (mainjar != appOptions.end()) {
|
||||||
|
addArgument(_T("-jar"));
|
||||||
|
addArgument(CfgFile::asString(*mainjar));
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const CfgFile::Properties& section = cfgFile.getProperties(
|
||||||
|
SectionName::ArgOptions);
|
||||||
|
const CfgFile::Properties::const_iterator arguments = section.find(
|
||||||
|
PropertyName::arguments);
|
||||||
|
if (arguments != section.end()) {
|
||||||
|
tstring_array::const_iterator it = arguments->second.begin();
|
||||||
|
const tstring_array::const_iterator end = arguments->second.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
addArgument(*it);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void convertArgs(const std::vector<std::string>& args, std::vector<char*>& argv) {
|
||||||
|
argv.reserve(args.size() + 1);
|
||||||
|
argv.resize(0);
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator it = args.begin();
|
||||||
|
const std::vector<std::string>::const_iterator end = args.end();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
argv.push_back(const_cast<char*>(it->c_str()));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add treminal '0'.
|
||||||
|
argv.push_back(0);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void Jvm::launch() {
|
||||||
|
typedef int (JNICALL *LaunchFuncType)(int argc, char ** argv,
|
||||||
|
int jargc, const char** jargv,
|
||||||
|
int appclassc, const char** appclassv,
|
||||||
|
const char* fullversion,
|
||||||
|
const char* dotversion,
|
||||||
|
const char* pname,
|
||||||
|
const char* lname,
|
||||||
|
jboolean javaargs,
|
||||||
|
jboolean cpwildcard,
|
||||||
|
jboolean javaw,
|
||||||
|
jint ergo);
|
||||||
|
|
||||||
|
std::vector<char*> argv;
|
||||||
|
convertArgs(args, argv);
|
||||||
|
|
||||||
|
// Don't count terminal '0'.
|
||||||
|
const int argc = (int)argv.size() - 1;
|
||||||
|
|
||||||
|
LOG_TRACE(tstrings::any() << "JVM library: \"" << jvmPath << "\"");
|
||||||
|
|
||||||
|
DllFunction<LaunchFuncType> func(Dll(jvmPath), "JLI_Launch");
|
||||||
|
int exitStatus = func(argc, argv.data(),
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"java",
|
||||||
|
"java",
|
||||||
|
JNI_FALSE,
|
||||||
|
JNI_FALSE,
|
||||||
|
JNI_FALSE,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (exitStatus != 0) {
|
||||||
|
JP_THROW("Failed to launch JVM");
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,37 +23,34 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILEATTRIBUTE_H
|
|
||||||
#define FILEATTRIBUTE_H
|
|
||||||
|
|
||||||
enum FileAttribute {
|
#ifndef JvmLauncher_h
|
||||||
faBlockSpecial,
|
#define JvmLauncher_h
|
||||||
faCharacterSpecial,
|
|
||||||
faFIFOSpecial,
|
|
||||||
faNormal,
|
|
||||||
faDirectory,
|
|
||||||
faSymbolicLink,
|
|
||||||
faSocket,
|
|
||||||
|
|
||||||
// Owner
|
#include "tstrings.h"
|
||||||
faReadOnly,
|
|
||||||
faWriteOnly,
|
|
||||||
faReadWrite,
|
|
||||||
faExecute,
|
|
||||||
|
|
||||||
// Group
|
class CfgFile;
|
||||||
faGroupReadOnly,
|
|
||||||
faGroupWriteOnly,
|
|
||||||
faGroupReadWrite,
|
|
||||||
faGroupExecute,
|
|
||||||
|
|
||||||
// Others
|
|
||||||
faOthersReadOnly,
|
|
||||||
faOthersWriteOnly,
|
|
||||||
faOthersReadWrite,
|
|
||||||
faOthersExecute,
|
|
||||||
|
|
||||||
faHidden
|
class Jvm {
|
||||||
|
public:
|
||||||
|
Jvm& initFromConfigFile(const CfgFile& cfgFile);
|
||||||
|
|
||||||
|
Jvm& addArgument(const tstring& value) {
|
||||||
|
args.push_back(tstrings::any(value).str());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Jvm& setPath(const tstring& v) {
|
||||||
|
jvmPath = v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void launch();
|
||||||
|
|
||||||
|
private:
|
||||||
|
tstring jvmPath;
|
||||||
|
std::vector<std::string> args;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILEATTRIBUTE_H
|
#endif // JvmLauncher_h
|
170
src/jdk.incubator.jpackage/share/native/common/Dll.h
Normal file
170
src/jdk.incubator.jpackage/share/native/common/Dll.h
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DLL_H_INCLUDED_
|
||||||
|
#define __DLL_H_INCLUDED_
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
typedef void* HMODULE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "kludge_c++11.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "tstrings.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper classes to dynamically load DLLs and call the libraries functions.
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Library loader.
|
||||||
|
* Usage:
|
||||||
|
* - load a library specified by full path:
|
||||||
|
* DLL deployLib(FileUtils::combinePath(javaHome, _T("bin\\deploy.dll"));
|
||||||
|
*
|
||||||
|
* Note: library should be specified by full path (due security reasons)
|
||||||
|
*
|
||||||
|
* - load system library (DLLs from Windows/System32 (SysWow64) directory):
|
||||||
|
* DLL kernel32Lib("kernel32", Dll::System());
|
||||||
|
*/
|
||||||
|
class Dll {
|
||||||
|
public:
|
||||||
|
struct System {};
|
||||||
|
|
||||||
|
explicit Dll(const tstrings::any &libPath);
|
||||||
|
explicit Dll(const tstrings::any &libName, const System &tag);
|
||||||
|
|
||||||
|
Dll(const Dll& other);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void getFunction(const tstrings::any &name, T& addr) const {
|
||||||
|
addr = reinterpret_cast<T>(getFunction(name.str(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns false & sets addr to NULL if the function not found
|
||||||
|
template <class T>
|
||||||
|
bool getFunction(const tstrings::any &name, T& addr, const std::nothrow_t &) const {
|
||||||
|
addr = reinterpret_cast<T>(getFunction(name.str(), false));
|
||||||
|
return addr != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tstring& path() const {
|
||||||
|
return thePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE getHandle() const {
|
||||||
|
return handle.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeLibrary(HMODULE h);
|
||||||
|
|
||||||
|
struct LibraryReleaser {
|
||||||
|
typedef HMODULE pointer;
|
||||||
|
|
||||||
|
void operator()(HMODULE h) {
|
||||||
|
freeLibrary(h);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::unique_ptr<HMODULE, LibraryReleaser> Handle;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* getFunction(const std::string &name, bool throwIfNotFound) const;
|
||||||
|
|
||||||
|
tstring thePath;
|
||||||
|
Handle handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DllFunction template class helps to check is a library function available and call it.
|
||||||
|
* Usage example:
|
||||||
|
* // RegDeleteKeyExW function (from advapi32.dll) is available on Vista+ or on WinXP 64bit
|
||||||
|
* // so to avoid dependency on the OS version we have to check if it's available at runtime
|
||||||
|
*
|
||||||
|
* // the function definition
|
||||||
|
* typedef LONG (WINAPI *RegDeleteKeyExWFunc)(HKEY hKey, const wchar_t* lpSubKey, REGSAM samDesired, DWORD Reserved);
|
||||||
|
*
|
||||||
|
* DllFunction<RegDeleteKeyExWFunc> _RegDeleteKeyExW(Dll("advapi32", Dll::System()), "RegDeleteKeyExW");
|
||||||
|
* if (_RegDeleteKeyExW.available()) {
|
||||||
|
* // the function is available, call it
|
||||||
|
* LONG result = _RegDeleteKeyExW(hKey, subkeyName, samDesired, 0);
|
||||||
|
* } else {
|
||||||
|
* // the function is not available, handle this
|
||||||
|
* throw std::exception("RegDeleteKeyExW function is not available");
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // or we can just try to call the function.
|
||||||
|
* // if the function is not available, exception with the corresponding description is thrown
|
||||||
|
* DllFunction<RegDeleteKeyExWFunc> _RegDeleteKeyExW(Dll("advapi32", Dll::System()), "RegDeleteKeyExW");
|
||||||
|
* LONG result = _RegDeleteKeyExW(hKey, subkeyName, samDesired, 0);
|
||||||
|
*/
|
||||||
|
template<class funcType>
|
||||||
|
class DllFunction {
|
||||||
|
public:
|
||||||
|
DllFunction(const Dll& library, const tstrings::any &funcName)
|
||||||
|
: lib(library), theName(funcName.str()) {
|
||||||
|
lib.getFunction(funcName, funcPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DllFunction(const std::nothrow_t&, const Dll& library,
|
||||||
|
const tstrings::any &funcName)
|
||||||
|
: lib(library), theName(funcName.str()) {
|
||||||
|
lib.getFunction(funcName, funcPtr, std::nothrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool available() const {
|
||||||
|
return funcPtr != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name() const {
|
||||||
|
return theName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tstring& libPath() const {
|
||||||
|
return lib.path();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator funcType() const {
|
||||||
|
if (!available()) {
|
||||||
|
JP_THROW(tstrings::any() << theName
|
||||||
|
<< "() function is not available in "
|
||||||
|
<< lib.path());
|
||||||
|
}
|
||||||
|
return funcPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Dll lib;
|
||||||
|
funcType funcPtr;
|
||||||
|
std::string theName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __DLL_H_INCLUDED_
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <string.h>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
#include "ErrorHandling.h"
|
#include "ErrorHandling.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
@ -47,7 +49,7 @@ void reportError(const SourceCodePos& pos, const tstring& msg) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void reportError(const SourceCodePos& pos, const std::exception& e) {
|
void reportError(const SourceCodePos& pos, const std::runtime_error& e) {
|
||||||
reportError(pos, (tstrings::any() << "Exception with message \'"
|
reportError(pos, (tstrings::any() << "Exception with message \'"
|
||||||
<< e.what() << "\' caught").tstr());
|
<< e.what() << "\' caught").tstr());
|
||||||
}
|
}
|
||||||
@ -58,7 +60,7 @@ void reportUnknownError(const SourceCodePos& pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string makeMessage(const std::exception& e, const SourceCodePos& pos) {
|
std::string makeMessage(const std::runtime_error& e, const SourceCodePos& pos) {
|
||||||
std::ostringstream printer;
|
std::ostringstream printer;
|
||||||
printer << getFilename(pos) << "(" << pos.lno << ") at "
|
printer << getFilename(pos) << "(" << pos.lno << ") at "
|
||||||
<< pos.func << "(): "
|
<< pos.func << "(): "
|
||||||
@ -139,3 +141,16 @@ std::string joinErrorMessages(const std::string& a, const std::string& b) {
|
|||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string lastCRTError() {
|
||||||
|
#ifndef _WIN32
|
||||||
|
return strerror(errno);
|
||||||
|
#else
|
||||||
|
TCHAR buffer[2048];
|
||||||
|
if (0 == _tcserror_s(buffer, errno)) {
|
||||||
|
return (tstrings::any() << buffer).str();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -50,18 +50,26 @@
|
|||||||
|
|
||||||
|
|
||||||
// Logs std::exception caught at 'pos'.
|
// Logs std::exception caught at 'pos'.
|
||||||
void reportError(const SourceCodePos& pos, const std::exception& e);
|
void reportError(const SourceCodePos& pos, const std::runtime_error& e);
|
||||||
// Logs unknown exception caught at 'pos'.
|
// Logs unknown exception caught at 'pos'.
|
||||||
// Assumed to be called from catch (...) {}
|
// Assumed to be called from catch (...) {}
|
||||||
void reportUnknownError(const SourceCodePos& pos);
|
void reportUnknownError(const SourceCodePos& pos);
|
||||||
|
|
||||||
std::string makeMessage(const std::exception& e, const SourceCodePos& pos);
|
std::string makeMessage(const std::runtime_error& e, const SourceCodePos& pos);
|
||||||
|
|
||||||
std::string joinErrorMessages(const std::string& a, const std::string& b);
|
std::string joinErrorMessages(const std::string& a, const std::string& b);
|
||||||
|
|
||||||
|
std::string lastCRTError();
|
||||||
|
|
||||||
|
|
||||||
|
class JpErrorBase {
|
||||||
|
public:
|
||||||
|
virtual const char* rawMessage() const throw() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class Base>
|
template <class Base>
|
||||||
class JpError: public Base {
|
class JpError: public JpErrorBase, public Base {
|
||||||
public:
|
public:
|
||||||
JpError(const Base& e, const SourceCodePos& pos):
|
JpError(const Base& e, const SourceCodePos& pos):
|
||||||
Base(e), msg(::makeMessage(e, pos)) {
|
Base(e), msg(::makeMessage(e, pos)) {
|
||||||
@ -74,10 +82,15 @@ public:
|
|||||||
const char* what() const throw() {
|
const char* what() const throw() {
|
||||||
return msg.c_str();
|
return msg.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// override JpErrorBase
|
||||||
|
const char* rawMessage() const throw() {
|
||||||
|
return Base::what();
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
// Assert Base is derived from std::exception
|
// Assert Base is derived from std::runtime_error
|
||||||
enum { isDerivedFromStdException =
|
enum { isDerivedFromStdException =
|
||||||
sizeof(static_cast<std::exception*>((Base*)0)) };
|
sizeof(static_cast<std::runtime_error*>((Base*)0)) };
|
||||||
|
|
||||||
std::string msg;
|
std::string msg;
|
||||||
};
|
};
|
||||||
@ -129,7 +142,7 @@ inline JpError<std::runtime_error> makeException(
|
|||||||
do {} while(0)
|
do {} while(0)
|
||||||
|
|
||||||
#define JP_CATCH_STD_EXCEPTION \
|
#define JP_CATCH_STD_EXCEPTION \
|
||||||
catch (const std::exception& e) \
|
catch (const std::runtime_error& e) \
|
||||||
{ \
|
{ \
|
||||||
JP_HANDLE_ERROR(e); \
|
JP_HANDLE_ERROR(e); \
|
||||||
}
|
}
|
143
src/jdk.incubator.jpackage/share/native/common/FileUtils.cpp
Normal file
143
src/jdk.incubator.jpackage/share/native/common/FileUtils.cpp
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "FileUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace FileUtils {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
const tstring::value_type pathSeparator = _T(';');
|
||||||
|
#else
|
||||||
|
const tstring::value_type pathSeparator = _T(':');
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
#ifdef _WIN32
|
||||||
|
const tstring::value_type dirSeparator = _T('\\');
|
||||||
|
const tstring::value_type alianDirSeparator = _T('/');
|
||||||
|
#else
|
||||||
|
const tstring::value_type dirSeparator = _T('/');
|
||||||
|
const tstring::value_type alianDirSeparator = _T('\\');
|
||||||
|
#endif
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
bool isDirSeparator(const tstring::value_type c) {
|
||||||
|
return (c == dirSeparator || c == alianDirSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring dirname(const tstring &path) {
|
||||||
|
tstring::size_type pos = path.find_last_of(_T("\\/"));
|
||||||
|
if (pos != tstring::npos) {
|
||||||
|
pos = path.find_last_not_of(_T("\\/"), pos); // skip trailing slashes
|
||||||
|
}
|
||||||
|
return pos == tstring::npos ? tstring() : path.substr(0, pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring basename(const tstring &path) {
|
||||||
|
const tstring::size_type pos = path.find_last_of(_T("\\/"));
|
||||||
|
if (pos == tstring::npos) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return path.substr(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring suffix(const tstring &path) {
|
||||||
|
const tstring::size_type pos = path.rfind(_T('.'));
|
||||||
|
if (pos == tstring::npos) {
|
||||||
|
return tstring();
|
||||||
|
}
|
||||||
|
const tstring::size_type dirSepPos = path.find_first_of(_T("\\/"),
|
||||||
|
pos + 1);
|
||||||
|
if (dirSepPos != tstring::npos) {
|
||||||
|
return tstring();
|
||||||
|
}
|
||||||
|
// test for '/..' and '..' cases
|
||||||
|
if (pos != 0 && path[pos - 1] == _T('.')
|
||||||
|
&& (pos == 1 || isDirSeparator(path[pos - 2]))) {
|
||||||
|
return tstring();
|
||||||
|
}
|
||||||
|
return path.substr(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring combinePath(const tstring& parent, const tstring& child) {
|
||||||
|
if (parent.empty()) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
if (child.empty()) {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
tstring parentWOSlash = removeTrailingSlash(parent);
|
||||||
|
// also handle the case when child contains starting slash
|
||||||
|
bool childHasSlash = isDirSeparator(*child.begin());
|
||||||
|
tstring childWOSlash = childHasSlash ? child.substr(1) : child;
|
||||||
|
|
||||||
|
return parentWOSlash.append(1, dirSeparator).append(childWOSlash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring removeTrailingSlash(const tstring& path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
tstring::const_reverse_iterator it = path.rbegin();
|
||||||
|
tstring::const_reverse_iterator end = path.rend();
|
||||||
|
|
||||||
|
while (it != end && isDirSeparator(*it)) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return path.substr(0, end - it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring normalizePath(tstring v) {
|
||||||
|
std::replace(v.begin(), v.end(), alianDirSeparator, dirSeparator);
|
||||||
|
#ifdef _WIN32
|
||||||
|
return tstrings::toLower(v);
|
||||||
|
#else
|
||||||
|
return v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring replaceSuffix(const tstring& path, const tstring& newSuffix) {
|
||||||
|
const tstring oldSuffix = suffix(path);
|
||||||
|
if (oldSuffix.empty()) {
|
||||||
|
return tstring().append(path).append(newSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.substr(0, path.size() - oldSuffix.size()).append(newSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileUtils
|
124
src/jdk.incubator.jpackage/share/native/common/FileUtils.h
Normal file
124
src/jdk.incubator.jpackage/share/native/common/FileUtils.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FILEUTILS_H
|
||||||
|
#define FILEUTILS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include "SysInfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace FileUtils {
|
||||||
|
extern const tstring::value_type pathSeparator;
|
||||||
|
|
||||||
|
// Returns 'true' if the given character is a path separator.
|
||||||
|
bool isDirSeparator(const tstring::value_type c);
|
||||||
|
|
||||||
|
// returns directory part of the path.
|
||||||
|
// returns empty string if the path contains only filename.
|
||||||
|
// if the path ends with slash/backslash,
|
||||||
|
// returns removeTrailingSlashes(path).
|
||||||
|
tstring dirname(const tstring &path);
|
||||||
|
|
||||||
|
// returns basename part of the path
|
||||||
|
// if the path ends with slash/backslash, returns empty string.
|
||||||
|
tstring basename(const tstring &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates forward slashes to back slashes and returns lower case version
|
||||||
|
* of the given string.
|
||||||
|
*/
|
||||||
|
tstring normalizePath(tstring v);
|
||||||
|
|
||||||
|
// Returns suffix of the path. If the given path has a suffix the first
|
||||||
|
// character of the return value is '.'.
|
||||||
|
// Otherwise return value if empty string.
|
||||||
|
tstring suffix(const tstring &path);
|
||||||
|
|
||||||
|
// combines two strings into a path
|
||||||
|
tstring combinePath(const tstring& parent, const tstring& child);
|
||||||
|
|
||||||
|
// removes trailing slashes and backslashes in the path if any
|
||||||
|
tstring removeTrailingSlash(const tstring& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace file suffix, example replaceSuffix("file/path.txt", ".csv")
|
||||||
|
* @param path file path to replace suffix
|
||||||
|
* @param suffix new suffix for path
|
||||||
|
* @return return file path with new suffix
|
||||||
|
*/
|
||||||
|
tstring replaceSuffix(const tstring& path, const tstring& suffix=tstring());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns absolute path of the given path.
|
||||||
|
* If the given string is empty, returns absolute path to the current
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
|
tstring toAbsolutePath(const tstring& path);
|
||||||
|
|
||||||
|
// Helper to construct path from multiple components.
|
||||||
|
//
|
||||||
|
// Sample usage:
|
||||||
|
// Construct "c:\Program Files\Java" string from three components
|
||||||
|
//
|
||||||
|
// tstring path = FileUtils::mkpath() << _T("c:")
|
||||||
|
// << _T("Program Files")
|
||||||
|
// << _T("Java");
|
||||||
|
//
|
||||||
|
class mkpath {
|
||||||
|
public:
|
||||||
|
operator const tstring& () const {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
mkpath& operator << (const tstring& p) {
|
||||||
|
path = combinePath(path, p);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mimic std::string
|
||||||
|
const tstring::value_type* c_str() const {
|
||||||
|
return path.c_str();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
tstring path;
|
||||||
|
};
|
||||||
|
|
||||||
|
// checks if the file or directory exists
|
||||||
|
bool isFileExists(const tstring &filePath);
|
||||||
|
|
||||||
|
// checks is the specified file is a directory
|
||||||
|
// returns false if the path does not exist
|
||||||
|
bool isDirectory(const tstring &filePath);
|
||||||
|
|
||||||
|
// checks if the specified directory is not empty
|
||||||
|
// returns true if the path is an existing directory and
|
||||||
|
// it contains at least one file other than "." or "..".
|
||||||
|
bool isDirectoryNotEmpty(const tstring &dirPath);
|
||||||
|
|
||||||
|
} // FileUtils
|
||||||
|
|
||||||
|
#endif // FILEUTILS_H
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "SysInfo.h"
|
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
|
|
||||||
|
|
||||||
@ -46,12 +45,10 @@ namespace {
|
|||||||
// by default log everything
|
// by default log everything
|
||||||
const Logger::LogLevel defaultLogLevel = Logger::LOG_TRACE;
|
const Logger::LogLevel defaultLogLevel = Logger::LOG_TRACE;
|
||||||
|
|
||||||
char defaultLogAppenderMemory[sizeof(StderrLogAppender)] = {};
|
char defaultLogAppenderMemory[sizeof(StreamLogAppender)] = {};
|
||||||
|
|
||||||
char defaultLoggerMemory[sizeof(Logger)] = {};
|
char defaultLoggerMemory[sizeof(Logger)] = {};
|
||||||
|
|
||||||
NopLogAppender nopLogApender;
|
|
||||||
|
|
||||||
LPCTSTR getLogLevelStr(Logger::LogLevel level) {
|
LPCTSTR getLogLevelStr(Logger::LogLevel level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case Logger::LOG_TRACE:
|
case Logger::LOG_TRACE:
|
||||||
@ -66,26 +63,12 @@ namespace {
|
|||||||
return _T("UNKNOWN");
|
return _T("UNKNOWN");
|
||||||
}
|
}
|
||||||
|
|
||||||
tstring retrieveModuleName() {
|
|
||||||
try {
|
|
||||||
return FileUtils::basename(SysInfo::getCurrentModulePath());
|
|
||||||
} catch (const std::exception&) {
|
|
||||||
return _T("Unknown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR moduleName[MAX_PATH] = { 'U', 'n', 'k', 'o', 'w', 'n', TCHAR(0) };
|
|
||||||
|
|
||||||
const LPCTSTR format = _T("[%04u/%02u/%02u %02u:%02u:%02u.%03u, %s (PID: %u, TID: %u), %s:%u (%s)]\n\t%s: %s\n");
|
|
||||||
|
|
||||||
enum State { NotInitialized, Initializing, Initialized };
|
enum State { NotInitialized, Initializing, Initialized };
|
||||||
State state = NotInitialized;
|
State state = NotInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LogEvent::LogEvent() {
|
LogEvent::LogEvent() {
|
||||||
memset(this, 0, sizeof(*this));
|
|
||||||
moduleName = tstring();
|
|
||||||
logLevel = tstring();
|
logLevel = tstring();
|
||||||
fileName = tstring();
|
fileName = tstring();
|
||||||
funcName = tstring();
|
funcName = tstring();
|
||||||
@ -93,10 +76,6 @@ LogEvent::LogEvent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StderrLogAppender::StderrLogAppender() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
Logger& Logger::defaultLogger() {
|
Logger& Logger::defaultLogger() {
|
||||||
Logger* reply = reinterpret_cast<Logger*>(defaultLoggerMemory);
|
Logger* reply = reinterpret_cast<Logger*>(defaultLoggerMemory);
|
||||||
@ -106,27 +85,17 @@ Logger& Logger::defaultLogger() {
|
|||||||
// object. OS will do resources clean up anyways when application
|
// object. OS will do resources clean up anyways when application
|
||||||
// terminates and the default log appender should live as long as
|
// terminates and the default log appender should live as long as
|
||||||
// application lives.
|
// application lives.
|
||||||
reply->appender = new (defaultLogAppenderMemory) StderrLogAppender();
|
reply->appender = new (defaultLogAppenderMemory) StreamLogAppender(
|
||||||
|
std::cout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Initializing == state) {
|
if (Initializing == state) {
|
||||||
// Recursive call to Logger::defaultLogger.
|
// Recursive call to Logger::defaultLogger.
|
||||||
moduleName[0] = TCHAR(0);
|
initializingLogging();
|
||||||
|
|
||||||
} else if (NotInitialized == state) {
|
} else if (NotInitialized == state) {
|
||||||
state = Initializing;
|
state = Initializing;
|
||||||
|
initializeLogging();
|
||||||
tstring mname = retrieveModuleName();
|
|
||||||
mname.resize(_countof(moduleName) - 1);
|
|
||||||
std::memcpy(moduleName, mname.c_str(), mname.size());
|
|
||||||
moduleName[mname.size()] = TCHAR(0);
|
|
||||||
|
|
||||||
// if JPACKAGE_DEBUG environment variable is NOT set to "true" disable
|
|
||||||
// logging.
|
|
||||||
if (SysInfo::getEnvVariable(std::nothrow,
|
|
||||||
L"JPACKAGE_DEBUG") != L"true") {
|
|
||||||
reply->appender = &nopLogApender;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = Initialized;
|
state = Initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,14 +121,8 @@ bool Logger::isLoggable(LogLevel logLevel) const {
|
|||||||
void Logger::log(LogLevel logLevel, LPCTSTR fileName, int lineNum,
|
void Logger::log(LogLevel logLevel, LPCTSTR fileName, int lineNum,
|
||||||
LPCTSTR funcName, const tstring& message) const {
|
LPCTSTR funcName, const tstring& message) const {
|
||||||
LogEvent logEvent;
|
LogEvent logEvent;
|
||||||
|
LogEvent::init(logEvent);
|
||||||
|
|
||||||
// [YYYY/MM/DD HH:MM:SS.ms, <module> (PID: processID, TID: threadID),
|
|
||||||
// fileName:lineNum (funcName)] <tab>LEVEL: message
|
|
||||||
GetLocalTime(&logEvent.ts);
|
|
||||||
|
|
||||||
logEvent.pid = GetCurrentProcessId();
|
|
||||||
logEvent.tid = GetCurrentThreadId();
|
|
||||||
logEvent.moduleName = moduleName;
|
|
||||||
logEvent.fileName = FileUtils::basename(fileName);
|
logEvent.fileName = FileUtils::basename(fileName);
|
||||||
logEvent.funcName = funcName;
|
logEvent.funcName = funcName;
|
||||||
logEvent.logLevel = getLogLevelStr(logLevel);
|
logEvent.logLevel = getLogLevelStr(logLevel);
|
||||||
@ -170,18 +133,20 @@ void Logger::log(LogLevel logLevel, LPCTSTR fileName, int lineNum,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StderrLogAppender::append(const LogEvent& v)
|
void StreamLogAppender::append(const LogEvent& v) {
|
||||||
{
|
tstring platformLogStr;
|
||||||
const tstring out = tstrings::unsafe_format(format,
|
LogEvent::appendFormatted(v, platformLogStr);
|
||||||
unsigned(v.ts.wYear), unsigned(v.ts.wMonth), unsigned(v.ts.wDay),
|
|
||||||
unsigned(v.ts.wHour), unsigned(v.ts.wMinute), unsigned(v.ts.wSecond),
|
|
||||||
unsigned(v.ts.wMilliseconds),
|
|
||||||
v.moduleName.c_str(), v.pid, v.tid,
|
|
||||||
v.fileName.c_str(), v.lineNum, v.funcName.c_str(),
|
|
||||||
v.logLevel.c_str(),
|
|
||||||
v.message.c_str());
|
|
||||||
|
|
||||||
std::cerr << tstrings::toUtf8(out);
|
tostringstream printer;
|
||||||
|
printer << _T('[') << platformLogStr
|
||||||
|
<< v.fileName << _T(':') << v.lineNum
|
||||||
|
<< _T(" (") << v.funcName << _T(')')
|
||||||
|
<< _T(']')
|
||||||
|
<< _T('\n') << _T('\t')
|
||||||
|
<< v.logLevel << _T(": ")
|
||||||
|
<< v.message;
|
||||||
|
|
||||||
|
*consumer << tstrings::toUtf8(printer.str()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,7 +26,7 @@
|
|||||||
#ifndef __LOG_H_INCLUDED_
|
#ifndef __LOG_H_INCLUDED_
|
||||||
#define __LOG_H_INCLUDED_
|
#define __LOG_H_INCLUDED_
|
||||||
|
|
||||||
#include <windows.h>
|
#include "PlatformLogEvent.h"
|
||||||
#include "tstrings.h"
|
#include "tstrings.h"
|
||||||
|
|
||||||
|
|
||||||
@ -45,11 +45,10 @@
|
|||||||
* (usually value of the TMP env. var)
|
* (usually value of the TMP env. var)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct LogEvent {
|
class Logger;
|
||||||
SYSTEMTIME ts;
|
class StreamLogAppender;
|
||||||
long tid;
|
|
||||||
long pid;
|
struct LogEvent: public PlatformLogEvent {
|
||||||
tstring moduleName;
|
|
||||||
tstring logLevel;
|
tstring logLevel;
|
||||||
tstring fileName;
|
tstring fileName;
|
||||||
int lineNum;
|
int lineNum;
|
||||||
@ -57,6 +56,14 @@ struct LogEvent {
|
|||||||
tstring message;
|
tstring message;
|
||||||
|
|
||||||
LogEvent();
|
LogEvent();
|
||||||
|
|
||||||
|
friend class Logger;
|
||||||
|
friend class StreamLogAppender;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void init(PlatformLogEvent& logEvent);
|
||||||
|
static void appendFormatted(const PlatformLogEvent& logEvent,
|
||||||
|
tstring& buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -96,13 +103,18 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes log events to stderr.
|
* Writes log events to the given std::ostream.
|
||||||
|
* Supposed to be used with std::cout or std::cerr
|
||||||
*/
|
*/
|
||||||
class StderrLogAppender: public LogAppender {
|
class StreamLogAppender: public LogAppender {
|
||||||
public:
|
public:
|
||||||
explicit StderrLogAppender();
|
explicit StreamLogAppender(std::ostream& consumer) : consumer(&consumer) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual void append(const LogEvent& v);
|
virtual void append(const LogEvent& v);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ostream* consumer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -154,19 +166,42 @@ public:
|
|||||||
private:
|
private:
|
||||||
const Logger &log;
|
const Logger &log;
|
||||||
const LogLevel level;
|
const LogLevel level;
|
||||||
const bool needLog;
|
|
||||||
const tstring file;
|
const tstring file;
|
||||||
const int line;
|
const int line;
|
||||||
const tstring func;
|
const tstring func;
|
||||||
const tstring scope;
|
const tstring scope;
|
||||||
|
const bool needLog;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void initializingLogging();
|
||||||
|
static void initializeLogging();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LogLevel level;
|
LogLevel level;
|
||||||
LogAppender* appender;
|
LogAppender* appender;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class WithExtraLogAppender {
|
||||||
|
public:
|
||||||
|
WithExtraLogAppender(LogAppender& logAppender):
|
||||||
|
oldLogAppender(Logger::defaultLogger().getAppender()),
|
||||||
|
newLogAppender(&Logger::defaultLogger().getAppender(),
|
||||||
|
&logAppender) {
|
||||||
|
Logger::defaultLogger().setAppender(newLogAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~WithExtraLogAppender() {
|
||||||
|
Logger::defaultLogger().setAppender(oldLogAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LogAppender& oldLogAppender;
|
||||||
|
TeeLogAppender newLogAppender;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// base logging macro
|
// base logging macro
|
||||||
#define LOGGER_LOG(logger, logLevel, message) \
|
#define LOGGER_LOG(logger, logLevel, message) \
|
||||||
do { \
|
do { \
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -47,7 +47,11 @@ struct SourceCodePos
|
|||||||
|
|
||||||
// Initializes SourceCodePos instance with the
|
// Initializes SourceCodePos instance with the
|
||||||
// information from the point of calling.
|
// information from the point of calling.
|
||||||
|
#ifdef THIS_FILE
|
||||||
|
#define JP_SOURCE_CODE_POS SourceCodePos(THIS_FILE, __FUNCTION__, __LINE__)
|
||||||
|
#else
|
||||||
#define JP_SOURCE_CODE_POS SourceCodePos(__FILE__, __FUNCTION__, __LINE__)
|
#define JP_SOURCE_CODE_POS SourceCodePos(__FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // #ifndef SourceCodePos_h
|
#endif // #ifndef SourceCodePos_h
|
182
src/jdk.incubator.jpackage/share/native/common/Toolbox.h
Normal file
182
src/jdk.incubator.jpackage/share/native/common/Toolbox.h
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Toolbox_h
|
||||||
|
#define Toolbox_h
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "tstrings.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder for API not falling into any particular category.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct deletePtr {
|
||||||
|
template <class PtrT>
|
||||||
|
void operator () (PtrT ptr) const {
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all pointers in the given range of items.
|
||||||
|
*/
|
||||||
|
template <class It>
|
||||||
|
void deleteAll(It b, It e) {
|
||||||
|
std::for_each(b, e, deletePtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all pointers from the container.
|
||||||
|
*/
|
||||||
|
template <class Ctnr>
|
||||||
|
void deleteAll(Ctnr& ctnr) {
|
||||||
|
deleteAll(std::begin(ctnr), std::end(ctnr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies std::for_each() to the given object that has begin() and end()
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
template <class Ctnr, class Fn>
|
||||||
|
void forEach(Ctnr& ctnr, Fn fn) {
|
||||||
|
std::for_each(std::begin(ctnr), std::end(ctnr), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Ctnr, class Fn>
|
||||||
|
void forEach(const Ctnr& ctnr, Fn fn) {
|
||||||
|
std::for_each(std::begin(ctnr), std::end(ctnr), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the given functor from destructor. Don't use directly.
|
||||||
|
* This is just a helper for runAtEndOfScope().
|
||||||
|
*/
|
||||||
|
template <class Fn>
|
||||||
|
class AtEndOfScope {
|
||||||
|
Fn func;
|
||||||
|
bool theAbort;
|
||||||
|
public:
|
||||||
|
explicit AtEndOfScope(Fn f): func(f), theAbort(false) {
|
||||||
|
}
|
||||||
|
~AtEndOfScope() {
|
||||||
|
if (!theAbort) {
|
||||||
|
JP_NO_THROW(func());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void abort(bool v=true) {
|
||||||
|
theAbort = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to create AtEndOfScope instance without need to
|
||||||
|
* specify template type explicitly. Like std::make_pair to construct
|
||||||
|
* std::pair instance.
|
||||||
|
*
|
||||||
|
* Use case:
|
||||||
|
* Say you need to call a function (foo()) at exit from another
|
||||||
|
* function (bar()).
|
||||||
|
* You will normally do:
|
||||||
|
* void bar() {
|
||||||
|
* workload();
|
||||||
|
* foo();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* If workload() can throw exceptions things become little bit more
|
||||||
|
* complicated:
|
||||||
|
* void bar() {
|
||||||
|
* JP_NO_THROW(workload());
|
||||||
|
* foo();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* If there is branching in bar() it is little bit more complicated again:
|
||||||
|
* int bar() {
|
||||||
|
* if (...) {
|
||||||
|
* JP_NO_THROW(workload());
|
||||||
|
* foo();
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
* if (...) {
|
||||||
|
* JP_NO_THROW(workload2());
|
||||||
|
* foo();
|
||||||
|
* return 1;
|
||||||
|
* }
|
||||||
|
* foo();
|
||||||
|
* return 2;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* So for relatively complex bar() this approach will end up with
|
||||||
|
* missing foo() call. The standard solution to avoid errors like this,
|
||||||
|
* is to call foo() from some object's destructor, i.e. delegate
|
||||||
|
* responsibility to ensure it is always called to compiler:
|
||||||
|
*
|
||||||
|
* struct FooCaller {
|
||||||
|
* ~FooCaller() { JP_NO_THROW(foo()); }
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* int bar() {
|
||||||
|
* FooCaller fooCaller;
|
||||||
|
* if (...) {
|
||||||
|
* JP_NO_THROW(workload());
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
* if (...) {
|
||||||
|
* JP_NO_THROW(workload2());
|
||||||
|
* foo();
|
||||||
|
* }
|
||||||
|
* return 2;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* However it is annoying to explicitly create FooCaller-like types
|
||||||
|
* for tasks like this. Use of runAtEndOfScope() saves you from this:
|
||||||
|
*
|
||||||
|
* int bar() {
|
||||||
|
* const auto fooCaller = runAtEndOfScope(foo);
|
||||||
|
* if (...) {
|
||||||
|
* JP_NO_THROW(workload());
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
* if (...) {
|
||||||
|
* JP_NO_THROW(workload2());
|
||||||
|
* foo();
|
||||||
|
* }
|
||||||
|
* return 2;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template <class Fn>
|
||||||
|
AtEndOfScope<Fn> runAtEndOfScope(Fn func) {
|
||||||
|
return AtEndOfScope<Fn>(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef Toolbox_h
|
170
src/jdk.incubator.jpackage/share/native/common/kludge_c++11.h
Normal file
170
src/jdk.incubator.jpackage/share/native/common/kludge_c++11.h
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef kludge_cxx11_h
|
||||||
|
#define kludge_cxx11_h
|
||||||
|
|
||||||
|
//
|
||||||
|
// This file contains kludge implementation of C++11 features needed to build
|
||||||
|
// jpackage until Open JDK moves forward from C++98 standard.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#ifndef __clang__
|
||||||
|
#if __cplusplus < 201103L
|
||||||
|
#define JP_WITH_KLUDGE_CXX11
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef JP_WITH_KLUDGE_CXX11
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
template <typename Tp, typename Dp>
|
||||||
|
class unique_ptr_impl {
|
||||||
|
public:
|
||||||
|
typedef typename Dp::pointer pointer;
|
||||||
|
typedef Tp element_type;
|
||||||
|
typedef Dp deleter_type;
|
||||||
|
|
||||||
|
unique_ptr_impl(): value(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr_impl(pointer p): value(p) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer release() {
|
||||||
|
const pointer retValue = value;
|
||||||
|
value = 0;
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unique_ptr_impl& other) {
|
||||||
|
std::swap(value, other.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer get() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unique_ptr_impl(const unique_ptr_impl&);
|
||||||
|
unique_ptr_impl& operator= (const unique_ptr_impl&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pointer value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace impl
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Tp>
|
||||||
|
struct default_delete {
|
||||||
|
typedef Tp* pointer;
|
||||||
|
|
||||||
|
void operator()(Tp* ptr) const {
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Tp, typename Dp = default_delete<Tp> >
|
||||||
|
class unique_ptr {
|
||||||
|
typedef impl::unique_ptr_impl<Tp, Dp> impl_type;
|
||||||
|
public:
|
||||||
|
typedef typename impl_type::pointer pointer;
|
||||||
|
typedef typename impl_type::element_type element_type;
|
||||||
|
typedef typename impl_type::deleter_type deleter_type;
|
||||||
|
|
||||||
|
unique_ptr() {
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr(pointer p): impl(p) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~unique_ptr() {
|
||||||
|
if (get() != 0) {
|
||||||
|
impl_type tmp;
|
||||||
|
tmp.swap(impl);
|
||||||
|
Dp()(tmp.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer release() {
|
||||||
|
return impl.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unique_ptr& other) {
|
||||||
|
impl.swap(other.impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer get() const {
|
||||||
|
return impl.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
element_type& operator *() const {
|
||||||
|
return *impl.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator ->() const {
|
||||||
|
return impl.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
impl_type impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Ctnr>
|
||||||
|
typename Ctnr::const_iterator begin(const Ctnr& ctnr) {
|
||||||
|
return ctnr.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Ctnr>
|
||||||
|
typename Ctnr::iterator begin(Ctnr& ctnr) {
|
||||||
|
return ctnr.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Ctnr>
|
||||||
|
typename Ctnr::const_iterator end(const Ctnr& ctnr) {
|
||||||
|
return ctnr.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Ctnr>
|
||||||
|
typename Ctnr::iterator end(Ctnr& ctnr) {
|
||||||
|
return ctnr.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // #ifdef JP_WITH_KLUDGE_CXX11
|
||||||
|
|
||||||
|
#endif // #ifndef kludge_cxx11_h
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -52,8 +52,15 @@ tstring unsafe_format(tstring::const_pointer format, ...) {
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
ret = _vsntprintf_s(&*fmtout.begin(), fmtout.size(), _TRUNCATE, format, args);
|
ret = _vsntprintf_s(&*fmtout.begin(), fmtout.size(), _TRUNCATE, format, args);
|
||||||
#else
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
|
#endif
|
||||||
// With g++ this compiles only with '-std=gnu++0x' option
|
// With g++ this compiles only with '-std=gnu++0x' option
|
||||||
ret = vsnprintf(&*fmtout.begin(), fmtout.size(), format, args);
|
ret = vsnprintf(&*fmtout.begin(), fmtout.size(), format, args);
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} while(-1 == ret);
|
} while(-1 == ret);
|
||||||
va_end(args);
|
va_end(args);
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -198,7 +198,7 @@ namespace format_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline str_arg_value<std::string> arg(std::string::const_pointer v) {
|
inline str_arg_value<std::string> arg(std::string::const_pointer v) {
|
||||||
return (v ? v : "(null)");
|
return std::string(v ? v: "(null)");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TSTRINGS_WITH_WCHAR
|
#ifdef TSTRINGS_WITH_WCHAR
|
||||||
@ -207,7 +207,7 @@ namespace format_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline str_arg_value<std::wstring> arg(std::wstring::const_pointer v) {
|
inline str_arg_value<std::wstring> arg(std::wstring::const_pointer v) {
|
||||||
return (v ? v : L"(null)");
|
return std::wstring(v ? v : L"(null)");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void arg(const std::wstring&); // Compilation error by design.
|
void arg(const std::wstring&); // Compilation error by design.
|
@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FILEPATH_H
|
|
||||||
#define FILEPATH_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FileAttribute.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class FileAttributes {
|
|
||||||
private:
|
|
||||||
TString FFileName;
|
|
||||||
bool FFollowLink;
|
|
||||||
std::vector<FileAttribute> FAttributes;
|
|
||||||
|
|
||||||
bool WriteAttributes();
|
|
||||||
bool ReadAttributes();
|
|
||||||
bool Valid(const FileAttribute Value);
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileAttributes(const TString FileName, bool FollowLink = true);
|
|
||||||
|
|
||||||
void Append(const FileAttribute Value);
|
|
||||||
bool Contains(const FileAttribute Value);
|
|
||||||
void Remove(const FileAttribute Value);
|
|
||||||
};
|
|
||||||
|
|
||||||
class FilePath {
|
|
||||||
private:
|
|
||||||
FilePath(void) {}
|
|
||||||
~FilePath(void) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static bool FileExists(const TString FileName);
|
|
||||||
static bool DirectoryExists(const TString DirectoryName);
|
|
||||||
|
|
||||||
static bool DeleteFile(const TString FileName);
|
|
||||||
static bool DeleteDirectory(const TString DirectoryName);
|
|
||||||
|
|
||||||
static TString ExtractFilePath(TString Path);
|
|
||||||
static TString ExtractFileExt(TString Path);
|
|
||||||
static TString ExtractFileName(TString Path);
|
|
||||||
static TString ChangeFileExt(TString Path, TString Extension);
|
|
||||||
|
|
||||||
static TString IncludeTrailingSeparator(const TString value);
|
|
||||||
static TString IncludeTrailingSeparator(const char* value);
|
|
||||||
static TString IncludeTrailingSeparator(const wchar_t* value);
|
|
||||||
static TString FixPathForPlatform(TString Path);
|
|
||||||
static TString FixPathSeparatorForPlatform(TString Path);
|
|
||||||
static TString PathSeparator();
|
|
||||||
|
|
||||||
static bool CreateDirectory(TString Path, bool ownerOnly);
|
|
||||||
static void ChangePermissions(TString FileName, bool ownerOnly);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //FILEPATH_H
|
|
@ -1,240 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "PropertyFile.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool Helpers::SplitOptionIntoNameValue(
|
|
||||||
TString option, TString& Name, TString& Value) {
|
|
||||||
bool hasValue = false;
|
|
||||||
Name = _T("");
|
|
||||||
Value = _T("");
|
|
||||||
unsigned int index = 0;
|
|
||||||
|
|
||||||
for (; index < option.length(); index++) {
|
|
||||||
TCHAR c = option[index];
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '=': {
|
|
||||||
index++;
|
|
||||||
hasValue = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case '\\': {
|
|
||||||
if (index + 1 < option.length()) {
|
|
||||||
c = option[index + 1];
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '\\': {
|
|
||||||
index++;
|
|
||||||
Name += '\\';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case '=': {
|
|
||||||
index++;
|
|
||||||
Name += '=';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
Name += c;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasValue) {
|
|
||||||
Value = option.substr(index, index - option.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
return (option.length() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TString Helpers::ReplaceString(TString subject, const TString& search,
|
|
||||||
const TString& replace) {
|
|
||||||
size_t pos = 0;
|
|
||||||
while((pos = subject.find(search, pos)) != TString::npos) {
|
|
||||||
subject.replace(pos, search.length(), replace);
|
|
||||||
pos += replace.length();
|
|
||||||
}
|
|
||||||
return subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Helpers::ConvertIdToFilePath(TString Value) {
|
|
||||||
TString search;
|
|
||||||
search = '.';
|
|
||||||
TString replace;
|
|
||||||
replace = '/';
|
|
||||||
TString result = ReplaceString(Value, search, replace);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Helpers::ConvertIdToJavaPath(TString Value) {
|
|
||||||
TString search;
|
|
||||||
search = '.';
|
|
||||||
TString replace;
|
|
||||||
replace = '/';
|
|
||||||
TString result = ReplaceString(Value, search, replace);
|
|
||||||
search = '\\';
|
|
||||||
result = ReplaceString(result, search, replace);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Helpers::ConvertJavaPathToId(TString Value) {
|
|
||||||
TString search;
|
|
||||||
search = '/';
|
|
||||||
TString replace;
|
|
||||||
replace = '.';
|
|
||||||
TString result = ReplaceString(Value, search, replace);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap<TString, TString>
|
|
||||||
Helpers::GetJavaOptionsFromConfig(IPropertyContainer* config) {
|
|
||||||
OrderedMap<TString, TString> result;
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index < config->GetCount(); index++) {
|
|
||||||
TString argname =
|
|
||||||
TString(_T("jvmarg.")) + PlatformString(index + 1).toString();
|
|
||||||
TString argvalue;
|
|
||||||
|
|
||||||
if (config->GetValue(argname, argvalue) == false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (argvalue.empty() == false) {
|
|
||||||
TString name;
|
|
||||||
TString value;
|
|
||||||
if (Helpers::SplitOptionIntoNameValue(argvalue, name, value)) {
|
|
||||||
result.Append(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> Helpers::GetArgsFromConfig(IPropertyContainer* config) {
|
|
||||||
std::list<TString> result;
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index < config->GetCount(); index++) {
|
|
||||||
TString argname = TString(_T("arg."))
|
|
||||||
+ PlatformString(index + 1).toString();
|
|
||||||
TString argvalue;
|
|
||||||
|
|
||||||
if (config->GetValue(argname, argvalue) == false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (argvalue.empty() == false) {
|
|
||||||
result.push_back((argvalue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString>
|
|
||||||
Helpers::MapToNameValueList(OrderedMap<TString, TString> Map) {
|
|
||||||
std::list<TString> result;
|
|
||||||
std::vector<TString> keys = Map.GetKeys();
|
|
||||||
|
|
||||||
for (OrderedMap<TString, TString>::const_iterator iterator = Map.begin();
|
|
||||||
iterator != Map.end(); iterator++) {
|
|
||||||
JPPair<TString, TString> *item = *iterator;
|
|
||||||
TString key = item->first;
|
|
||||||
TString value = item->second;
|
|
||||||
|
|
||||||
if (value.length() == 0) {
|
|
||||||
result.push_back(key);
|
|
||||||
} else {
|
|
||||||
result.push_back(key + _T('=') + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Helpers::NameValueToString(TString name, TString value) {
|
|
||||||
TString result;
|
|
||||||
|
|
||||||
if (value.empty() == true) {
|
|
||||||
result = name;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = name + TString(_T("=")) + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> Helpers::StringToArray(TString Value) {
|
|
||||||
std::list<TString> result;
|
|
||||||
TString line;
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index < Value.length(); index++) {
|
|
||||||
TCHAR c = Value[index];
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '\n': {
|
|
||||||
result.push_back(line);
|
|
||||||
line = _T("");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case '\r': {
|
|
||||||
result.push_back(line);
|
|
||||||
line = _T("");
|
|
||||||
|
|
||||||
if (Value[index + 1] == '\n')
|
|
||||||
index++;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
line += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The buffer may not have ended with a Carriage Return/Line Feed.
|
|
||||||
if (line.length() > 0) {
|
|
||||||
result.push_back(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HELPERS_H
|
|
||||||
#define HELPERS_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "OrderedMap.h"
|
|
||||||
#include "IniFile.h"
|
|
||||||
|
|
||||||
|
|
||||||
class Helpers {
|
|
||||||
private:
|
|
||||||
Helpers(void) {}
|
|
||||||
~Helpers(void) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Supports two formats for option:
|
|
||||||
// Example 1:
|
|
||||||
// foo=bar
|
|
||||||
//
|
|
||||||
// Example 2:
|
|
||||||
// <name=foo=, value=goo>
|
|
||||||
static bool SplitOptionIntoNameValue(TString option,
|
|
||||||
TString& Name, TString& Value);
|
|
||||||
static TString ReplaceString(TString subject, const TString& search,
|
|
||||||
const TString& replace);
|
|
||||||
static TString ConvertIdToFilePath(TString Value);
|
|
||||||
static TString ConvertIdToJavaPath(TString Value);
|
|
||||||
static TString ConvertJavaPathToId(TString Value);
|
|
||||||
|
|
||||||
static OrderedMap<TString, TString>
|
|
||||||
GetJavaOptionsFromConfig(IPropertyContainer* config);
|
|
||||||
static std::list<TString> GetArgsFromConfig(IPropertyContainer* config);
|
|
||||||
|
|
||||||
static std::list<TString>
|
|
||||||
MapToNameValueList(OrderedMap<TString, TString> Map);
|
|
||||||
|
|
||||||
static TString NameValueToString(TString name, TString value);
|
|
||||||
|
|
||||||
static std::list<TString> StringToArray(TString Value);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // HELPERS_H
|
|
@ -1,261 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
IniFile::IniFile() : ISectionalPropertyContainer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
IniFile::~IniFile() {
|
|
||||||
for (OrderedMap<TString, IniSectionData*>::iterator iterator =
|
|
||||||
FMap.begin(); iterator != FMap.end(); iterator++) {
|
|
||||||
JPPair<TString, IniSectionData*> *item = *iterator;
|
|
||||||
delete item->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniFile::LoadFromFile(const TString FileName) {
|
|
||||||
bool result = false;
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
|
|
||||||
std::list<TString> contents = platform.LoadFromFile(FileName);
|
|
||||||
|
|
||||||
if (contents.empty() == false) {
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
// Determine the if file is an INI file or property file.
|
|
||||||
// Assign FDefaultSection if it is
|
|
||||||
// an INI file. Otherwise FDefaultSection is NULL.
|
|
||||||
for (std::list<TString>::const_iterator iterator = contents.begin();
|
|
||||||
iterator != contents.end(); iterator++) {
|
|
||||||
TString line = *iterator;
|
|
||||||
|
|
||||||
if (line[0] == ';') {
|
|
||||||
// Semicolon is a comment so ignore the line.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (line[0] == '[') {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found == true) {
|
|
||||||
TString sectionName;
|
|
||||||
|
|
||||||
for (std::list<TString>::const_iterator iterator = contents.begin();
|
|
||||||
iterator != contents.end(); iterator++) {
|
|
||||||
TString line = *iterator;
|
|
||||||
|
|
||||||
if (line[0] == ';') {
|
|
||||||
// Semicolon is a comment so ignore the line.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (line[0] == '[' && line[line.length() - 1] == ']') {
|
|
||||||
sectionName = line.substr(1, line.size() - 2);
|
|
||||||
}
|
|
||||||
else if (sectionName.empty() == false) {
|
|
||||||
TString name;
|
|
||||||
TString value;
|
|
||||||
|
|
||||||
if (Helpers::SplitOptionIntoNameValue(
|
|
||||||
line, name, value) == true) {
|
|
||||||
Append(sectionName, name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniFile::SaveToFile(const TString FileName, bool ownerOnly) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
std::list<TString> contents;
|
|
||||||
std::vector<TString> keys = FMap.GetKeys();
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index < keys.size(); index++) {
|
|
||||||
TString name = keys[index];
|
|
||||||
IniSectionData *section = NULL;
|
|
||||||
|
|
||||||
if (FMap.GetValue(name, section) == true && section != NULL) {
|
|
||||||
contents.push_back(_T("[") + name + _T("]"));
|
|
||||||
std::list<TString> lines = section->GetLines();
|
|
||||||
contents.insert(contents.end(), lines.begin(), lines.end());
|
|
||||||
contents.push_back(_T(""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
platform.SaveToFile(FileName, contents, ownerOnly);
|
|
||||||
result = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IniFile::Append(const TString SectionName,
|
|
||||||
const TString Key, TString Value) {
|
|
||||||
if (FMap.ContainsKey(SectionName) == true) {
|
|
||||||
IniSectionData* section = NULL;
|
|
||||||
|
|
||||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
|
||||||
section->SetValue(Key, Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IniSectionData *section = new IniSectionData();
|
|
||||||
section->SetValue(Key, Value);
|
|
||||||
FMap.Append(SectionName, section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IniFile::AppendSection(const TString SectionName,
|
|
||||||
OrderedMap<TString, TString> Values) {
|
|
||||||
if (FMap.ContainsKey(SectionName) == true) {
|
|
||||||
IniSectionData* section = NULL;
|
|
||||||
|
|
||||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
|
||||||
section->Append(Values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IniSectionData *section = new IniSectionData(Values);
|
|
||||||
FMap.Append(SectionName, section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniFile::GetValue(const TString SectionName,
|
|
||||||
const TString Key, TString& Value) {
|
|
||||||
bool result = false;
|
|
||||||
IniSectionData* section = NULL;
|
|
||||||
|
|
||||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
|
||||||
result = section->GetValue(Key, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniFile::SetValue(const TString SectionName,
|
|
||||||
const TString Key, TString Value) {
|
|
||||||
bool result = false;
|
|
||||||
IniSectionData* section = NULL;
|
|
||||||
|
|
||||||
if (FMap.GetValue(SectionName, section) && section != NULL) {
|
|
||||||
result = section->SetValue(Key, Value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Append(SectionName, Key, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniFile::GetSection(const TString SectionName,
|
|
||||||
OrderedMap<TString, TString> &Data) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FMap.ContainsKey(SectionName) == true) {
|
|
||||||
IniSectionData* section = NULL;
|
|
||||||
|
|
||||||
if (FMap.GetValue(SectionName, section) == true && section != NULL) {
|
|
||||||
OrderedMap<TString, TString> data = section->GetData();
|
|
||||||
Data.Append(data);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniFile::ContainsSection(const TString SectionName) {
|
|
||||||
return FMap.ContainsKey(SectionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
IniSectionData::IniSectionData() {
|
|
||||||
FMap.SetAllowDuplicates(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
IniSectionData::IniSectionData(OrderedMap<TString, TString> Values) {
|
|
||||||
FMap = Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> IniSectionData::GetKeys() {
|
|
||||||
return FMap.GetKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> IniSectionData::GetLines() {
|
|
||||||
std::list<TString> result;
|
|
||||||
std::vector<TString> keys = FMap.GetKeys();
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index < keys.size(); index++) {
|
|
||||||
TString name = keys[index];
|
|
||||||
TString value;
|
|
||||||
|
|
||||||
if (FMap.GetValue(name, value) == true) {
|
|
||||||
name = Helpers::ReplaceString(name, _T("="), _T("\\="));
|
|
||||||
value = Helpers::ReplaceString(value, _T("="), _T("\\="));
|
|
||||||
|
|
||||||
TString line = name + _T('=') + value;
|
|
||||||
result.push_back(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap<TString, TString> IniSectionData::GetData() {
|
|
||||||
OrderedMap<TString, TString> result = FMap;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniSectionData::GetValue(const TString Key, TString& Value) {
|
|
||||||
return FMap.GetValue(Key, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IniSectionData::SetValue(const TString Key, TString Value) {
|
|
||||||
return FMap.SetValue(Key, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IniSectionData::Append(OrderedMap<TString, TString> Values) {
|
|
||||||
FMap.Append(Values);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t IniSectionData::GetCount() {
|
|
||||||
return FMap.Count();
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INIFILE_H
|
|
||||||
#define INIFILE_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "OrderedMap.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
class IniSectionData : public IPropertyContainer {
|
|
||||||
private:
|
|
||||||
OrderedMap<TString, TString> FMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
IniSectionData();
|
|
||||||
IniSectionData(OrderedMap<TString, TString> Values);
|
|
||||||
|
|
||||||
std::vector<TString> GetKeys();
|
|
||||||
std::list<TString> GetLines();
|
|
||||||
OrderedMap<TString, TString> GetData();
|
|
||||||
|
|
||||||
bool SetValue(const TString Key, TString Value);
|
|
||||||
void Append(OrderedMap<TString, TString> Values);
|
|
||||||
|
|
||||||
virtual bool GetValue(const TString Key, TString& Value);
|
|
||||||
virtual size_t GetCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class IniFile : public ISectionalPropertyContainer {
|
|
||||||
private:
|
|
||||||
OrderedMap<TString, IniSectionData*> FMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
IniFile();
|
|
||||||
virtual ~IniFile();
|
|
||||||
|
|
||||||
void internalTest();
|
|
||||||
|
|
||||||
bool LoadFromFile(const TString FileName);
|
|
||||||
bool SaveToFile(const TString FileName, bool ownerOnly = true);
|
|
||||||
|
|
||||||
void Append(const TString SectionName, const TString Key, TString Value);
|
|
||||||
void AppendSection(const TString SectionName,
|
|
||||||
OrderedMap<TString, TString> Values);
|
|
||||||
bool SetValue(const TString SectionName,
|
|
||||||
const TString Key, TString Value);
|
|
||||||
|
|
||||||
// ISectionalPropertyContainer
|
|
||||||
virtual bool GetSection(const TString SectionName,
|
|
||||||
OrderedMap<TString, TString> &Data);
|
|
||||||
virtual bool ContainsSection(const TString SectionName);
|
|
||||||
virtual bool GetValue(const TString SectionName,
|
|
||||||
const TString Key, TString& Value);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // INIFILE_H
|
|
@ -1,318 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "JavaVirtualMachine.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
#include "Package.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "Messages.h"
|
|
||||||
#include "Macros.h"
|
|
||||||
|
|
||||||
#include "jni.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
|
|
||||||
bool RunVM() {
|
|
||||||
JavaVirtualMachine javavm;
|
|
||||||
|
|
||||||
bool result = javavm.StartJVM();
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
platform.ShowMessage(_T("Failed to launch JVM\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
JavaOptions::JavaOptions(): FOptions(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaOptions::~JavaOptions() {
|
|
||||||
if (FOptions != NULL) {
|
|
||||||
for (unsigned int index = 0; index < GetCount(); index++) {
|
|
||||||
delete[] FOptions[index].optionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] FOptions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JavaOptions::AppendValue(const TString Key, TString Value, void* Extra) {
|
|
||||||
JavaOptionItem item;
|
|
||||||
item.name = Key;
|
|
||||||
item.value = Value;
|
|
||||||
item.extraInfo = Extra;
|
|
||||||
FItems.push_back(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JavaOptions::AppendValue(const TString Key, TString Value) {
|
|
||||||
AppendValue(Key, Value, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JavaOptions::AppendValue(const TString Key) {
|
|
||||||
AppendValue(Key, _T(""), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JavaOptions::AppendValues(OrderedMap<TString, TString> Values) {
|
|
||||||
if (Values.GetAllowDuplicates()) {
|
|
||||||
for (int i = 0; i < (int)Values.Count(); i++) {
|
|
||||||
TString name, value;
|
|
||||||
|
|
||||||
bool bResult = Values.GetKey(i, name);
|
|
||||||
bResult &= Values.GetValue(i, value);
|
|
||||||
|
|
||||||
if (bResult) {
|
|
||||||
AppendValue(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // In case we asked to add values from OrderedMap with allow
|
|
||||||
// duplicates set to false. Not used now, but should avoid possible
|
|
||||||
// bugs.
|
|
||||||
std::vector<TString> orderedKeys = Values.GetKeys();
|
|
||||||
|
|
||||||
for (std::vector<TString>::const_iterator iterator = orderedKeys.begin();
|
|
||||||
iterator != orderedKeys.end(); iterator++) {
|
|
||||||
TString name = *iterator;
|
|
||||||
TString value;
|
|
||||||
|
|
||||||
if (Values.GetValue(name, value) == true) {
|
|
||||||
AppendValue(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JavaOptions::ReplaceValue(const TString Key, TString Value) {
|
|
||||||
for (std::list<JavaOptionItem>::iterator iterator = FItems.begin();
|
|
||||||
iterator != FItems.end(); iterator++) {
|
|
||||||
|
|
||||||
TString lkey = iterator->name;
|
|
||||||
|
|
||||||
if (lkey == Key) {
|
|
||||||
JavaOptionItem item = *iterator;
|
|
||||||
item.value = Value;
|
|
||||||
iterator = FItems.erase(iterator);
|
|
||||||
FItems.insert(iterator, item);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> JavaOptions::ToList() {
|
|
||||||
std::list<TString> result;
|
|
||||||
Macros& macros = Macros::GetInstance();
|
|
||||||
|
|
||||||
for (std::list<JavaOptionItem>::const_iterator iterator = FItems.begin();
|
|
||||||
iterator != FItems.end(); iterator++) {
|
|
||||||
TString key = iterator->name;
|
|
||||||
TString value = iterator->value;
|
|
||||||
TString option = Helpers::NameValueToString(key, value);
|
|
||||||
option = macros.ExpandMacros(option);
|
|
||||||
result.push_back(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t JavaOptions::GetCount() {
|
|
||||||
return FItems.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
JavaVirtualMachine::JavaVirtualMachine() {
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaVirtualMachine::~JavaVirtualMachine(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JavaVirtualMachine::StartJVM() {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
Package& package = Package::GetInstance();
|
|
||||||
|
|
||||||
TString classpath = package.GetClassPath();
|
|
||||||
TString modulepath = package.GetModulePath();
|
|
||||||
JavaOptions options;
|
|
||||||
|
|
||||||
if (modulepath.empty() == false) {
|
|
||||||
options.AppendValue(_T("-Djava.module.path"), modulepath);
|
|
||||||
}
|
|
||||||
|
|
||||||
options.AppendValue(_T("-Djava.library.path"),
|
|
||||||
package.GetPackageAppDirectory() + FilePath::PathSeparator()
|
|
||||||
+ package.GetPackageLauncherDirectory());
|
|
||||||
options.AppendValue(
|
|
||||||
_T("-Djava.launcher.path"), package.GetPackageLauncherDirectory());
|
|
||||||
options.AppendValues(package.GetJavaOptions());
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (package.Debugging() == dsJava) {
|
|
||||||
options.AppendValue(_T("-Xdebug"), _T(""));
|
|
||||||
options.AppendValue(
|
|
||||||
_T("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=localhost:5005"),
|
|
||||||
_T(""));
|
|
||||||
platform.ShowMessage(_T("localhost:5005"));
|
|
||||||
}
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
TString maxHeapSizeOption;
|
|
||||||
TString minHeapSizeOption;
|
|
||||||
|
|
||||||
|
|
||||||
if (package.GetMemoryState() == PackageBootFields::msAuto) {
|
|
||||||
TPlatformNumber memorySize = package.GetMemorySize();
|
|
||||||
TString memory =
|
|
||||||
PlatformString((size_t)memorySize).toString() + _T("m");
|
|
||||||
maxHeapSizeOption = TString(_T("-Xmx")) + memory;
|
|
||||||
options.AppendValue(maxHeapSizeOption, _T(""));
|
|
||||||
|
|
||||||
if (memorySize > 256)
|
|
||||||
minHeapSizeOption = _T("-Xms256m");
|
|
||||||
else
|
|
||||||
minHeapSizeOption = _T("-Xms") + memory;
|
|
||||||
|
|
||||||
options.AppendValue(minHeapSizeOption, _T(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
TString mainClassName = package.GetMainClassName();
|
|
||||||
TString mainModule = package.GetMainModule();
|
|
||||||
|
|
||||||
if (mainClassName.empty() == true && mainModule.empty() == true) {
|
|
||||||
Messages& messages = Messages::GetInstance();
|
|
||||||
platform.ShowMessage(messages.GetMessage(NO_MAIN_CLASS_SPECIFIED));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
configureLibrary();
|
|
||||||
|
|
||||||
// Initialize the arguments to JLI_Launch()
|
|
||||||
//
|
|
||||||
// On Mac OS X JLI_Launch spawns a new thread that actually starts the JVM.
|
|
||||||
// This new thread simply re-runs main(argc, argv). Therefore we do not
|
|
||||||
// want to add new args if we are still in the original main thread so we
|
|
||||||
// will treat them as command line args provided by the user ...
|
|
||||||
// Only propagate original set of args first time.
|
|
||||||
|
|
||||||
options.AppendValue(_T("-classpath"));
|
|
||||||
options.AppendValue(classpath);
|
|
||||||
|
|
||||||
std::list<TString> vmargs;
|
|
||||||
vmargs.push_back(package.GetCommandName());
|
|
||||||
|
|
||||||
if (package.HasSplashScreen() == true) {
|
|
||||||
options.AppendValue(TString(_T("-splash:"))
|
|
||||||
+ package.GetSplashScreenFileName(), _T(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainModule.empty() == true) {
|
|
||||||
options.AppendValue(Helpers::ConvertJavaPathToId(mainClassName),
|
|
||||||
_T(""));
|
|
||||||
} else {
|
|
||||||
options.AppendValue(_T("-m"));
|
|
||||||
options.AppendValue(mainModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
return launchVM(options, vmargs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JavaVirtualMachine::configureLibrary() {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
Package& package = Package::GetInstance();
|
|
||||||
TString libName = package.GetJavaLibraryFileName();
|
|
||||||
platform.addPlatformDependencies(&javaLibrary);
|
|
||||||
javaLibrary.Load(libName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JavaVirtualMachine::launchVM(JavaOptions& options,
|
|
||||||
std::list<TString>& vmargs) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
Package& package = Package::GetInstance();
|
|
||||||
|
|
||||||
#ifdef MAC
|
|
||||||
// Mac adds a ProcessSerialNumber to args when launched from .app
|
|
||||||
// filter out the psn since they it's not expected in the app
|
|
||||||
if (platform.IsMainThread() == false) {
|
|
||||||
std::list<TString> loptions = options.ToList();
|
|
||||||
vmargs.splice(vmargs.end(), loptions,
|
|
||||||
loptions.begin(), loptions.end());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
std::list<TString> loptions = options.ToList();
|
|
||||||
vmargs.splice(vmargs.end(), loptions, loptions.begin(), loptions.end());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::list<TString> largs = package.GetArgs();
|
|
||||||
vmargs.splice(vmargs.end(), largs, largs.begin(), largs.end());
|
|
||||||
|
|
||||||
size_t argc = vmargs.size();
|
|
||||||
DynamicBuffer<char*> argv(argc + 1);
|
|
||||||
if (argv.GetData() == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int index = 0;
|
|
||||||
for (std::list<TString>::const_iterator iterator = vmargs.begin();
|
|
||||||
iterator != vmargs.end(); iterator++) {
|
|
||||||
TString item = *iterator;
|
|
||||||
std::string arg = PlatformString(item).toStdString();
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("%i %s\n", index, arg.c_str());
|
|
||||||
#endif // DEBUG
|
|
||||||
argv[index] = PlatformString::duplicate(arg.c_str());
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv[argc] = NULL;
|
|
||||||
|
|
||||||
// On Mac we can only free the boot fields if the calling thread is
|
|
||||||
// not the main thread.
|
|
||||||
#ifdef MAC
|
|
||||||
if (platform.IsMainThread() == false) {
|
|
||||||
package.FreeBootFields();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
package.FreeBootFields();
|
|
||||||
#endif // MAC
|
|
||||||
|
|
||||||
if (javaLibrary.JavaVMCreate(argc, argv.GetData()) == true) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index = 0; index < argc; index++) {
|
|
||||||
if (argv[index] != NULL) {
|
|
||||||
delete[] argv[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef JAVAVIRTUALMACHINE_H
|
|
||||||
#define JAVAVIRTUALMACHINE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "jni.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "Library.h"
|
|
||||||
|
|
||||||
struct JavaOptionItem {
|
|
||||||
TString name;
|
|
||||||
TString value;
|
|
||||||
void* extraInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JavaOptions {
|
|
||||||
private:
|
|
||||||
std::list<JavaOptionItem> FItems;
|
|
||||||
JavaVMOption* FOptions;
|
|
||||||
|
|
||||||
public:
|
|
||||||
JavaOptions();
|
|
||||||
~JavaOptions();
|
|
||||||
|
|
||||||
void AppendValue(const TString Key, TString Value, void* Extra);
|
|
||||||
void AppendValue(const TString Key, TString Value);
|
|
||||||
void AppendValue(const TString Key);
|
|
||||||
void AppendValues(OrderedMap<TString, TString> Values);
|
|
||||||
void ReplaceValue(const TString Key, TString Value);
|
|
||||||
std::list<TString> ToList();
|
|
||||||
size_t GetCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
class JavaVirtualMachine {
|
|
||||||
private:
|
|
||||||
JavaLibrary javaLibrary;
|
|
||||||
|
|
||||||
void configureLibrary();
|
|
||||||
bool launchVM(JavaOptions& options, std::list<TString>& vmargs);
|
|
||||||
public:
|
|
||||||
JavaVirtualMachine();
|
|
||||||
~JavaVirtualMachine(void);
|
|
||||||
|
|
||||||
bool StartJVM();
|
|
||||||
};
|
|
||||||
|
|
||||||
bool RunVM();
|
|
||||||
|
|
||||||
#endif // JAVAVIRTUALMACHINE_H
|
|
@ -1,188 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Library.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "Messages.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
Library::Library() {
|
|
||||||
Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Library::Library(const TString &FileName) {
|
|
||||||
Initialize();
|
|
||||||
Load(FileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
Library::~Library() {
|
|
||||||
Unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::Initialize() {
|
|
||||||
FModule = NULL;
|
|
||||||
FDependentLibraryNames = NULL;
|
|
||||||
FDependenciesLibraries = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::InitializeDependencies() {
|
|
||||||
if (FDependentLibraryNames == NULL) {
|
|
||||||
FDependentLibraryNames = new std::vector<TString>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FDependenciesLibraries == NULL) {
|
|
||||||
FDependenciesLibraries = new std::vector<Library*>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::LoadDependencies() {
|
|
||||||
if (FDependentLibraryNames != NULL && FDependenciesLibraries != NULL) {
|
|
||||||
for (std::vector<TString>::const_iterator iterator =
|
|
||||||
FDependentLibraryNames->begin();
|
|
||||||
iterator != FDependentLibraryNames->end(); iterator++) {
|
|
||||||
Library* library = new Library();
|
|
||||||
|
|
||||||
if (library->Load(*iterator) == true) {
|
|
||||||
FDependenciesLibraries->push_back(library);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete FDependentLibraryNames;
|
|
||||||
FDependentLibraryNames = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::UnloadDependencies() {
|
|
||||||
if (FDependenciesLibraries != NULL) {
|
|
||||||
for (std::vector<Library*>::const_iterator iterator =
|
|
||||||
FDependenciesLibraries->begin();
|
|
||||||
iterator != FDependenciesLibraries->end(); iterator++) {
|
|
||||||
Library* library = *iterator;
|
|
||||||
|
|
||||||
if (library != NULL) {
|
|
||||||
library->Unload();
|
|
||||||
delete library;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete FDependenciesLibraries;
|
|
||||||
FDependenciesLibraries = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Procedure Library::GetProcAddress(const std::string& MethodName) const {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
return platform.GetProcAddress(FModule, MethodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Library::Load(const TString &FileName) {
|
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if (FModule == NULL) {
|
|
||||||
LoadDependencies();
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
FModule = platform.LoadLibrary(FileName);
|
|
||||||
|
|
||||||
if (FModule == NULL) {
|
|
||||||
Messages& messages = Messages::GetInstance();
|
|
||||||
platform.ShowMessage(messages.GetMessage(LIBRARY_NOT_FOUND),
|
|
||||||
FileName);
|
|
||||||
result = false;
|
|
||||||
} else {
|
|
||||||
fname = PlatformString(FileName).toStdString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Library::Unload() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FModule != NULL) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
platform.FreeLibrary(FModule);
|
|
||||||
FModule = NULL;
|
|
||||||
UnloadDependencies();
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::AddDependency(const TString &FileName) {
|
|
||||||
InitializeDependencies();
|
|
||||||
|
|
||||||
if (FDependentLibraryNames != NULL) {
|
|
||||||
FDependentLibraryNames->push_back(FileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::AddDependencies(const std::vector<TString> &Dependencies) {
|
|
||||||
if (Dependencies.size() > 0) {
|
|
||||||
InitializeDependencies();
|
|
||||||
|
|
||||||
if (FDependentLibraryNames != NULL) {
|
|
||||||
for (std::vector<TString>::const_iterator iterator =
|
|
||||||
FDependentLibraryNames->begin();
|
|
||||||
iterator != FDependentLibraryNames->end(); iterator++) {
|
|
||||||
TString fileName = *iterator;
|
|
||||||
AddDependency(fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaLibrary::JavaLibrary() : Library(), FCreateProc(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JavaLibrary::JavaVMCreate(size_t argc, char *argv[]) {
|
|
||||||
if (FCreateProc == NULL) {
|
|
||||||
FCreateProc = (JAVA_CREATE) GetProcAddress(LAUNCH_FUNC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FCreateProc == NULL) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
Messages& messages = Messages::GetInstance();
|
|
||||||
platform.ShowMessage(
|
|
||||||
messages.GetMessage(FAILED_LOCATING_JVM_ENTRY_POINT));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FCreateProc((int) argc, argv,
|
|
||||||
0, NULL,
|
|
||||||
0, NULL,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"java",
|
|
||||||
"java",
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
0) == 0;
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LIBRARY_H
|
|
||||||
#define LIBRARY_H
|
|
||||||
|
|
||||||
#include "PlatformDefs.h"
|
|
||||||
//#include "Platform.h"
|
|
||||||
#include "OrderedMap.h"
|
|
||||||
|
|
||||||
#include "jni.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
// Private typedef for function pointer casting
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(_WIN64)
|
|
||||||
#define LAUNCH_FUNC "_JLI_Launch@56"
|
|
||||||
#else
|
|
||||||
#define LAUNCH_FUNC "JLI_Launch"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (JNICALL *JAVA_CREATE)(int argc, char ** argv,
|
|
||||||
int jargc, const char** jargv,
|
|
||||||
int appclassc, const char** appclassv,
|
|
||||||
const char* fullversion,
|
|
||||||
const char* dotversion,
|
|
||||||
const char* pname,
|
|
||||||
const char* lname,
|
|
||||||
jboolean javaargs,
|
|
||||||
jboolean cpwildcard,
|
|
||||||
jboolean javaw,
|
|
||||||
jint ergo);
|
|
||||||
|
|
||||||
class Library {
|
|
||||||
private:
|
|
||||||
std::vector<TString> *FDependentLibraryNames;
|
|
||||||
std::vector<Library*> *FDependenciesLibraries;
|
|
||||||
Module FModule;
|
|
||||||
std::string fname;
|
|
||||||
|
|
||||||
void Initialize();
|
|
||||||
void InitializeDependencies();
|
|
||||||
void LoadDependencies();
|
|
||||||
void UnloadDependencies();
|
|
||||||
|
|
||||||
public:
|
|
||||||
void* GetProcAddress(const std::string& MethodName) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Library();
|
|
||||||
Library(const TString &FileName);
|
|
||||||
~Library();
|
|
||||||
|
|
||||||
bool Load(const TString &FileName);
|
|
||||||
bool Unload();
|
|
||||||
|
|
||||||
const std::string& GetName() const {
|
|
||||||
return fname;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddDependency(const TString &FileName);
|
|
||||||
void AddDependencies(const std::vector<TString> &Dependencies);
|
|
||||||
};
|
|
||||||
|
|
||||||
class JavaLibrary : public Library {
|
|
||||||
JAVA_CREATE FCreateProc;
|
|
||||||
JavaLibrary(const TString &FileName);
|
|
||||||
public:
|
|
||||||
JavaLibrary();
|
|
||||||
bool JavaVMCreate(size_t argc, char *argv[]);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LIBRARY_H
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Macros.h"
|
|
||||||
#include "Package.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
|
|
||||||
|
|
||||||
Macros::Macros(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Macros::~Macros(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Macros::Initialize() {
|
|
||||||
Package& package = Package::GetInstance();
|
|
||||||
Macros& macros = Macros::GetInstance();
|
|
||||||
|
|
||||||
// Public macros.
|
|
||||||
macros.AddMacro(_T("$ROOTDIR"), package.GetPackageRootDirectory());
|
|
||||||
macros.AddMacro(_T("$APPDIR"), package.GetPackageAppDirectory());
|
|
||||||
macros.AddMacro(_T("$BINDIR"), package.GetPackageLauncherDirectory());
|
|
||||||
}
|
|
||||||
|
|
||||||
Macros& Macros::GetInstance() {
|
|
||||||
static Macros instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Macros::ExpandMacros(TString Value) {
|
|
||||||
TString result = Value;
|
|
||||||
|
|
||||||
for (std::map<TString, TString>::iterator iterator = FData.begin();
|
|
||||||
iterator != FData.end();
|
|
||||||
iterator++) {
|
|
||||||
|
|
||||||
TString name = iterator->first;
|
|
||||||
|
|
||||||
if (Value.find(name) != TString::npos) {
|
|
||||||
TString lvalue = iterator->second;
|
|
||||||
result = Helpers::ReplaceString(Value, name, lvalue);
|
|
||||||
result = ExpandMacros(result);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Macros::AddMacro(TString Key, TString Value) {
|
|
||||||
FData.insert(std::map<TString, TString>::value_type(Key, Value));
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Messages.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "Macros.h"
|
|
||||||
#include "JavaVirtualMachine.h"
|
|
||||||
|
|
||||||
Messages::Messages(void) {
|
|
||||||
FMessages.SetReadOnly(false);
|
|
||||||
FMessages.SetValue(LIBRARY_NOT_FOUND, _T("Failed to find library."));
|
|
||||||
FMessages.SetValue(FAILED_CREATING_JVM, _T("Failed to create JVM"));
|
|
||||||
FMessages.SetValue(FAILED_LOCATING_JVM_ENTRY_POINT,
|
|
||||||
_T("Failed to locate JLI_Launch"));
|
|
||||||
FMessages.SetValue(NO_MAIN_CLASS_SPECIFIED, _T("No main class specified"));
|
|
||||||
FMessages.SetValue(METHOD_NOT_FOUND, _T("No method %s in class %s."));
|
|
||||||
FMessages.SetValue(CLASS_NOT_FOUND, _T("Class %s not found."));
|
|
||||||
FMessages.SetValue(ERROR_INVOKING_METHOD, _T("Error invoking method."));
|
|
||||||
FMessages.SetValue(APPCDS_CACHE_FILE_NOT_FOUND,
|
|
||||||
_T("Error: AppCDS cache does not exists:\n%s\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Messages& Messages::GetInstance() {
|
|
||||||
static Messages instance;
|
|
||||||
// Guaranteed to be destroyed. Instantiated on first use.
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Messages::~Messages(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Messages::GetMessage(const TString Key) {
|
|
||||||
TString result;
|
|
||||||
FMessages.GetValue(Key, result);
|
|
||||||
Macros& macros = Macros::GetInstance();
|
|
||||||
result = macros.ExpandMacros(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MESSAGES_H
|
|
||||||
#define MESSAGES_H
|
|
||||||
|
|
||||||
#include "PropertyFile.h"
|
|
||||||
|
|
||||||
#define LIBRARY_NOT_FOUND _T("library.not.found")
|
|
||||||
#define FAILED_CREATING_JVM _T("failed.creating.jvm")
|
|
||||||
#define FAILED_LOCATING_JVM_ENTRY_POINT _T("failed.locating.jvm.entry.point")
|
|
||||||
#define NO_MAIN_CLASS_SPECIFIED _T("no.main.class.specified")
|
|
||||||
|
|
||||||
#define METHOD_NOT_FOUND _T("method.not.found")
|
|
||||||
#define CLASS_NOT_FOUND _T("class.not.found")
|
|
||||||
#define ERROR_INVOKING_METHOD _T("error.invoking.method")
|
|
||||||
|
|
||||||
#define CONFIG_FILE_NOT_FOUND _T("config.file.not.found")
|
|
||||||
|
|
||||||
#define BUNDLED_JVM_NOT_FOUND _T("bundled.jvm.not.found")
|
|
||||||
|
|
||||||
#define APPCDS_CACHE_FILE_NOT_FOUND _T("appcds.cache.file.not.found")
|
|
||||||
|
|
||||||
class Messages {
|
|
||||||
private:
|
|
||||||
PropertyFile FMessages;
|
|
||||||
|
|
||||||
Messages(void);
|
|
||||||
public:
|
|
||||||
static Messages& GetInstance();
|
|
||||||
~Messages(void);
|
|
||||||
|
|
||||||
TString GetMessage(const TString Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MESSAGES_H
|
|
@ -1,271 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ORDEREDMAP_H
|
|
||||||
#define ORDEREDMAP_H
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
template <typename _T1, typename _T2>
|
|
||||||
struct JPPair
|
|
||||||
{
|
|
||||||
typedef _T1 first_type;
|
|
||||||
typedef _T2 second_type;
|
|
||||||
|
|
||||||
first_type first;
|
|
||||||
second_type second;
|
|
||||||
|
|
||||||
JPPair(first_type Value1, second_type Value2) {
|
|
||||||
first = Value1;
|
|
||||||
second = Value2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename TKey, typename TValue>
|
|
||||||
class OrderedMap {
|
|
||||||
public:
|
|
||||||
typedef TKey key_type;
|
|
||||||
typedef TValue mapped_type;
|
|
||||||
typedef JPPair<key_type, mapped_type> container_type;
|
|
||||||
typedef typename std::vector<container_type*>::iterator iterator;
|
|
||||||
typedef typename std::vector<container_type*>::const_iterator const_iterator;
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::map<key_type, container_type*> map_type;
|
|
||||||
typedef std::vector<container_type*> list_type;
|
|
||||||
|
|
||||||
map_type FMap;
|
|
||||||
list_type FList;
|
|
||||||
bool FAllowDuplicates;
|
|
||||||
|
|
||||||
typename list_type::iterator FindListItem(const key_type Key) {
|
|
||||||
typename list_type::iterator result = FList.end();
|
|
||||||
|
|
||||||
for (typename list_type::iterator iterator =
|
|
||||||
FList.begin(); iterator != FList.end(); iterator++) {
|
|
||||||
container_type *item = *iterator;
|
|
||||||
|
|
||||||
if (item->first == Key) {
|
|
||||||
result = iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
OrderedMap() {
|
|
||||||
FAllowDuplicates = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap(const OrderedMap<key_type, mapped_type> &Value) {
|
|
||||||
Append(Value);
|
|
||||||
FAllowDuplicates = Value.GetAllowDuplicates();
|
|
||||||
}
|
|
||||||
|
|
||||||
~OrderedMap() {
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetAllowDuplicates(bool Value) {
|
|
||||||
FAllowDuplicates = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetAllowDuplicates() const {
|
|
||||||
return FAllowDuplicates;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return FList.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const {
|
|
||||||
return FList.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return FList.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const {
|
|
||||||
return FList.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() {
|
|
||||||
for (typename list_type::iterator iterator =
|
|
||||||
FList.begin(); iterator != FList.end(); iterator++) {
|
|
||||||
container_type *item = *iterator;
|
|
||||||
|
|
||||||
if (item != NULL) {
|
|
||||||
delete item;
|
|
||||||
item = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FMap.clear();
|
|
||||||
FList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ContainsKey(key_type Key) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FMap.find(Key) != FMap.end()) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<key_type> GetKeys() {
|
|
||||||
std::vector<key_type> result;
|
|
||||||
|
|
||||||
for (typename list_type::const_iterator iterator = FList.begin();
|
|
||||||
iterator != FList.end(); iterator++) {
|
|
||||||
container_type *item = *iterator;
|
|
||||||
result.push_back(item->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assign(const OrderedMap<key_type, mapped_type> &Value) {
|
|
||||||
Clear();
|
|
||||||
Append(Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Append(const OrderedMap<key_type, mapped_type> &Value) {
|
|
||||||
for (size_t index = 0; index < Value.FList.size(); index++) {
|
|
||||||
container_type *item = Value.FList[index];
|
|
||||||
Append(item->first, item->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Append(key_type Key, mapped_type Value) {
|
|
||||||
container_type *item = new container_type(Key, Value);
|
|
||||||
FMap.insert(std::pair<key_type, container_type*>(Key, item));
|
|
||||||
FList.push_back(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RemoveByKey(key_type Key) {
|
|
||||||
bool result = false;
|
|
||||||
typename list_type::iterator iterator = FindListItem(Key);
|
|
||||||
|
|
||||||
if (iterator != FList.end()) {
|
|
||||||
FMap.erase(Key);
|
|
||||||
FList.erase(iterator);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetValue(key_type Key, mapped_type &Value) {
|
|
||||||
bool result = false;
|
|
||||||
container_type* item = FMap[Key];
|
|
||||||
|
|
||||||
if (item != NULL) {
|
|
||||||
Value = item->second;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SetValue(key_type Key, mapped_type &Value) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if ((FAllowDuplicates == false) && (ContainsKey(Key) == true)) {
|
|
||||||
container_type *item = FMap[Key];
|
|
||||||
|
|
||||||
if (item != NULL) {
|
|
||||||
item->second = Value;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Append(Key, Value);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetKey(int index, key_type &Value) {
|
|
||||||
if (index < 0 || index >= (int)FList.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
container_type *item = FList.at(index);
|
|
||||||
if (item != NULL) {
|
|
||||||
Value = item->first;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetValue(int index, mapped_type &Value) {
|
|
||||||
if (index < 0 || index >= (int)FList.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
container_type *item = FList.at(index);
|
|
||||||
if (item != NULL) {
|
|
||||||
Value = item->second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapped_type &operator[](key_type Key) {
|
|
||||||
container_type* item = FMap[Key];
|
|
||||||
assert(item != NULL);
|
|
||||||
|
|
||||||
if (item != NULL) {
|
|
||||||
return item->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::invalid_argument("Key not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap& operator= (OrderedMap &Value) {
|
|
||||||
Clear();
|
|
||||||
FAllowDuplicates = Value.GetAllowDuplicates();
|
|
||||||
Append(Value);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Count() {
|
|
||||||
return FList.size();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ORDEREDMAP_H
|
|
@ -1,557 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Package.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "Macros.h"
|
|
||||||
#include "IniFile.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
Package::Package(void) {
|
|
||||||
FInitialized = false;
|
|
||||||
Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
TPlatformNumber StringToPercentageOfNumber(TString Value,
|
|
||||||
TPlatformNumber Number) {
|
|
||||||
TPlatformNumber result = 0;
|
|
||||||
size_t percentage = atoi(PlatformString(Value.c_str()));
|
|
||||||
|
|
||||||
if (percentage > 0 && Number > 0) {
|
|
||||||
result = Number * percentage / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Package::Initialize() {
|
|
||||||
if (FInitialized == true) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
|
|
||||||
FBootFields = new PackageBootFields();
|
|
||||||
FDebugging = dsNone;
|
|
||||||
|
|
||||||
// Allow duplicates for Java options, so we can have multiple --add-exports
|
|
||||||
// or similar args.
|
|
||||||
FBootFields->FJavaOptions.SetAllowDuplicates(true);
|
|
||||||
FBootFields->FPackageRootDirectory = platform.GetPackageRootDirectory();
|
|
||||||
FBootFields->FPackageAppDirectory = platform.GetPackageAppDirectory();
|
|
||||||
FBootFields->FPackageLauncherDirectory =
|
|
||||||
platform.GetPackageLauncherDirectory();
|
|
||||||
FBootFields->FAppDataDirectory = platform.GetAppDataDirectory();
|
|
||||||
|
|
||||||
std::map<TString, TString> keys = platform.GetKeys();
|
|
||||||
|
|
||||||
// Read from configure.cfg/Info.plist
|
|
||||||
AutoFreePtr<ISectionalPropertyContainer> config =
|
|
||||||
platform.GetConfigFile(platform.GetConfigFileName());
|
|
||||||
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[JPACKAGE_APP_DATA_DIR], FBootFields->FPackageAppDataDirectory);
|
|
||||||
FBootFields->FPackageAppDataDirectory =
|
|
||||||
FilePath::FixPathForPlatform(FBootFields->FPackageAppDataDirectory);
|
|
||||||
|
|
||||||
// Main JAR.
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_MAINJAR_KEY], FBootFields->FMainJar);
|
|
||||||
FBootFields->FMainJar = FilePath::FixPathForPlatform(FBootFields->FMainJar);
|
|
||||||
|
|
||||||
// Main Module.
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_MAINMODULE_KEY], FBootFields->FMainModule);
|
|
||||||
|
|
||||||
// Classpath.
|
|
||||||
// 1. If the provided class path contains main jar then only use
|
|
||||||
// provided class path.
|
|
||||||
// 2. If class path provided by config file is empty then add main jar.
|
|
||||||
// 3. If main jar is not in provided class path then add it.
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_CLASSPATH_KEY], FBootFields->FClassPath);
|
|
||||||
FBootFields->FClassPath =
|
|
||||||
FilePath::FixPathSeparatorForPlatform(FBootFields->FClassPath);
|
|
||||||
|
|
||||||
if (FBootFields->FClassPath.empty() == true) {
|
|
||||||
FBootFields->FClassPath = GetMainJar();
|
|
||||||
} else if (FBootFields->FClassPath.find(GetMainJar()) == TString::npos) {
|
|
||||||
FBootFields->FClassPath = GetMainJar()
|
|
||||||
+ FilePath::PathSeparator() + FBootFields->FClassPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modulepath.
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_MODULEPATH_KEY], FBootFields->FModulePath);
|
|
||||||
FBootFields->FModulePath =
|
|
||||||
FilePath::FixPathSeparatorForPlatform(FBootFields->FModulePath);
|
|
||||||
|
|
||||||
// Main Class.
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_MAINCLASSNAME_KEY], FBootFields->FMainClassName);
|
|
||||||
|
|
||||||
// Splash Screen.
|
|
||||||
if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_SPLASH_KEY],
|
|
||||||
FBootFields->FSplashScreenFileName) == true) {
|
|
||||||
FBootFields->FSplashScreenFileName =
|
|
||||||
FilePath::IncludeTrailingSeparator(GetPackageAppDirectory())
|
|
||||||
+ FilePath::FixPathForPlatform(FBootFields->FSplashScreenFileName);
|
|
||||||
|
|
||||||
if (FilePath::FileExists(FBootFields->FSplashScreenFileName) == false) {
|
|
||||||
FBootFields->FSplashScreenFileName = _T("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Runtime.
|
|
||||||
config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[JAVA_RUNTIME_KEY], FBootFields->FJavaRuntimeDirectory);
|
|
||||||
|
|
||||||
// Read jvmargs.
|
|
||||||
PromoteAppCDSState(config);
|
|
||||||
ReadJavaOptions(config);
|
|
||||||
|
|
||||||
// Read args if none were passed in.
|
|
||||||
if (FBootFields->FArgs.size() == 0) {
|
|
||||||
OrderedMap<TString, TString> args;
|
|
||||||
|
|
||||||
if (config->GetSection(keys[CONFIG_SECTION_ARGOPTIONS], args) == true) {
|
|
||||||
FBootFields->FArgs = Helpers::MapToNameValueList(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto Memory.
|
|
||||||
TString autoMemory;
|
|
||||||
|
|
||||||
if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_APP_MEMORY], autoMemory) == true) {
|
|
||||||
if (autoMemory == _T("auto") || autoMemory == _T("100%")) {
|
|
||||||
FBootFields->FMemoryState = PackageBootFields::msAuto;
|
|
||||||
FBootFields->FMemorySize = platform.GetMemorySize();
|
|
||||||
} else if (autoMemory.length() == 2 && isdigit(autoMemory[0]) &&
|
|
||||||
autoMemory[1] == '%') {
|
|
||||||
FBootFields->FMemoryState = PackageBootFields::msAuto;
|
|
||||||
FBootFields->FMemorySize =
|
|
||||||
StringToPercentageOfNumber(autoMemory.substr(0, 1),
|
|
||||||
platform.GetMemorySize());
|
|
||||||
} else if (autoMemory.length() == 3 && isdigit(autoMemory[0]) &&
|
|
||||||
isdigit(autoMemory[1]) && autoMemory[2] == '%') {
|
|
||||||
FBootFields->FMemoryState = PackageBootFields::msAuto;
|
|
||||||
FBootFields->FMemorySize =
|
|
||||||
StringToPercentageOfNumber(autoMemory.substr(0, 2),
|
|
||||||
platform.GetMemorySize());
|
|
||||||
} else {
|
|
||||||
FBootFields->FMemoryState = PackageBootFields::msManual;
|
|
||||||
FBootFields->FMemorySize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
TString debug;
|
|
||||||
if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
keys[CONFIG_APP_DEBUG], debug) == true) {
|
|
||||||
FBootFields->FArgs.push_back(debug);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Package::Clear() {
|
|
||||||
FreeBootFields();
|
|
||||||
FInitialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the only location that the AppCDS state should be modified except
|
|
||||||
// by command line arguments provided by the user.
|
|
||||||
//
|
|
||||||
// The state of AppCDS is as follows:
|
|
||||||
//
|
|
||||||
// -> cdsUninitialized
|
|
||||||
// -> cdsGenCache If -Xappcds:generatecache
|
|
||||||
// -> cdsDisabled If -Xappcds:off
|
|
||||||
// -> cdsEnabled If "AppCDSJavaOptions" section is present
|
|
||||||
// -> cdsAuto If "AppCDSJavaOptions" section is present and
|
|
||||||
// app.appcds.cache=auto
|
|
||||||
// -> cdsDisabled Default
|
|
||||||
//
|
|
||||||
void Package::PromoteAppCDSState(ISectionalPropertyContainer* Config) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
std::map<TString, TString> keys = platform.GetKeys();
|
|
||||||
|
|
||||||
// The AppCDS state can change at this point.
|
|
||||||
switch (platform.GetAppCDSState()) {
|
|
||||||
case cdsEnabled:
|
|
||||||
case cdsAuto:
|
|
||||||
case cdsDisabled:
|
|
||||||
case cdsGenCache: {
|
|
||||||
// Do nothing.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsUninitialized: {
|
|
||||||
if (Config->ContainsSection(
|
|
||||||
keys[CONFIG_SECTION_APPCDSJAVAOPTIONS]) == true) {
|
|
||||||
// If the AppCDS section is present then enable AppCDS.
|
|
||||||
TString appCDSCacheValue;
|
|
||||||
|
|
||||||
// If running with AppCDS enabled, and the configuration has
|
|
||||||
// been setup so "auto" is enabled, then
|
|
||||||
// the launcher will attempt to generate the cache file
|
|
||||||
// automatically and run the application.
|
|
||||||
if (Config->GetValue(keys[CONFIG_SECTION_APPLICATION],
|
|
||||||
_T("app.appcds.cache"), appCDSCacheValue) == true &&
|
|
||||||
appCDSCacheValue == _T("auto")) {
|
|
||||||
platform.SetAppCDSState(cdsAuto);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
platform.SetAppCDSState(cdsEnabled);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
platform.SetAppCDSState(cdsDisabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Package::ReadJavaOptions(ISectionalPropertyContainer* Config) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
std::map<TString, TString> keys = platform.GetKeys();
|
|
||||||
|
|
||||||
// Evaluate based on the current AppCDS state.
|
|
||||||
switch (platform.GetAppCDSState()) {
|
|
||||||
case cdsUninitialized: {
|
|
||||||
throw Exception(_T("Internal Error"));
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsDisabled: {
|
|
||||||
Config->GetSection(keys[CONFIG_SECTION_JAVAOPTIONS],
|
|
||||||
FBootFields->FJavaOptions);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsGenCache: {
|
|
||||||
Config->GetSection(keys[
|
|
||||||
CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS],
|
|
||||||
FBootFields->FJavaOptions);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsAuto:
|
|
||||||
case cdsEnabled: {
|
|
||||||
if (Config->GetValue(keys[CONFIG_SECTION_APPCDSJAVAOPTIONS],
|
|
||||||
_T( "-XX:SharedArchiveFile"),
|
|
||||||
FBootFields->FAppCDSCacheFileName) == true) {
|
|
||||||
// File names may contain the incorrect path separators.
|
|
||||||
// The cache file name must be corrected at this point.
|
|
||||||
if (FBootFields->FAppCDSCacheFileName.empty() == false) {
|
|
||||||
IniFile* iniConfig = dynamic_cast<IniFile*>(Config);
|
|
||||||
|
|
||||||
if (iniConfig != NULL) {
|
|
||||||
FBootFields->FAppCDSCacheFileName =
|
|
||||||
FilePath::FixPathForPlatform(
|
|
||||||
FBootFields->FAppCDSCacheFileName);
|
|
||||||
iniConfig->SetValue(keys[
|
|
||||||
CONFIG_SECTION_APPCDSJAVAOPTIONS],
|
|
||||||
_T( "-XX:SharedArchiveFile"),
|
|
||||||
FBootFields->FAppCDSCacheFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Config->GetSection(keys[CONFIG_SECTION_APPCDSJAVAOPTIONS],
|
|
||||||
FBootFields->FJavaOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Package::SetCommandLineArguments(int argc, TCHAR* argv[]) {
|
|
||||||
if (argc > 0) {
|
|
||||||
std::list<TString> args;
|
|
||||||
|
|
||||||
// Prepare app arguments. Skip value at index 0 -
|
|
||||||
// this is path to executable.
|
|
||||||
FBootFields->FCommandName = argv[0];
|
|
||||||
|
|
||||||
// Path to executable is at 0 index so start at index 1.
|
|
||||||
for (int index = 1; index < argc; index++) {
|
|
||||||
TString arg = argv[index];
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (arg == _T("-debug")) {
|
|
||||||
FDebugging = dsNative;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg == _T("-javadebug")) {
|
|
||||||
FDebugging = dsJava;
|
|
||||||
}
|
|
||||||
#endif //DEBUG
|
|
||||||
#ifdef MAC
|
|
||||||
if (arg.find(_T("-psn_"), 0) != TString::npos) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
|
|
||||||
if (platform.IsMainThread() == true) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("%s\n", arg.c_str());
|
|
||||||
#endif //DEBUG
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg == _T("-NSDocumentRevisionsDebugMode")) {
|
|
||||||
// Ignore -NSDocumentRevisionsDebugMode and
|
|
||||||
// the following YES/NO
|
|
||||||
index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif //MAC
|
|
||||||
|
|
||||||
args.push_back(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.size() > 0) {
|
|
||||||
FBootFields->FArgs = args;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Package& Package::GetInstance() {
|
|
||||||
static Package instance;
|
|
||||||
// Guaranteed to be destroyed. Instantiated on first use.
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Package::~Package(void) {
|
|
||||||
FreeBootFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Package::FreeBootFields() {
|
|
||||||
if (FBootFields != NULL) {
|
|
||||||
delete FBootFields;
|
|
||||||
FBootFields = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap<TString, TString> Package::GetJavaOptions() {
|
|
||||||
return FBootFields->FJavaOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> GetKeysThatAreNotDuplicates(OrderedMap<TString,
|
|
||||||
TString> &Defaults, OrderedMap<TString, TString> &Overrides) {
|
|
||||||
std::vector<TString> result;
|
|
||||||
std::vector<TString> overrideKeys = Overrides.GetKeys();
|
|
||||||
|
|
||||||
for (size_t index = 0; index < overrideKeys.size(); index++) {
|
|
||||||
TString overridesKey = overrideKeys[index];
|
|
||||||
TString overridesValue;
|
|
||||||
TString defaultValue;
|
|
||||||
|
|
||||||
if ((Defaults.ContainsKey(overridesKey) == false) ||
|
|
||||||
(Defaults.GetValue(overridesKey, defaultValue) == true &&
|
|
||||||
Overrides.GetValue(overridesKey, overridesValue) == true &&
|
|
||||||
defaultValue != overridesValue)) {
|
|
||||||
result.push_back(overridesKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap<TString, TString> CreateOrderedMapFromKeyList(OrderedMap<TString,
|
|
||||||
TString> &Map, std::vector<TString> &Keys) {
|
|
||||||
OrderedMap<TString, TString> result;
|
|
||||||
|
|
||||||
for (size_t index = 0; index < Keys.size(); index++) {
|
|
||||||
TString key = Keys[index];
|
|
||||||
TString value;
|
|
||||||
|
|
||||||
if (Map.GetValue(key, value) == true) {
|
|
||||||
result.Append(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> GetKeysThatAreNotOverridesOfDefaultValues(
|
|
||||||
OrderedMap<TString, TString> &Defaults, OrderedMap<TString,
|
|
||||||
TString> &Overrides) {
|
|
||||||
std::vector<TString> result;
|
|
||||||
std::vector<TString> keys = Overrides.GetKeys();
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index< keys.size(); index++) {
|
|
||||||
TString key = keys[index];
|
|
||||||
|
|
||||||
if (Defaults.ContainsKey(key) == true) {
|
|
||||||
try {
|
|
||||||
TString value = Overrides[key];
|
|
||||||
Defaults[key] = value;
|
|
||||||
}
|
|
||||||
catch (std::out_of_range &) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.push_back(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> Package::GetArgs() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetPackageRootDirectory() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FPackageRootDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetPackageAppDirectory() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FPackageAppDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetPackageLauncherDirectory() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FPackageLauncherDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetAppDataDirectory() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FAppDataDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetAppCDSCacheDirectory() {
|
|
||||||
if (FAppCDSCacheDirectory.empty()) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
FAppCDSCacheDirectory = FilePath::IncludeTrailingSeparator(
|
|
||||||
platform.GetAppDataDirectory())
|
|
||||||
+ FilePath::IncludeTrailingSeparator(
|
|
||||||
GetPackageAppDataDirectory()) + _T("cache");
|
|
||||||
|
|
||||||
Macros& macros = Macros::GetInstance();
|
|
||||||
FAppCDSCacheDirectory = macros.ExpandMacros(FAppCDSCacheDirectory);
|
|
||||||
FAppCDSCacheDirectory =
|
|
||||||
FilePath::FixPathForPlatform(FAppCDSCacheDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FAppCDSCacheDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetAppCDSCacheFileName() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
|
|
||||||
if (FBootFields->FAppCDSCacheFileName.empty() == false) {
|
|
||||||
Macros& macros = Macros::GetInstance();
|
|
||||||
FBootFields->FAppCDSCacheFileName =
|
|
||||||
macros.ExpandMacros(FBootFields->FAppCDSCacheFileName);
|
|
||||||
FBootFields->FAppCDSCacheFileName =
|
|
||||||
FilePath::FixPathForPlatform(FBootFields->FAppCDSCacheFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FBootFields->FAppCDSCacheFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetPackageAppDataDirectory() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FPackageAppDataDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetClassPath() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FClassPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetModulePath() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FModulePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetMainJar() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FMainJar;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetMainModule() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FMainModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetMainClassName() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FMainClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetJavaLibraryFileName() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
|
|
||||||
if (FBootFields->FJavaLibraryFileName.empty() == true) {
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
Macros& macros = Macros::GetInstance();
|
|
||||||
TString jvmRuntimePath = macros.ExpandMacros(GetJavaRuntimeDirectory());
|
|
||||||
FBootFields->FJavaLibraryFileName =
|
|
||||||
platform.GetBundledJavaLibraryFileName(jvmRuntimePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FBootFields->FJavaLibraryFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetJavaRuntimeDirectory() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FJavaRuntimeDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetSplashScreenFileName() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FSplashScreenFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Package::HasSplashScreen() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FilePath::FileExists(FBootFields->FSplashScreenFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Package::GetCommandName() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FCommandName;
|
|
||||||
}
|
|
||||||
|
|
||||||
TPlatformNumber Package::GetMemorySize() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FMemorySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
PackageBootFields::MemoryState Package::GetMemoryState() {
|
|
||||||
assert(FBootFields != NULL);
|
|
||||||
return FBootFields->FMemoryState;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugState Package::Debugging() {
|
|
||||||
return FDebugging;
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PACKAGE_H
|
|
||||||
#define PACKAGE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
#include "PropertyFile.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
class PackageBootFields {
|
|
||||||
public:
|
|
||||||
enum MemoryState {msManual, msAuto};
|
|
||||||
|
|
||||||
public:
|
|
||||||
OrderedMap<TString, TString> FJavaOptions;
|
|
||||||
std::list<TString> FArgs;
|
|
||||||
|
|
||||||
TString FPackageRootDirectory;
|
|
||||||
TString FPackageAppDirectory;
|
|
||||||
TString FPackageLauncherDirectory;
|
|
||||||
TString FAppDataDirectory;
|
|
||||||
TString FPackageAppDataDirectory;
|
|
||||||
TString FClassPath;
|
|
||||||
TString FModulePath;
|
|
||||||
TString FMainJar;
|
|
||||||
TString FMainModule;
|
|
||||||
TString FMainClassName;
|
|
||||||
TString FJavaRuntimeDirectory;
|
|
||||||
TString FJavaLibraryFileName;
|
|
||||||
TString FSplashScreenFileName;
|
|
||||||
bool FUseJavaPreferences;
|
|
||||||
TString FCommandName;
|
|
||||||
|
|
||||||
TString FAppCDSCacheFileName;
|
|
||||||
|
|
||||||
TPlatformNumber FMemorySize;
|
|
||||||
MemoryState FMemoryState;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Package {
|
|
||||||
private:
|
|
||||||
Package(Package const&); // Don't Implement.
|
|
||||||
void operator=(Package const&); // Don't implement
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool FInitialized;
|
|
||||||
PackageBootFields* FBootFields;
|
|
||||||
TString FAppCDSCacheDirectory;
|
|
||||||
|
|
||||||
DebugState FDebugging;
|
|
||||||
|
|
||||||
Package(void);
|
|
||||||
|
|
||||||
TString GetMainJar();
|
|
||||||
void ReadJavaOptions(ISectionalPropertyContainer* Config);
|
|
||||||
void PromoteAppCDSState(ISectionalPropertyContainer* Config);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Package& GetInstance();
|
|
||||||
~Package(void);
|
|
||||||
|
|
||||||
void Initialize();
|
|
||||||
void Clear();
|
|
||||||
void FreeBootFields();
|
|
||||||
|
|
||||||
void SetCommandLineArguments(int argc, TCHAR* argv[]);
|
|
||||||
|
|
||||||
OrderedMap<TString, TString> GetJavaOptions();
|
|
||||||
TString GetMainModule();
|
|
||||||
|
|
||||||
std::list<TString> GetArgs();
|
|
||||||
|
|
||||||
TString GetPackageRootDirectory();
|
|
||||||
TString GetPackageAppDirectory();
|
|
||||||
TString GetPackageLauncherDirectory();
|
|
||||||
TString GetAppDataDirectory();
|
|
||||||
|
|
||||||
TString GetAppCDSCacheDirectory();
|
|
||||||
TString GetAppCDSCacheFileName();
|
|
||||||
|
|
||||||
TString GetPackageAppDataDirectory();
|
|
||||||
TString GetClassPath();
|
|
||||||
TString GetModulePath();
|
|
||||||
TString GetMainClassName();
|
|
||||||
TString GetJavaLibraryFileName();
|
|
||||||
TString GetJavaRuntimeDirectory();
|
|
||||||
TString GetSplashScreenFileName();
|
|
||||||
bool HasSplashScreen();
|
|
||||||
TString GetCommandName();
|
|
||||||
|
|
||||||
TPlatformNumber GetMemorySize();
|
|
||||||
PackageBootFields::MemoryState GetMemoryState();
|
|
||||||
|
|
||||||
DebugState Debugging();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PACKAGE_H
|
|
@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "Messages.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
#include "WindowsPlatform.h"
|
|
||||||
#endif // WINDOWS
|
|
||||||
#ifdef LINUX
|
|
||||||
#include "LinuxPlatform.h"
|
|
||||||
#endif // LINUX
|
|
||||||
#ifdef MAC
|
|
||||||
#include "MacPlatform.h"
|
|
||||||
#endif // MAC
|
|
||||||
|
|
||||||
Platform& Platform::GetInstance() {
|
|
||||||
#ifdef WINDOWS
|
|
||||||
static WindowsPlatform instance;
|
|
||||||
#endif // WINDOWS
|
|
||||||
|
|
||||||
#ifdef LINUX
|
|
||||||
static LinuxPlatform instance;
|
|
||||||
#endif // LINUX
|
|
||||||
|
|
||||||
#ifdef MAC
|
|
||||||
static MacPlatform instance;
|
|
||||||
#endif // MAC
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Platform::GetConfigFileName() {
|
|
||||||
TString result;
|
|
||||||
TString basedir = GetPackageAppDirectory();
|
|
||||||
|
|
||||||
if (basedir.empty() == false) {
|
|
||||||
basedir = FilePath::IncludeTrailingSeparator(basedir);
|
|
||||||
TString appConfig = basedir + GetAppName() + _T(".cfg");
|
|
||||||
|
|
||||||
if (FilePath::FileExists(appConfig) == true) {
|
|
||||||
result = appConfig;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = basedir + _T("package.cfg");
|
|
||||||
|
|
||||||
if (FilePath::FileExists(result) == false) {
|
|
||||||
result = _T("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> Platform::LoadFromFile(TString FileName) {
|
|
||||||
std::list<TString> result;
|
|
||||||
|
|
||||||
if (FilePath::FileExists(FileName) == true) {
|
|
||||||
std::wifstream stream(FileName.data());
|
|
||||||
InitStreamLocale(&stream);
|
|
||||||
|
|
||||||
if (stream.is_open() == true) {
|
|
||||||
while (stream.eof() == false) {
|
|
||||||
std::wstring line;
|
|
||||||
std::getline(stream, line);
|
|
||||||
|
|
||||||
// # at the first character will comment out the line.
|
|
||||||
if (line.empty() == false && line[0] != '#') {
|
|
||||||
result.push_back(PlatformString(line).toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Platform::SaveToFile(TString FileName, std::list<TString> Contents, bool ownerOnly) {
|
|
||||||
TString path = FilePath::ExtractFilePath(FileName);
|
|
||||||
|
|
||||||
if (FilePath::DirectoryExists(path) == false) {
|
|
||||||
FilePath::CreateDirectory(path, ownerOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wofstream stream(FileName.data());
|
|
||||||
InitStreamLocale(&stream);
|
|
||||||
|
|
||||||
FilePath::ChangePermissions(FileName.data(), ownerOnly);
|
|
||||||
|
|
||||||
if (stream.is_open() == true) {
|
|
||||||
for (std::list<TString>::const_iterator iterator =
|
|
||||||
Contents.begin(); iterator != Contents.end(); iterator++) {
|
|
||||||
TString line = *iterator;
|
|
||||||
stream << PlatformString(line).toUnicodeString() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<TString, TString> Platform::GetKeys() {
|
|
||||||
std::map<TString, TString> keys;
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_VERSION,
|
|
||||||
_T("app.version")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINJAR_KEY,
|
|
||||||
_T("app.mainjar")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINMODULE_KEY,
|
|
||||||
_T("app.mainmodule")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MAINCLASSNAME_KEY,
|
|
||||||
_T("app.mainclass")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_CLASSPATH_KEY,
|
|
||||||
_T("app.classpath")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_MODULEPATH_KEY,
|
|
||||||
_T("app.modulepath")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(APP_NAME_KEY,
|
|
||||||
_T("app.name")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(JAVA_RUNTIME_KEY,
|
|
||||||
_T("app.runtime")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(JPACKAGE_APP_DATA_DIR,
|
|
||||||
_T("app.identifier")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_SPLASH_KEY,
|
|
||||||
_T("app.splash")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_MEMORY,
|
|
||||||
_T("app.memory")));
|
|
||||||
keys.insert(std::map<TString, TString>::value_type(CONFIG_APP_DEBUG,
|
|
||||||
_T("app.debug")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_APPLICATION_INSTANCE,
|
|
||||||
_T("app.application.instance")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_SECTION_APPLICATION,
|
|
||||||
_T("Application")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_SECTION_JAVAOPTIONS,
|
|
||||||
_T("JavaOptions")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_SECTION_APPCDSJAVAOPTIONS,
|
|
||||||
_T("AppCDSJavaOptions")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS,
|
|
||||||
_T("AppCDSGenerateCacheJavaOptions")));
|
|
||||||
keys.insert(std::map<TString,
|
|
||||||
TString>::value_type(CONFIG_SECTION_ARGOPTIONS,
|
|
||||||
_T("ArgOptions")));
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
@ -1,264 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLATFORM_H
|
|
||||||
#define PLATFORM_H
|
|
||||||
|
|
||||||
#include "PlatformDefs.h"
|
|
||||||
#include "Properties.h"
|
|
||||||
#include "OrderedMap.h"
|
|
||||||
#include "Library.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
// Config file sections
|
|
||||||
#define CONFIG_SECTION_APPLICATION _T("CONFIG_SECTION_APPLICATION")
|
|
||||||
#define CONFIG_SECTION_JAVAOPTIONS _T("CONFIG_SECTION_JAVAOPTIONS")
|
|
||||||
#define CONFIG_SECTION_APPCDSJAVAOPTIONS _T("CONFIG_SECTION_APPCDSJAVAOPTIONS")
|
|
||||||
#define CONFIG_SECTION_ARGOPTIONS _T("CONFIG_SECTION_ARGOPTIONS")
|
|
||||||
#define CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS \
|
|
||||||
_T("CONFIG_SECTION_APPCDSGENERATECACHEJAVAOPTIONS")
|
|
||||||
|
|
||||||
// Config file keys.
|
|
||||||
#define CONFIG_VERSION _T("CONFIG_VERSION")
|
|
||||||
#define CONFIG_MAINJAR_KEY _T("CONFIG_MAINJAR_KEY")
|
|
||||||
#define CONFIG_MAINMODULE_KEY _T("CONFIG_MAINMODULE_KEY")
|
|
||||||
#define CONFIG_MAINCLASSNAME_KEY _T("CONFIG_MAINCLASSNAME_KEY")
|
|
||||||
#define CONFIG_CLASSPATH_KEY _T("CONFIG_CLASSPATH_KEY")
|
|
||||||
#define CONFIG_MODULEPATH_KEY _T("CONFIG_MODULEPATH_KEY")
|
|
||||||
#define APP_NAME_KEY _T("APP_NAME_KEY")
|
|
||||||
#define CONFIG_SPLASH_KEY _T("CONFIG_SPLASH_KEY")
|
|
||||||
#define CONFIG_APP_MEMORY _T("CONFIG_APP_MEMORY")
|
|
||||||
#define CONFIG_APP_DEBUG _T("CONFIG_APP_DEBUG")
|
|
||||||
#define CONFIG_APPLICATION_INSTANCE _T("CONFIG_APPLICATION_INSTANCE")
|
|
||||||
|
|
||||||
#define JAVA_RUNTIME_KEY _T("JAVA_RUNTIME_KEY")
|
|
||||||
#define JPACKAGE_APP_DATA_DIR _T("CONFIG_APP_IDENTIFIER")
|
|
||||||
|
|
||||||
struct WideString {
|
|
||||||
size_t length;
|
|
||||||
wchar_t* data;
|
|
||||||
|
|
||||||
WideString() { length = 0; data = NULL; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MultibyteString {
|
|
||||||
size_t length;
|
|
||||||
char* data;
|
|
||||||
|
|
||||||
MultibyteString() { length = 0; data = NULL; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Process {
|
|
||||||
protected:
|
|
||||||
std::list<TString> FOutput;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Process() {
|
|
||||||
Output.SetInstance(this);
|
|
||||||
Input.SetInstance(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Process() {}
|
|
||||||
|
|
||||||
virtual bool IsRunning() = 0;
|
|
||||||
virtual bool Terminate() = 0;
|
|
||||||
virtual bool Execute(const TString Application,
|
|
||||||
const std::vector<TString> Arguments, bool AWait = false) = 0;
|
|
||||||
virtual bool Wait() = 0;
|
|
||||||
virtual TProcessID GetProcessID() = 0;
|
|
||||||
|
|
||||||
virtual std::list<TString> GetOutput() { return FOutput; }
|
|
||||||
virtual void SetInput(TString Value) = 0;
|
|
||||||
|
|
||||||
ReadProperty<Process, std::list<TString>, &Process::GetOutput> Output;
|
|
||||||
WriteProperty<Process, TString, &Process::SetInput> Input;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class AutoFreePtr {
|
|
||||||
private:
|
|
||||||
T* FObject;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AutoFreePtr() {
|
|
||||||
FObject = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoFreePtr(T* Value) {
|
|
||||||
FObject = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoFreePtr() {
|
|
||||||
if (FObject != NULL) {
|
|
||||||
delete FObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T* () const {
|
|
||||||
return FObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator* () const {
|
|
||||||
return *FObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->() const {
|
|
||||||
return FObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
T** operator&() {
|
|
||||||
return &FObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator=(const T * rhs) {
|
|
||||||
FObject = rhs;
|
|
||||||
return FObject;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DebugState {dsNone, dsNative, dsJava};
|
|
||||||
enum MessageResponse {mrOK, mrCancel};
|
|
||||||
enum AppCDSState {cdsUninitialized, cdsDisabled,
|
|
||||||
cdsEnabled, cdsAuto, cdsGenCache};
|
|
||||||
|
|
||||||
class Platform {
|
|
||||||
private:
|
|
||||||
AppCDSState FAppCDSState;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Platform(void): FAppCDSState(cdsUninitialized) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
AppCDSState GetAppCDSState() { return FAppCDSState; }
|
|
||||||
void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; }
|
|
||||||
|
|
||||||
static Platform& GetInstance();
|
|
||||||
|
|
||||||
virtual ~Platform(void) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void ShowMessage(TString title, TString description) = 0;
|
|
||||||
virtual void ShowMessage(TString description) = 0;
|
|
||||||
virtual MessageResponse ShowResponseMessage(TString title,
|
|
||||||
TString description) = 0;
|
|
||||||
|
|
||||||
// Caller must free result using delete[].
|
|
||||||
virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source,
|
|
||||||
bool &release) = 0;
|
|
||||||
|
|
||||||
// Caller must free result using delete[].
|
|
||||||
virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source,
|
|
||||||
bool &release) = 0;
|
|
||||||
|
|
||||||
// Returns:
|
|
||||||
// Windows=C:\Users\<username>\AppData\Local
|
|
||||||
// Linux=~/.local
|
|
||||||
// Mac=~/Library/Application Support
|
|
||||||
virtual TString GetAppDataDirectory() = 0;
|
|
||||||
|
|
||||||
virtual TString GetPackageAppDirectory() = 0;
|
|
||||||
virtual TString GetPackageLauncherDirectory() = 0;
|
|
||||||
virtual TString GetPackageRuntimeBinDirectory() = 0;
|
|
||||||
virtual TString GetAppName() = 0;
|
|
||||||
|
|
||||||
virtual TString GetConfigFileName();
|
|
||||||
|
|
||||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath) = 0;
|
|
||||||
|
|
||||||
// Caller must free result.
|
|
||||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0;
|
|
||||||
|
|
||||||
virtual TString GetModuleFileName() = 0;
|
|
||||||
virtual TString GetPackageRootDirectory() = 0;
|
|
||||||
|
|
||||||
virtual Module LoadLibrary(TString FileName) = 0;
|
|
||||||
virtual void FreeLibrary(Module Module) = 0;
|
|
||||||
virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0;
|
|
||||||
|
|
||||||
// Caller must free result.
|
|
||||||
virtual Process* CreateProcess() = 0;
|
|
||||||
|
|
||||||
virtual bool IsMainThread() = 0;
|
|
||||||
|
|
||||||
// Returns megabytes.
|
|
||||||
virtual TPlatformNumber GetMemorySize() = 0;
|
|
||||||
|
|
||||||
virtual std::map<TString, TString> GetKeys();
|
|
||||||
|
|
||||||
virtual void InitStreamLocale(wios *stream) = 0;
|
|
||||||
virtual std::list<TString> LoadFromFile(TString FileName);
|
|
||||||
virtual void SaveToFile(TString FileName,
|
|
||||||
std::list<TString> Contents, bool ownerOnly);
|
|
||||||
|
|
||||||
virtual TString GetTempDirectory() = 0;
|
|
||||||
|
|
||||||
virtual void addPlatformDependencies(JavaLibrary *pJavaLibrary) = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// String helpers
|
|
||||||
// Caller must free result using delete[].
|
|
||||||
static void CopyString(char *Destination,
|
|
||||||
size_t NumberOfElements, const char *Source);
|
|
||||||
|
|
||||||
// Caller must free result using delete[].
|
|
||||||
static void CopyString(wchar_t *Destination,
|
|
||||||
size_t NumberOfElements, const wchar_t *Source);
|
|
||||||
|
|
||||||
static WideString MultibyteStringToWideString(const char* value);
|
|
||||||
static MultibyteString WideStringToMultibyteString(const wchar_t* value);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Exception: public std::exception {
|
|
||||||
private:
|
|
||||||
TString FMessage;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SetMessage(const TString Message) {
|
|
||||||
FMessage = Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Exception() : exception() {}
|
|
||||||
explicit Exception(const TString Message) : exception() {
|
|
||||||
SetMessage(Message);
|
|
||||||
}
|
|
||||||
virtual ~Exception() throw() {}
|
|
||||||
|
|
||||||
TString GetMessage() { return FMessage; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PLATFORM_H
|
|
@ -1,227 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PlatformString.h"
|
|
||||||
|
|
||||||
#include "Helpers.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "jni.h"
|
|
||||||
|
|
||||||
void PlatformString::initialize() {
|
|
||||||
FWideTStringToFree = NULL;
|
|
||||||
FLength = 0;
|
|
||||||
FData = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(void) {
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::~PlatformString(void) {
|
|
||||||
if (FData != NULL) {
|
|
||||||
delete[] FData;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FWideTStringToFree != NULL) {
|
|
||||||
delete[] FWideTStringToFree;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(const PlatformString &value) {
|
|
||||||
initialize();
|
|
||||||
FLength = value.FLength;
|
|
||||||
FData = new char[FLength + 1];
|
|
||||||
Platform::CopyString(FData, FLength + 1, value.FData);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(const char* value) {
|
|
||||||
initialize();
|
|
||||||
FLength = strlen(value);
|
|
||||||
FData = new char[FLength + 1];
|
|
||||||
Platform::CopyString(FData, FLength + 1, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(size_t Value) {
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
std::string s;
|
|
||||||
ss << Value;
|
|
||||||
s = ss.str();
|
|
||||||
|
|
||||||
FLength = strlen(s.c_str());
|
|
||||||
FData = new char[FLength + 1];
|
|
||||||
Platform::CopyString(FData, FLength + 1, s.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(const wchar_t* value) {
|
|
||||||
initialize();
|
|
||||||
MultibyteString temp = Platform::WideStringToMultibyteString(value);
|
|
||||||
FLength = temp.length;
|
|
||||||
FData = temp.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(const std::string &value) {
|
|
||||||
initialize();
|
|
||||||
const char* lvalue = value.data();
|
|
||||||
FLength = value.size();
|
|
||||||
FData = new char[FLength + 1];
|
|
||||||
Platform::CopyString(FData, FLength + 1, lvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::PlatformString(const std::wstring &value) {
|
|
||||||
initialize();
|
|
||||||
const wchar_t* lvalue = value.data();
|
|
||||||
MultibyteString temp = Platform::WideStringToMultibyteString(lvalue);
|
|
||||||
FLength = temp.length;
|
|
||||||
FData = temp.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString PlatformString::Format(const TString value, ...) {
|
|
||||||
TString result = value;
|
|
||||||
|
|
||||||
va_list arglist;
|
|
||||||
va_start(arglist, value);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
size_t pos = result.find(_T("%s"), 0);
|
|
||||||
|
|
||||||
if (pos == TString::npos) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TCHAR* arg = va_arg(arglist, TCHAR*);
|
|
||||||
|
|
||||||
if (arg == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.replace(pos, StringLength(_T("%s")), arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(arglist);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t PlatformString::length() {
|
|
||||||
return FLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* PlatformString::c_str() {
|
|
||||||
return FData;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* PlatformString::toMultibyte() {
|
|
||||||
return FData;
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t* PlatformString::toWideString() {
|
|
||||||
WideString result = Platform::MultibyteStringToWideString(FData);
|
|
||||||
|
|
||||||
if (result.data != NULL) {
|
|
||||||
if (FWideTStringToFree != NULL) {
|
|
||||||
delete [] FWideTStringToFree;
|
|
||||||
}
|
|
||||||
|
|
||||||
FWideTStringToFree = result.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring PlatformString::toUnicodeString() {
|
|
||||||
std::wstring result;
|
|
||||||
wchar_t* data = toWideString();
|
|
||||||
|
|
||||||
if (FLength != 0 && data != NULL) {
|
|
||||||
// NOTE: Cleanup of result is handled by PlatformString destructor.
|
|
||||||
result = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PlatformString::toStdString() {
|
|
||||||
std::string result;
|
|
||||||
char* data = toMultibyte();
|
|
||||||
|
|
||||||
if (FLength > 0 && data != NULL) {
|
|
||||||
result = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR* PlatformString::toPlatformString() {
|
|
||||||
#ifdef _UNICODE
|
|
||||||
return toWideString();
|
|
||||||
#else
|
|
||||||
return c_str();
|
|
||||||
#endif //_UNICODE
|
|
||||||
}
|
|
||||||
|
|
||||||
TString PlatformString::toString() {
|
|
||||||
#ifdef _UNICODE
|
|
||||||
return toUnicodeString();
|
|
||||||
#else
|
|
||||||
return toStdString();
|
|
||||||
#endif //_UNICODE
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::operator char* () {
|
|
||||||
return c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::operator wchar_t* () {
|
|
||||||
return toWideString();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformString::operator std::wstring () {
|
|
||||||
return toUnicodeString();
|
|
||||||
}
|
|
||||||
|
|
||||||
char* PlatformString::duplicate(const char* Value) {
|
|
||||||
size_t length = strlen(Value);
|
|
||||||
char* result = new char[length + 1];
|
|
||||||
Platform::CopyString(result, length + 1, Value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t* PlatformString::duplicate(const wchar_t* Value) {
|
|
||||||
size_t length = wcslen(Value);
|
|
||||||
wchar_t* result = new wchar_t[length + 1];
|
|
||||||
Platform::CopyString(result, length + 1, Value);
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLATFORMSTRING_H
|
|
||||||
#define PLATFORMSTRING_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "jni.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class DynamicBuffer {
|
|
||||||
private:
|
|
||||||
T* FData;
|
|
||||||
size_t FSize;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DynamicBuffer(size_t Size) {
|
|
||||||
FSize = 0;
|
|
||||||
FData = NULL;
|
|
||||||
Resize(Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~DynamicBuffer() {
|
|
||||||
delete[] FData;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* GetData() { return FData; }
|
|
||||||
size_t GetSize() { return FSize; }
|
|
||||||
|
|
||||||
bool Resize(size_t Size) {
|
|
||||||
FSize = Size;
|
|
||||||
|
|
||||||
if (FData != NULL) {
|
|
||||||
delete[] FData;
|
|
||||||
FData = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FSize != 0) {
|
|
||||||
FData = new T[FSize];
|
|
||||||
if (FData != NULL) {
|
|
||||||
Zero();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Zero() {
|
|
||||||
memset(FData, 0, FSize * sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator[](size_t index) {
|
|
||||||
return FData[index];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlatformString {
|
|
||||||
private:
|
|
||||||
char* FData; // Stored as UTF-8
|
|
||||||
size_t FLength;
|
|
||||||
wchar_t* FWideTStringToFree;
|
|
||||||
|
|
||||||
void initialize();
|
|
||||||
|
|
||||||
// Prohibit Heap-Based PlatformStrings
|
|
||||||
private:
|
|
||||||
static void *operator new(size_t size);
|
|
||||||
static void operator delete(void *ptr);
|
|
||||||
|
|
||||||
public:
|
|
||||||
PlatformString(void);
|
|
||||||
PlatformString(const PlatformString &value);
|
|
||||||
PlatformString(const char* value);
|
|
||||||
PlatformString(const wchar_t* value);
|
|
||||||
PlatformString(const std::string &value);
|
|
||||||
PlatformString(const std::wstring &value);
|
|
||||||
PlatformString(size_t Value);
|
|
||||||
|
|
||||||
static TString Format(const TString value, ...);
|
|
||||||
|
|
||||||
~PlatformString(void);
|
|
||||||
|
|
||||||
size_t length();
|
|
||||||
|
|
||||||
char* c_str();
|
|
||||||
char* toMultibyte();
|
|
||||||
wchar_t* toWideString();
|
|
||||||
std::wstring toUnicodeString();
|
|
||||||
std::string toStdString();
|
|
||||||
TCHAR* toPlatformString();
|
|
||||||
TString toString();
|
|
||||||
|
|
||||||
operator char* ();
|
|
||||||
operator wchar_t* ();
|
|
||||||
operator std::wstring ();
|
|
||||||
|
|
||||||
// Caller must free result using delete[].
|
|
||||||
static char* duplicate(const char* Value);
|
|
||||||
|
|
||||||
// Caller must free result using delete[].
|
|
||||||
static wchar_t* duplicate(const wchar_t* Value);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PLATFORMSTRING_H
|
|
@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PROPERTIES_H
|
|
||||||
#define PROPERTIES_H
|
|
||||||
|
|
||||||
#include "PlatformDefs.h"
|
|
||||||
#include "OrderedMap.h"
|
|
||||||
|
|
||||||
//#include <stdio.h>
|
|
||||||
//#include <stdlib.h>
|
|
||||||
//#include <memory.h>
|
|
||||||
//#include <string>
|
|
||||||
//#include <map>
|
|
||||||
//#include <list>
|
|
||||||
//#include <vector>
|
|
||||||
//#include <fstream>
|
|
||||||
|
|
||||||
//using namespace std;
|
|
||||||
|
|
||||||
template <typename ObjectType, typename ValueType,
|
|
||||||
ValueType (ObjectType::*getter)(void),
|
|
||||||
void (ObjectType::*setter)(ValueType)>
|
|
||||||
class Property {
|
|
||||||
private:
|
|
||||||
ObjectType* FObject;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Property() {
|
|
||||||
FObject = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetInstance(ObjectType* Value) {
|
|
||||||
FObject = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To set the value using the set method.
|
|
||||||
ValueType operator =(const ValueType& Value) {
|
|
||||||
assert(FObject != NULL);
|
|
||||||
(FObject->*setter)(Value);
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Property class is treated as the internal type.
|
|
||||||
operator ValueType() {
|
|
||||||
assert(FObject != NULL);
|
|
||||||
return (FObject->*getter)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ObjectType, typename ValueType,
|
|
||||||
ValueType (ObjectType::*getter)(void)>
|
|
||||||
class ReadProperty {
|
|
||||||
private:
|
|
||||||
ObjectType* FObject;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ReadProperty() {
|
|
||||||
FObject = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetInstance(ObjectType* Value) {
|
|
||||||
FObject = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Property class is treated as the internal type.
|
|
||||||
operator ValueType() {
|
|
||||||
assert(FObject != NULL);
|
|
||||||
return (FObject->*getter)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ObjectType, typename ValueType,
|
|
||||||
void (ObjectType::*setter)(ValueType)>
|
|
||||||
class WriteProperty {
|
|
||||||
private:
|
|
||||||
ObjectType* FObject;
|
|
||||||
|
|
||||||
public:
|
|
||||||
WriteProperty() {
|
|
||||||
FObject = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetInstance(ObjectType* Value) {
|
|
||||||
FObject = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To set the value using the set method.
|
|
||||||
ValueType operator =(const ValueType& Value) {
|
|
||||||
assert(FObject != NULL);
|
|
||||||
(FObject->*setter)(Value);
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType,
|
|
||||||
ValueType (*getter)(void), void (*setter)(ValueType)>
|
|
||||||
class StaticProperty {
|
|
||||||
public:
|
|
||||||
StaticProperty() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// To set the value using the set method.
|
|
||||||
ValueType operator =(const ValueType& Value) {
|
|
||||||
(*getter)(Value);
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Property class is treated as the internal type which is the getter.
|
|
||||||
operator ValueType() {
|
|
||||||
return (*setter)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType, ValueType (*getter)(void)>
|
|
||||||
class StaticReadProperty {
|
|
||||||
public:
|
|
||||||
StaticReadProperty() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Property class is treated as the internal type which is the getter.
|
|
||||||
operator ValueType() {
|
|
||||||
return (*getter)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType, void (*setter)(ValueType)>
|
|
||||||
class StaticWriteProperty {
|
|
||||||
public:
|
|
||||||
StaticWriteProperty() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// To set the value using the set method.
|
|
||||||
ValueType operator =(const ValueType& Value) {
|
|
||||||
(*setter)(Value);
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IPropertyContainer {
|
|
||||||
public:
|
|
||||||
IPropertyContainer(void) {}
|
|
||||||
virtual ~IPropertyContainer(void) {}
|
|
||||||
|
|
||||||
virtual bool GetValue(const TString Key, TString& Value) = 0;
|
|
||||||
virtual size_t GetCount() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ISectionalPropertyContainer {
|
|
||||||
public:
|
|
||||||
ISectionalPropertyContainer(void) {}
|
|
||||||
virtual ~ISectionalPropertyContainer(void) {}
|
|
||||||
|
|
||||||
virtual bool GetValue(const TString SectionName,
|
|
||||||
const TString Key, TString& Value) = 0;
|
|
||||||
virtual bool ContainsSection(const TString SectionName) = 0;
|
|
||||||
virtual bool GetSection(const TString SectionName,
|
|
||||||
OrderedMap<TString, TString> &Data) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PROPERTIES_H
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PropertyFile.h"
|
|
||||||
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
PropertyFile::PropertyFile(void) : IPropertyContainer() {
|
|
||||||
FReadOnly = false;
|
|
||||||
FModified = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyFile::PropertyFile(const TString FileName) : IPropertyContainer() {
|
|
||||||
FReadOnly = true;
|
|
||||||
FModified = false;
|
|
||||||
LoadFromFile(FileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyFile::PropertyFile(OrderedMap<TString, TString> Value) {
|
|
||||||
FData.Append(Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyFile::PropertyFile(PropertyFile &Value) {
|
|
||||||
FData = Value.FData;
|
|
||||||
FReadOnly = Value.FReadOnly;
|
|
||||||
FModified = Value.FModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyFile::~PropertyFile(void) {
|
|
||||||
FData.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PropertyFile::SetModified(bool Value) {
|
|
||||||
FModified = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::IsModified() {
|
|
||||||
return FModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::GetReadOnly() {
|
|
||||||
return FReadOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PropertyFile::SetReadOnly(bool Value) {
|
|
||||||
FReadOnly = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::LoadFromFile(const TString FileName) {
|
|
||||||
bool result = false;
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
|
|
||||||
std::list<TString> contents = platform.LoadFromFile(FileName);
|
|
||||||
|
|
||||||
if (contents.empty() == false) {
|
|
||||||
for (std::list<TString>::const_iterator iterator = contents.begin();
|
|
||||||
iterator != contents.end(); iterator++) {
|
|
||||||
TString line = *iterator;
|
|
||||||
TString name;
|
|
||||||
TString value;
|
|
||||||
|
|
||||||
if (Helpers::SplitOptionIntoNameValue(line, name, value) == true) {
|
|
||||||
FData.Append(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetModified(false);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::SaveToFile(const TString FileName, bool ownerOnly) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (GetReadOnly() == false && IsModified()) {
|
|
||||||
std::list<TString> contents;
|
|
||||||
std::vector<TString> keys = FData.GetKeys();
|
|
||||||
|
|
||||||
for (size_t index = 0; index < keys.size(); index++) {
|
|
||||||
TString name = keys[index];
|
|
||||||
|
|
||||||
try {
|
|
||||||
TString value;// = FData[index];
|
|
||||||
|
|
||||||
if (FData.GetValue(name, value) == true) {
|
|
||||||
TString line = name + _T('=') + value;
|
|
||||||
contents.push_back(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::out_of_range &) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
platform.SaveToFile(FileName, contents, ownerOnly);
|
|
||||||
|
|
||||||
SetModified(false);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::GetValue(const TString Key, TString& Value) {
|
|
||||||
return FData.GetValue(Key, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::SetValue(const TString Key, TString Value) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (GetReadOnly() == false) {
|
|
||||||
FData.SetValue(Key, Value);
|
|
||||||
SetModified(true);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PropertyFile::RemoveKey(const TString Key) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (GetReadOnly() == false) {
|
|
||||||
result = FData.RemoveByKey(Key);
|
|
||||||
|
|
||||||
if (result == true) {
|
|
||||||
SetModified(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t PropertyFile::GetCount() {
|
|
||||||
return FData.Count();
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedMap<TString, TString> PropertyFile::GetData() {
|
|
||||||
return FData;
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PROPERTYFILE_H
|
|
||||||
#define PROPERTYFILE_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyFile : public IPropertyContainer {
|
|
||||||
private:
|
|
||||||
bool FReadOnly;
|
|
||||||
bool FModified;
|
|
||||||
OrderedMap<TString, TString> FData;
|
|
||||||
|
|
||||||
void SetModified(bool Value);
|
|
||||||
|
|
||||||
public:
|
|
||||||
PropertyFile(void);
|
|
||||||
PropertyFile(const TString FileName);
|
|
||||||
PropertyFile(OrderedMap<TString, TString> Value);
|
|
||||||
PropertyFile(PropertyFile &Value);
|
|
||||||
virtual ~PropertyFile(void);
|
|
||||||
|
|
||||||
bool IsModified();
|
|
||||||
bool GetReadOnly();
|
|
||||||
void SetReadOnly(bool Value);
|
|
||||||
|
|
||||||
bool LoadFromFile(const TString FileName);
|
|
||||||
bool SaveToFile(const TString FileName, bool ownerOnly = true);
|
|
||||||
|
|
||||||
bool SetValue(const TString Key, TString Value);
|
|
||||||
bool RemoveKey(const TString Key);
|
|
||||||
|
|
||||||
OrderedMap<TString, TString> GetData();
|
|
||||||
|
|
||||||
// IPropertyContainer
|
|
||||||
virtual bool GetValue(const TString Key, TString& Value);
|
|
||||||
virtual size_t GetCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PROPERTYFILE_H
|
|
@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
#include "PropertyFile.h"
|
|
||||||
#include "JavaVirtualMachine.h"
|
|
||||||
#include "Package.h"
|
|
||||||
#include "Macros.h"
|
|
||||||
#include "Messages.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is the app launcher program for application packaging on Windows, Mac,
|
|
||||||
and Linux.
|
|
||||||
|
|
||||||
Basic approach:
|
|
||||||
- Launcher (jpackageapplauncher) is executable that loads
|
|
||||||
applauncher.dll/libapplauncher.dylib/libapplauncher.so
|
|
||||||
and calls start_launcher below.
|
|
||||||
- Reads app/package.cfg or Info.plist or app/<appname>.cfg for application
|
|
||||||
launch configuration (package.cfg is property file).
|
|
||||||
- Load Java with requested Java settings (bundled client Java if availble,
|
|
||||||
server or installed Java otherwise).
|
|
||||||
- Wait for Java to exit and then exit from Main
|
|
||||||
- To debug application by passing command line argument.
|
|
||||||
- Application folder is added to the library path (so LoadLibrary()) works.
|
|
||||||
|
|
||||||
Limitations and future work:
|
|
||||||
- Running Java code in primordial thread may cause problems
|
|
||||||
(example: can not use custom stack size).
|
|
||||||
Solution used by java launcher is to create a new thread to invoke Java.
|
|
||||||
See CR 6316197 for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
JNIEXPORT bool start_launcher(int argc, TCHAR* argv[]) {
|
|
||||||
bool result = false;
|
|
||||||
bool parentProcess = true;
|
|
||||||
|
|
||||||
// Platform must be initialize first.
|
|
||||||
Platform& platform = Platform::GetInstance();
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int index = 0; index < argc; index++) {
|
|
||||||
TString argument = argv[index];
|
|
||||||
|
|
||||||
if (argument == _T("-Xappcds:generatecache")) {
|
|
||||||
platform.SetAppCDSState(cdsGenCache);
|
|
||||||
}
|
|
||||||
else if (argument == _T("-Xappcds:off")) {
|
|
||||||
platform.SetAppCDSState(cdsDisabled);
|
|
||||||
}
|
|
||||||
else if (argument == _T("-Xapp:child")) {
|
|
||||||
parentProcess = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Package must be initialized after Platform is fully initialized.
|
|
||||||
Package& package = Package::GetInstance();
|
|
||||||
Macros::Initialize();
|
|
||||||
package.SetCommandLineArguments(argc, argv);
|
|
||||||
|
|
||||||
switch (platform.GetAppCDSState()) {
|
|
||||||
case cdsDisabled:
|
|
||||||
case cdsUninitialized:
|
|
||||||
case cdsEnabled: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsGenCache: {
|
|
||||||
TString cacheDirectory = package.GetAppCDSCacheDirectory();
|
|
||||||
|
|
||||||
if (FilePath::DirectoryExists(cacheDirectory) == false) {
|
|
||||||
FilePath::CreateDirectory(cacheDirectory, true);
|
|
||||||
} else {
|
|
||||||
TString cacheFileName =
|
|
||||||
package.GetAppCDSCacheFileName();
|
|
||||||
if (FilePath::FileExists(cacheFileName) == true) {
|
|
||||||
FilePath::DeleteFile(cacheFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsAuto: {
|
|
||||||
TString cacheFileName = package.GetAppCDSCacheFileName();
|
|
||||||
|
|
||||||
if (parentProcess == true &&
|
|
||||||
FilePath::FileExists(cacheFileName) == false) {
|
|
||||||
AutoFreePtr<Process> process = platform.CreateProcess();
|
|
||||||
std::vector<TString> args;
|
|
||||||
args.push_back(_T("-Xappcds:generatecache"));
|
|
||||||
args.push_back(_T("-Xapp:child"));
|
|
||||||
process->Execute(
|
|
||||||
platform.GetModuleFileName(), args, true);
|
|
||||||
|
|
||||||
if (FilePath::FileExists(cacheFileName) == false) {
|
|
||||||
// Cache does not exist after trying to generate it,
|
|
||||||
// so run without cache.
|
|
||||||
platform.SetAppCDSState(cdsDisabled);
|
|
||||||
package.Clear();
|
|
||||||
package.Initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation
|
|
||||||
switch (platform.GetAppCDSState()) {
|
|
||||||
case cdsDisabled:
|
|
||||||
case cdsGenCache: {
|
|
||||||
// Do nothing.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsEnabled:
|
|
||||||
case cdsAuto: {
|
|
||||||
TString cacheFileName =
|
|
||||||
package.GetAppCDSCacheFileName();
|
|
||||||
|
|
||||||
if (FilePath::FileExists(cacheFileName) == false) {
|
|
||||||
Messages& messages = Messages::GetInstance();
|
|
||||||
TString message = PlatformString::Format(
|
|
||||||
messages.GetMessage(
|
|
||||||
APPCDS_CACHE_FILE_NOT_FOUND),
|
|
||||||
cacheFileName.data());
|
|
||||||
throw Exception(message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case cdsUninitialized: {
|
|
||||||
platform.ShowMessage(_T("Internal Error"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run App
|
|
||||||
result = RunVM();
|
|
||||||
} catch (Exception &e) {
|
|
||||||
platform.ShowMessage(e.GetMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void stop_launcher() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,27 +23,22 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MACROS_H
|
#include "PlatformLogEvent.h"
|
||||||
#define MACROS_H
|
#include "Log.h"
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
class Macros {
|
void LogEvent::init(PlatformLogEvent& logEvent) {
|
||||||
private:
|
}
|
||||||
std::map<TString, TString> FData;
|
|
||||||
|
|
||||||
Macros(void);
|
|
||||||
|
|
||||||
public:
|
void LogEvent::appendFormatted(const PlatformLogEvent& logEvent,
|
||||||
static Macros& GetInstance();
|
tstring& buffer) {
|
||||||
static void Initialize();
|
}
|
||||||
~Macros(void);
|
|
||||||
|
|
||||||
TString ExpandMacros(TString Value);
|
|
||||||
void AddMacro(TString Key, TString Value);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MACROS_H
|
void Logger::initializingLogging() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::initializeLogging() {
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,13 +23,11 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#ifndef PlatformLogEvent_h
|
||||||
|
#define PlatformLogEvent_h
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
|
struct PlatformLogEvent {
|
||||||
LPVOID lpvReserved) {
|
};
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#endif // PlatformLogEvent_h
|
68
src/jdk.incubator.jpackage/unix/native/common/UnixDll.cpp
Normal file
68
src/jdk.incubator.jpackage/unix/native/common/UnixDll.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include "Dll.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
HMODULE loadLibrary(const tstring& path) {
|
||||||
|
HMODULE h = dlopen(path.c_str(), RTLD_LAZY);
|
||||||
|
if (!h) {
|
||||||
|
JP_THROW(tstrings::any() << "dlopen(" << path
|
||||||
|
<< ") failed. Error: " << dlerror());
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namesace
|
||||||
|
|
||||||
|
Dll::Dll(const tstrings::any &libPath): thePath(libPath.tstr()),
|
||||||
|
handle(loadLibrary(thePath)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Dll::Dll(const Dll& other): thePath(other.thePath),
|
||||||
|
handle(loadLibrary(thePath)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Dll::getFunction(const std::string &name, bool throwIfNotFound) const {
|
||||||
|
void *ptr = dlsym(handle.get(), name.c_str());
|
||||||
|
if (throwIfNotFound && !ptr) {
|
||||||
|
JP_THROW(tstrings::any() << "dlsym(" << thePath
|
||||||
|
<< ", " << name << ") failed. Error: " << dlerror());
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
void Dll::freeLibrary(HMODULE h) {
|
||||||
|
if (h) {
|
||||||
|
dlclose(h);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,45 +23,43 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PLATFORM_DEFS_H
|
|
||||||
#define PLATFORM_DEFS_H
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dlfcn.h>
|
#include <unistd.h>
|
||||||
#include <libgen.h>
|
#include "FileUtils.h"
|
||||||
#include <string>
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#ifndef LINUX
|
namespace FileUtils {
|
||||||
#define LINUX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _T(x) x
|
bool isFileExists(const tstring &filePath) {
|
||||||
|
struct stat statBuffer;
|
||||||
|
return (stat(filePath.c_str(), &statBuffer) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
typedef char TCHAR;
|
|
||||||
typedef std::string TString;
|
|
||||||
#define StringLength strlen
|
|
||||||
|
|
||||||
typedef unsigned long DWORD;
|
tstring toAbsolutePath(const tstring& path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
char buffer[PATH_MAX] = { 0 };
|
||||||
|
char* buf = getcwd(buffer, sizeof(buffer));
|
||||||
|
if (buf) {
|
||||||
|
tstring result(buf);
|
||||||
|
if (result.empty()) {
|
||||||
|
JP_THROW(tstrings::any() << "getcwd() returned empty string");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#define TRAILING_PATHSEPARATOR '/'
|
JP_THROW(tstrings::any() << "getcwd() failed. Error: "
|
||||||
#define BAD_TRAILING_PATHSEPARATOR '\\'
|
<< lastCRTError());
|
||||||
#define PATH_SEPARATOR ':'
|
}
|
||||||
#define BAD_PATH_SEPARATOR ';'
|
|
||||||
#define MAX_PATH 1000
|
|
||||||
|
|
||||||
typedef long TPlatformNumber;
|
if (isDirSeparator(path[0])) {
|
||||||
typedef pid_t TProcessID;
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
#define HMODULE void*
|
return mkpath() << toAbsolutePath("") << path;
|
||||||
|
}
|
||||||
|
|
||||||
typedef void* Module;
|
} // namespace FileUtils
|
||||||
typedef void* Procedure;
|
|
||||||
|
|
||||||
#define StringToFileSystemString PlatformString
|
|
||||||
#define FileSystemStringToString PlatformString
|
|
||||||
|
|
||||||
#endif // PLATFORM_DEFS_H
|
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "SysInfo.h"
|
||||||
|
#include "UnixSysInfo.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
|
||||||
|
namespace SysInfo {
|
||||||
|
|
||||||
|
tstring getEnvVariable(const tstring& name) {
|
||||||
|
char *value = ::getenv(name.c_str());
|
||||||
|
if (!value) {
|
||||||
|
JP_THROW(tstrings::any() << "getenv("
|
||||||
|
<< name
|
||||||
|
<< ") failed. Variable not set");
|
||||||
|
}
|
||||||
|
return tstring(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring getEnvVariable(const std::nothrow_t&, const tstring& name,
|
||||||
|
const tstring& defValue) {
|
||||||
|
char *value = ::getenv(name.c_str());
|
||||||
|
if (value) {
|
||||||
|
return tstring(value);
|
||||||
|
}
|
||||||
|
return defValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isEnvVariableSet(const tstring& name) {
|
||||||
|
return ::getenv(name.c_str()) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring_array getCommandArgs(CommandArgProgramNameMode progNameMode) {
|
||||||
|
tstring_array result;
|
||||||
|
for (int i = progNameMode == ExcludeProgramName ? 1 : 0; i < argc; i++) {
|
||||||
|
result.push_back(argv[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int argc = 0;
|
||||||
|
char** argv = 0;
|
||||||
|
|
||||||
|
} // end of namespace SysInfo
|
35
src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.h
Normal file
35
src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UnixSysInfo_h
|
||||||
|
#define UnixSysInfo_h
|
||||||
|
|
||||||
|
|
||||||
|
namespace SysInfo {
|
||||||
|
extern int argc;
|
||||||
|
extern char** argv;
|
||||||
|
} // UnixSysInfo
|
||||||
|
|
||||||
|
#endif // UnixSysInfo_h
|
@ -1,331 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "FileAttributes.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <list>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
|
|
||||||
FFileName = FileName;
|
|
||||||
FFollowLink = FollowLink;
|
|
||||||
ReadAttributes();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileAttributes::WriteAttributes() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
mode_t attributes = 0;
|
|
||||||
|
|
||||||
for (std::vector<FileAttribute>::const_iterator iterator =
|
|
||||||
FAttributes.begin();
|
|
||||||
iterator != FAttributes.end(); iterator++) {
|
|
||||||
switch (*iterator) {
|
|
||||||
case faBlockSpecial:
|
|
||||||
{
|
|
||||||
attributes |= S_IFBLK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faCharacterSpecial:
|
|
||||||
{
|
|
||||||
attributes |= S_IFCHR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faFIFOSpecial:
|
|
||||||
{
|
|
||||||
attributes |= S_IFIFO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faNormal:
|
|
||||||
{
|
|
||||||
attributes |= S_IFREG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faDirectory:
|
|
||||||
{
|
|
||||||
attributes |= S_IFDIR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faSymbolicLink:
|
|
||||||
{
|
|
||||||
attributes |= S_IFLNK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faSocket:
|
|
||||||
{
|
|
||||||
attributes |= S_IFSOCK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owner
|
|
||||||
case faReadOnly:
|
|
||||||
{
|
|
||||||
attributes |= S_IRUSR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faWriteOnly:
|
|
||||||
{
|
|
||||||
attributes |= S_IWUSR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faReadWrite:
|
|
||||||
{
|
|
||||||
attributes |= S_IRUSR;
|
|
||||||
attributes |= S_IWUSR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faExecute:
|
|
||||||
{
|
|
||||||
attributes |= S_IXUSR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group
|
|
||||||
case faGroupReadOnly:
|
|
||||||
{
|
|
||||||
attributes |= S_IRGRP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faGroupWriteOnly:
|
|
||||||
{
|
|
||||||
attributes |= S_IWGRP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faGroupReadWrite:
|
|
||||||
{
|
|
||||||
attributes |= S_IRGRP;
|
|
||||||
attributes |= S_IWGRP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faGroupExecute:
|
|
||||||
{
|
|
||||||
attributes |= S_IXGRP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Others
|
|
||||||
case faOthersReadOnly:
|
|
||||||
{
|
|
||||||
attributes |= S_IROTH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faOthersWriteOnly:
|
|
||||||
{
|
|
||||||
attributes |= S_IWOTH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faOthersReadWrite:
|
|
||||||
{
|
|
||||||
attributes |= S_IROTH;
|
|
||||||
attributes |= S_IWOTH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faOthersExecute:
|
|
||||||
{
|
|
||||||
attributes |= S_IXOTH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chmod(FFileName.data(), attributes) == 0) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define S_ISRUSR(m) (((m) & S_IRWXU) == S_IRUSR)
|
|
||||||
#define S_ISWUSR(m) (((m) & S_IRWXU) == S_IWUSR)
|
|
||||||
#define S_ISXUSR(m) (((m) & S_IRWXU) == S_IXUSR)
|
|
||||||
|
|
||||||
#define S_ISRGRP(m) (((m) & S_IRWXG) == S_IRGRP)
|
|
||||||
#define S_ISWGRP(m) (((m) & S_IRWXG) == S_IWGRP)
|
|
||||||
#define S_ISXGRP(m) (((m) & S_IRWXG) == S_IXGRP)
|
|
||||||
|
|
||||||
#define S_ISROTH(m) (((m) & S_IRWXO) == S_IROTH)
|
|
||||||
#define S_ISWOTH(m) (((m) & S_IRWXO) == S_IWOTH)
|
|
||||||
#define S_ISXOTH(m) (((m) & S_IRWXO) == S_IXOTH)
|
|
||||||
|
|
||||||
bool FileAttributes::ReadAttributes() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
struct stat status;
|
|
||||||
|
|
||||||
if (stat(StringToFileSystemString(FFileName), &status) == 0) {
|
|
||||||
result = true;
|
|
||||||
|
|
||||||
if (S_ISBLK(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faBlockSpecial);
|
|
||||||
}
|
|
||||||
if (S_ISCHR(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faCharacterSpecial);
|
|
||||||
}
|
|
||||||
if (S_ISFIFO(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faFIFOSpecial);
|
|
||||||
}
|
|
||||||
if (S_ISREG(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faNormal);
|
|
||||||
}
|
|
||||||
if (S_ISDIR(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faDirectory);
|
|
||||||
}
|
|
||||||
if (S_ISLNK(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faSymbolicLink);
|
|
||||||
}
|
|
||||||
if (S_ISSOCK(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owner
|
|
||||||
if (S_ISRUSR(status.st_mode) != 0) {
|
|
||||||
if (S_ISWUSR(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faReadWrite);
|
|
||||||
} else {
|
|
||||||
FAttributes.push_back(faReadOnly);
|
|
||||||
}
|
|
||||||
} else if (S_ISWUSR(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faWriteOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISXUSR(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faExecute);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group
|
|
||||||
if (S_ISRGRP(status.st_mode) != 0) {
|
|
||||||
if (S_ISWGRP(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faGroupReadWrite);
|
|
||||||
} else {
|
|
||||||
FAttributes.push_back(faGroupReadOnly);
|
|
||||||
}
|
|
||||||
} else if (S_ISWGRP(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faGroupWriteOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISXGRP(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faGroupExecute);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Others
|
|
||||||
if (S_ISROTH(status.st_mode) != 0) {
|
|
||||||
if (S_ISWOTH(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faOthersReadWrite);
|
|
||||||
} else {
|
|
||||||
FAttributes.push_back(faOthersReadOnly);
|
|
||||||
}
|
|
||||||
} else if (S_ISWOTH(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faOthersWriteOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISXOTH(status.st_mode) != 0) {
|
|
||||||
FAttributes.push_back(faOthersExecute);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FFileName.size() > 0 && FFileName[0] == '.') {
|
|
||||||
FAttributes.push_back(faHidden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileAttributes::Valid(const FileAttribute Value) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
switch (Value) {
|
|
||||||
case faReadWrite:
|
|
||||||
case faWriteOnly:
|
|
||||||
case faExecute:
|
|
||||||
|
|
||||||
case faGroupReadWrite:
|
|
||||||
case faGroupWriteOnly:
|
|
||||||
case faGroupReadOnly:
|
|
||||||
case faGroupExecute:
|
|
||||||
|
|
||||||
case faOthersReadWrite:
|
|
||||||
case faOthersWriteOnly:
|
|
||||||
case faOthersReadOnly:
|
|
||||||
case faOthersExecute:
|
|
||||||
|
|
||||||
case faReadOnly:
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileAttributes::Append(FileAttribute Value) {
|
|
||||||
if (Valid(Value) == true) {
|
|
||||||
if ((Value == faReadOnly && Contains(faWriteOnly) == true) ||
|
|
||||||
(Value == faWriteOnly && Contains(faReadOnly) == true)) {
|
|
||||||
Value = faReadWrite;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAttributes.push_back(Value);
|
|
||||||
WriteAttributes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileAttributes::Contains(FileAttribute Value) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
std::vector<FileAttribute>::const_iterator iterator =
|
|
||||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
|
||||||
|
|
||||||
if (iterator != FAttributes.end()) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileAttributes::Remove(FileAttribute Value) {
|
|
||||||
if (Valid(Value) == true) {
|
|
||||||
if (Value == faReadOnly && Contains(faReadWrite) == true) {
|
|
||||||
Append(faWriteOnly);
|
|
||||||
Remove(faReadWrite);
|
|
||||||
} else if (Value == faWriteOnly && Contains(faReadWrite) == true) {
|
|
||||||
Append(faReadOnly);
|
|
||||||
Remove(faReadWrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<FileAttribute>::iterator iterator =
|
|
||||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
|
||||||
|
|
||||||
if (iterator != FAttributes.end()) {
|
|
||||||
FAttributes.erase(iterator);
|
|
||||||
WriteAttributes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,197 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PlatformDefs.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <list>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
bool FilePath::FileExists(const TString FileName) {
|
|
||||||
bool result = false;
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
if ((stat(StringToFileSystemString(FileName), &buf) == 0) &&
|
|
||||||
(S_ISREG(buf.st_mode) != 0)) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::DirectoryExists(const TString DirectoryName) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) &&
|
|
||||||
(S_ISDIR(buf.st_mode) != 0)) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::DeleteFile(const TString FileName) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FileExists(FileName) == true) {
|
|
||||||
if (unlink(StringToFileSystemString(FileName)) == 0) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::DeleteDirectory(const TString DirectoryName) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (DirectoryExists(DirectoryName) == true) {
|
|
||||||
if (unlink(StringToFileSystemString(DirectoryName)) == 0) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::IncludeTrailingSeparator(const TString value) {
|
|
||||||
TString result = value;
|
|
||||||
|
|
||||||
if (value.size() > 0) {
|
|
||||||
TString::iterator i = result.end();
|
|
||||||
i--;
|
|
||||||
|
|
||||||
if (*i != TRAILING_PATHSEPARATOR) {
|
|
||||||
result += TRAILING_PATHSEPARATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::IncludeTrailingSeparator(const char* value) {
|
|
||||||
TString lvalue = PlatformString(value).toString();
|
|
||||||
return IncludeTrailingSeparator(lvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::IncludeTrailingSeparator(const wchar_t* value) {
|
|
||||||
TString lvalue = PlatformString(value).toString();
|
|
||||||
return IncludeTrailingSeparator(lvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ExtractFilePath(TString Path) {
|
|
||||||
return dirname(StringToFileSystemString(Path));
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ExtractFileExt(TString Path) {
|
|
||||||
TString result;
|
|
||||||
size_t dot = Path.find_last_of('.');
|
|
||||||
|
|
||||||
if (dot != TString::npos) {
|
|
||||||
result = Path.substr(dot, Path.size() - dot);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ExtractFileName(TString Path) {
|
|
||||||
return basename(StringToFileSystemString(Path));
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ChangeFileExt(TString Path, TString Extension) {
|
|
||||||
TString result;
|
|
||||||
size_t dot = Path.find_last_of('.');
|
|
||||||
|
|
||||||
if (dot != TString::npos) {
|
|
||||||
result = Path.substr(0, dot) + Extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.empty() == true) {
|
|
||||||
result = Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::FixPathForPlatform(TString Path) {
|
|
||||||
TString result = Path;
|
|
||||||
std::replace(result.begin(), result.end(),
|
|
||||||
BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::FixPathSeparatorForPlatform(TString Path) {
|
|
||||||
TString result = Path;
|
|
||||||
std::replace(result.begin(), result.end(),
|
|
||||||
BAD_PATH_SEPARATOR, PATH_SEPARATOR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::PathSeparator() {
|
|
||||||
TString result;
|
|
||||||
result = PATH_SEPARATOR;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::CreateDirectory(TString Path, bool ownerOnly) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
std::list<TString> paths;
|
|
||||||
TString lpath = Path;
|
|
||||||
|
|
||||||
while (lpath.empty() == false && DirectoryExists(lpath) == false) {
|
|
||||||
paths.push_front(lpath);
|
|
||||||
lpath = ExtractFilePath(lpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::list<TString>::iterator iterator = paths.begin();
|
|
||||||
iterator != paths.end(); iterator++) {
|
|
||||||
lpath = *iterator;
|
|
||||||
|
|
||||||
mode_t mode = S_IRWXU;
|
|
||||||
if (!ownerOnly) {
|
|
||||||
mode |= S_IRWXG | S_IROTH | S_IXOTH;
|
|
||||||
}
|
|
||||||
if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
|
|
||||||
mode_t mode = S_IRWXU;
|
|
||||||
if (!ownerOnly) {
|
|
||||||
mode |= S_IRWXG | S_IROTH | S_IXOTH;
|
|
||||||
}
|
|
||||||
chmod(FileName.data(), mode);
|
|
||||||
}
|
|
@ -1,313 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PosixPlatform.h"
|
|
||||||
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FilePath.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/file.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
PosixPlatform::PosixPlatform(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PosixPlatform::~PosixPlatform(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
TString PosixPlatform::GetTempDirectory() {
|
|
||||||
struct passwd* pw = getpwuid(getuid());
|
|
||||||
TString homedir(pw->pw_dir);
|
|
||||||
homedir += getTmpDirString();
|
|
||||||
if (!FilePath::DirectoryExists(homedir)) {
|
|
||||||
if (!FilePath::CreateDirectory(homedir, false)) {
|
|
||||||
homedir.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return homedir;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString PosixPlatform::fixName(const TString& name) {
|
|
||||||
TString fixedName(name);
|
|
||||||
const TString chars("?:*<>/\\");
|
|
||||||
for (TString::const_iterator it = chars.begin(); it != chars.end(); it++) {
|
|
||||||
fixedName.erase(std::remove(fixedName.begin(),
|
|
||||||
fixedName.end(), *it), fixedName.end());
|
|
||||||
}
|
|
||||||
return fixedName;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageResponse PosixPlatform::ShowResponseMessage(TString title,
|
|
||||||
TString description) {
|
|
||||||
MessageResponse result = mrCancel;
|
|
||||||
|
|
||||||
printf("%s %s (Y/N)\n", PlatformString(title).toPlatformString(),
|
|
||||||
PlatformString(description).toPlatformString());
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
std::string input;
|
|
||||||
std::cin >> input;
|
|
||||||
|
|
||||||
if (input == "Y") {
|
|
||||||
result = mrOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Module PosixPlatform::LoadLibrary(TString FileName) {
|
|
||||||
return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PosixPlatform::FreeLibrary(Module AModule) {
|
|
||||||
dlclose(AModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
Procedure PosixPlatform::GetProcAddress(Module AModule,
|
|
||||||
std::string MethodName) {
|
|
||||||
return dlsym(AModule, PlatformString(MethodName));
|
|
||||||
}
|
|
||||||
|
|
||||||
Process* PosixPlatform::CreateProcess() {
|
|
||||||
return new PosixProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PosixPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Platform::CopyString(char *Destination,
|
|
||||||
size_t NumberOfElements, const char *Source) {
|
|
||||||
strncpy(Destination, Source, NumberOfElements);
|
|
||||||
|
|
||||||
if (NumberOfElements > 0) {
|
|
||||||
Destination[NumberOfElements - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Platform::CopyString(wchar_t *Destination,
|
|
||||||
size_t NumberOfElements, const wchar_t *Source) {
|
|
||||||
wcsncpy(Destination, Source, NumberOfElements);
|
|
||||||
|
|
||||||
if (NumberOfElements > 0) {
|
|
||||||
Destination[NumberOfElements - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owner must free the return value.
|
|
||||||
|
|
||||||
MultibyteString Platform::WideStringToMultibyteString(
|
|
||||||
const wchar_t* value) {
|
|
||||||
MultibyteString result;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (value == NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = wcstombs(NULL, value, 0);
|
|
||||||
if (count > 0) {
|
|
||||||
result.data = new char[count + 1];
|
|
||||||
result.data[count] = '\0';
|
|
||||||
result.length = count;
|
|
||||||
wcstombs(result.data, value, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owner must free the return value.
|
|
||||||
|
|
||||||
WideString Platform::MultibyteStringToWideString(const char* value) {
|
|
||||||
WideString result;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (value == NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = mbstowcs(NULL, value, 0);
|
|
||||||
if (count > 0) {
|
|
||||||
result.data = new wchar_t[count + 1];
|
|
||||||
result.data[count] = '\0';
|
|
||||||
result.length = count;
|
|
||||||
mbstowcs(result.data, value, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PosixPlatform::InitStreamLocale(wios *stream) {
|
|
||||||
// Nothing to do for POSIX platforms.
|
|
||||||
}
|
|
||||||
|
|
||||||
PosixProcess::PosixProcess() : Process() {
|
|
||||||
FChildPID = 0;
|
|
||||||
FRunning = false;
|
|
||||||
FOutputHandle = 0;
|
|
||||||
FInputHandle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PosixProcess::~PosixProcess() {
|
|
||||||
Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PosixProcess::ReadOutput() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FOutputHandle != 0 && IsRunning() == true) {
|
|
||||||
char buffer[4096] = {0};
|
|
||||||
|
|
||||||
ssize_t count = read(FOutputHandle, buffer, sizeof (buffer));
|
|
||||||
|
|
||||||
if (count == -1) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
// continue;
|
|
||||||
} else {
|
|
||||||
perror("read");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} else if (count == 0) {
|
|
||||||
// break;
|
|
||||||
} else {
|
|
||||||
std::list<TString> output = Helpers::StringToArray(buffer);
|
|
||||||
FOutput.splice(FOutput.end(), output, output.begin(), output.end());
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PosixProcess::IsRunning() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (kill(FChildPID, 0) == 0) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PosixProcess::Terminate() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (IsRunning() == true && FRunning == true) {
|
|
||||||
FRunning = false;
|
|
||||||
Cleanup();
|
|
||||||
int status = kill(FChildPID, SIGTERM);
|
|
||||||
|
|
||||||
if (status == 0) {
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (errno == EINVAL) {
|
|
||||||
printf("Kill error: The value of the sig argument is an invalid or unsupported signal number.");
|
|
||||||
} else if (errno == EPERM) {
|
|
||||||
printf("Kill error: The process does not have permission to send the signal to any receiving process.");
|
|
||||||
} else if (errno == ESRCH) {
|
|
||||||
printf("Kill error: No process or process group can be found corresponding to that specified by pid.");
|
|
||||||
}
|
|
||||||
#endif // DEBUG
|
|
||||||
if (IsRunning() == true) {
|
|
||||||
status = kill(FChildPID, SIGKILL);
|
|
||||||
|
|
||||||
if (status == 0) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PosixProcess::Wait() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
int status = 0;
|
|
||||||
pid_t wpid = 0;
|
|
||||||
|
|
||||||
wpid = wait(&status);
|
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
|
||||||
if (errno != EINTR) {
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (WIFEXITED(status)) {
|
|
||||||
printf("child exited, status=%d\n", WEXITSTATUS(status));
|
|
||||||
} else if (WIFSIGNALED(status)) {
|
|
||||||
printf("child killed (signal %d)\n", WTERMSIG(status));
|
|
||||||
} else if (WIFSTOPPED(status)) {
|
|
||||||
printf("child stopped (signal %d)\n", WSTOPSIG(status));
|
|
||||||
#ifdef WIFCONTINUED // Not all implementations support this
|
|
||||||
} else if (WIFCONTINUED(status)) {
|
|
||||||
printf("child continued\n");
|
|
||||||
#endif // WIFCONTINUED
|
|
||||||
} else { // Non-standard case -- may never happen
|
|
||||||
printf("Unexpected status (0x%x)\n", status);
|
|
||||||
}
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
if (wpid != -1) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TProcessID PosixProcess::GetProcessID() {
|
|
||||||
return FChildPID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PosixProcess::SetInput(TString Value) {
|
|
||||||
if (FInputHandle != 0) {
|
|
||||||
if (write(FInputHandle, Value.data(), Value.size()) < 0) {
|
|
||||||
throw Exception(_T("Internal Error - write failed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> PosixProcess::GetOutput() {
|
|
||||||
ReadOutput();
|
|
||||||
return Process::GetOutput();
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef POSIXPLATFORM_H
|
|
||||||
#define POSIXPLATFORM_H
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
class PosixPlatform : virtual public Platform {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
TString fixName(const TString& name);
|
|
||||||
|
|
||||||
virtual TString getTmpDirString() = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PosixPlatform(void);
|
|
||||||
virtual ~PosixPlatform(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual MessageResponse ShowResponseMessage(TString title,
|
|
||||||
TString description);
|
|
||||||
|
|
||||||
virtual Module LoadLibrary(TString FileName);
|
|
||||||
virtual void FreeLibrary(Module AModule);
|
|
||||||
virtual Procedure GetProcAddress(Module AModule, std::string MethodName);
|
|
||||||
|
|
||||||
virtual Process* CreateProcess();
|
|
||||||
virtual TString GetTempDirectory();
|
|
||||||
void InitStreamLocale(wios *stream);
|
|
||||||
void addPlatformDependencies(JavaLibrary *pJavaLibrary);
|
|
||||||
};
|
|
||||||
|
|
||||||
class PosixProcess : public Process {
|
|
||||||
private:
|
|
||||||
pid_t FChildPID;
|
|
||||||
sigset_t saveblock;
|
|
||||||
int FOutputHandle;
|
|
||||||
int FInputHandle;
|
|
||||||
struct sigaction savintr, savequit;
|
|
||||||
bool FRunning;
|
|
||||||
|
|
||||||
void Cleanup();
|
|
||||||
bool ReadOutput();
|
|
||||||
|
|
||||||
public:
|
|
||||||
PosixProcess();
|
|
||||||
virtual ~PosixProcess();
|
|
||||||
|
|
||||||
virtual bool IsRunning();
|
|
||||||
virtual bool Terminate();
|
|
||||||
virtual bool Execute(const TString Application,
|
|
||||||
const std::vector<TString> Arguments, bool AWait = false);
|
|
||||||
virtual bool Wait();
|
|
||||||
virtual TProcessID GetProcessID();
|
|
||||||
virtual void SetInput(TString Value);
|
|
||||||
virtual std::list<TString> GetOutput();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // POSIXPLATFORM_H
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -64,8 +64,6 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
|
|||||||
"jdk.incubator.jpackage.internal.resources.WinResources");
|
"jdk.incubator.jpackage.internal.resources.WinResources");
|
||||||
|
|
||||||
private final static String LIBRARY_NAME = "applauncher.dll";
|
private final static String LIBRARY_NAME = "applauncher.dll";
|
||||||
private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll";
|
|
||||||
private final static String REDIST_MSVCP = "msvcpVS_VER.dll";
|
|
||||||
|
|
||||||
private final static String TEMPLATE_APP_ICON ="java48.ico";
|
private final static String TEMPLATE_APP_ICON ="java48.ico";
|
||||||
|
|
||||||
@ -189,13 +187,6 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
|
|||||||
// copy the jars
|
// copy the jars
|
||||||
copyApplication(params);
|
copyApplication(params);
|
||||||
|
|
||||||
// copy in the needed libraries
|
|
||||||
try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
|
|
||||||
Files.copy(is_lib, binDir.resolve(LIBRARY_NAME));
|
|
||||||
}
|
|
||||||
|
|
||||||
copyMSVCDLLs();
|
|
||||||
|
|
||||||
// create the additional launcher(s), if any
|
// create the additional launcher(s), if any
|
||||||
List<Map<String, ? super Object>> entryPoints =
|
List<Map<String, ? super Object>> entryPoints =
|
||||||
StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
|
StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
|
||||||
@ -209,27 +200,6 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
|
|||||||
public void prepareJreFiles(Map<String, ? super Object> params)
|
public void prepareJreFiles(Map<String, ? super Object> params)
|
||||||
throws IOException {}
|
throws IOException {}
|
||||||
|
|
||||||
private void copyMSVCDLLs() throws IOException {
|
|
||||||
AtomicReference<IOException> ioe = new AtomicReference<>();
|
|
||||||
try (Stream<Path> files = Files.list(runtimeDir.resolve("bin"))) {
|
|
||||||
files.filter(p -> Pattern.matches(
|
|
||||||
"^(vcruntime|msvcp|msvcr|ucrtbase|api-ms-win-).*\\.dll$",
|
|
||||||
p.toFile().getName().toLowerCase()))
|
|
||||||
.forEach(p -> {
|
|
||||||
try {
|
|
||||||
Files.copy(p, binDir.resolve((p.toFile().getName())));
|
|
||||||
} catch (IOException e) {
|
|
||||||
ioe.set(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
IOException e = ioe.get();
|
|
||||||
if (e != null) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateValueAndPut(
|
private void validateValueAndPut(
|
||||||
Map<String, String> data, String key,
|
Map<String, String> data, String key,
|
||||||
BundlerParamInfo<String> param,
|
BundlerParamInfo<String> param,
|
||||||
|
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "AppLauncher.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "UniqueHandle.h"
|
||||||
|
#include "ErrorHandling.h"
|
||||||
|
#include "WinErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
|
// AllowSetForegroundWindow
|
||||||
|
#pragma comment(lib, "user32")
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void launchApp() {
|
||||||
|
// [RT-31061] otherwise UI can be left in back of other windows.
|
||||||
|
::AllowSetForegroundWindow(ASFW_ANY);
|
||||||
|
|
||||||
|
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||||
|
const tstring appImageRoot = FileUtils::dirname(launcherPath);
|
||||||
|
|
||||||
|
AppLauncher()
|
||||||
|
.setImageRoot(appImageRoot)
|
||||||
|
.addJvmLibName(_T("bin\\jli.dll"))
|
||||||
|
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
|
||||||
|
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||||
|
<< _T("runtime"))
|
||||||
|
.launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JP_LAUNCHERW
|
||||||
|
|
||||||
|
int APIENTRY wmain() {
|
||||||
|
return AppLauncher::launch(std::nothrow, launchApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class LastErrorGuiLogAppender : public LogAppender {
|
||||||
|
public:
|
||||||
|
virtual void append(const LogEvent& v) {
|
||||||
|
JP_TRY;
|
||||||
|
|
||||||
|
const std::wstring msg = (tstrings::any()
|
||||||
|
<< AppLauncher::lastErrorMsg()).wstr();
|
||||||
|
MessageBox(0, msg.c_str(),
|
||||||
|
FileUtils::basename(SysInfo::getProcessModulePath()).c_str(),
|
||||||
|
MB_ICONERROR | MB_OK);
|
||||||
|
|
||||||
|
JP_CATCH_ALL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Console {
|
||||||
|
public:
|
||||||
|
Console() {
|
||||||
|
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
|
// Failed to connect to parent's console. Create our own.
|
||||||
|
if (!AllocConsole()) {
|
||||||
|
// We already have a console, no need to redirect std I/O.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdoutChannel = std::unique_ptr<Channel>(new Channel(stdout));
|
||||||
|
stderrChannel = std::unique_ptr<Channel>(new Channel(stderr));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FileCloser {
|
||||||
|
typedef FILE* pointer;
|
||||||
|
|
||||||
|
void operator()(pointer h) {
|
||||||
|
::fclose(h);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::unique_ptr<
|
||||||
|
FileCloser::pointer,
|
||||||
|
FileCloser
|
||||||
|
> UniqueFILEHandle;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Channel {
|
||||||
|
public:
|
||||||
|
Channel(FILE* stdFILEHandle): stdFILEHandle(stdFILEHandle) {
|
||||||
|
const char* stdFileName = "CONOUT$";
|
||||||
|
const char* openMode = "w";
|
||||||
|
if (stdFILEHandle == stdin) {
|
||||||
|
stdFileName = "CONIN$";
|
||||||
|
openMode = "r";
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* fp = 0;
|
||||||
|
freopen_s(&fp, stdFileName, openMode, stdFILEHandle);
|
||||||
|
|
||||||
|
fileHandle = UniqueFILEHandle(fp);
|
||||||
|
|
||||||
|
std::ios_base::sync_with_stdio();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Channel() {
|
||||||
|
JP_TRY;
|
||||||
|
|
||||||
|
FILE* fp = 0;
|
||||||
|
fileHandle = UniqueFILEHandle(fp);
|
||||||
|
std::ios_base::sync_with_stdio();
|
||||||
|
|
||||||
|
JP_CATCH_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
UniqueFILEHandle fileHandle;
|
||||||
|
FILE *stdFILEHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<Channel> stdoutChannel;
|
||||||
|
std::unique_ptr<Channel> stderrChannel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void launchAppW() {
|
||||||
|
std::unique_ptr<Console> console;
|
||||||
|
if (AppLauncher::isWithLogging()) {
|
||||||
|
console = std::unique_ptr<Console>(new Console());
|
||||||
|
}
|
||||||
|
|
||||||
|
launchApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
|
||||||
|
LastErrorGuiLogAppender lastErrorLogAppender;
|
||||||
|
TeeLogAppender logAppender(&AppLauncher::defaultLastErrorLogAppender(),
|
||||||
|
&lastErrorLogAppender);
|
||||||
|
return AppLauncher::launch(std::nothrow, launchAppW, &logAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include "PlatformLogEvent.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
tstring retrieveModuleName() {
|
||||||
|
try {
|
||||||
|
return FileUtils::basename(SysInfo::getCurrentModulePath());
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error&) {
|
||||||
|
return _T("Unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TCHAR moduleName[MAX_PATH] = { 'U', 'n', 'k', 'n', 'o', 'w', 'n', TCHAR(0) };
|
||||||
|
|
||||||
|
const LPCTSTR formatStr = _T("%04u/%02u/%02u %02u:%02u:%02u.%03u, %s (PID: %u, TID: %u), ");
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
PlatformLogEvent::PlatformLogEvent() {
|
||||||
|
std::memset(static_cast<void*>(this), 0, sizeof(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LogEvent::init(PlatformLogEvent& logEvent) {
|
||||||
|
GetLocalTime(&logEvent.ts);
|
||||||
|
logEvent.pid = GetCurrentProcessId();
|
||||||
|
logEvent.tid = GetCurrentThreadId();
|
||||||
|
logEvent.moduleName = ::moduleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LogEvent::appendFormatted(const PlatformLogEvent& logEvent,
|
||||||
|
tstring& buffer) {
|
||||||
|
const tstring str = tstrings::unsafe_format(formatStr,
|
||||||
|
unsigned(logEvent.ts.wYear),
|
||||||
|
unsigned(logEvent.ts.wMonth),
|
||||||
|
unsigned(logEvent.ts.wDay),
|
||||||
|
unsigned(logEvent.ts.wHour),
|
||||||
|
unsigned(logEvent.ts.wMinute),
|
||||||
|
unsigned(logEvent.ts.wSecond),
|
||||||
|
unsigned(logEvent.ts.wMilliseconds),
|
||||||
|
logEvent.moduleName,
|
||||||
|
logEvent.pid,
|
||||||
|
logEvent.tid);
|
||||||
|
buffer.append(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::initializingLogging() {
|
||||||
|
moduleName[0] = TCHAR(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::initializeLogging() {
|
||||||
|
tstring mname = retrieveModuleName();
|
||||||
|
mname.resize(_countof(moduleName) - 1);
|
||||||
|
std::memcpy(moduleName, mname.c_str(), mname.size());
|
||||||
|
moduleName[mname.size()] = TCHAR(0);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,32 +23,19 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILEATTRIBUTES_H
|
#ifndef PlatformLogEvent_h
|
||||||
#define FILEATTRIBUTES_H
|
#define PlatformLogEvent_h
|
||||||
|
|
||||||
#include "Platform.h"
|
#include <windows.h>
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "FileAttribute.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class FileAttributes {
|
struct PlatformLogEvent {
|
||||||
private:
|
SYSTEMTIME ts;
|
||||||
TString FFileName;
|
long tid;
|
||||||
bool FFollowLink;
|
long pid;
|
||||||
std::vector<FileAttribute> FAttributes;
|
LPCTSTR moduleName;
|
||||||
|
|
||||||
bool WriteAttributes();
|
PlatformLogEvent();
|
||||||
bool ReadAttributes();
|
|
||||||
bool Valid(const FileAttribute Value);
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileAttributes(const TString FileName, bool FollowLink = true);
|
|
||||||
|
|
||||||
void Append(const FileAttribute Value);
|
|
||||||
bool Contains(const FileAttribute Value);
|
|
||||||
void Remove(const FileAttribute Value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILEATTRIBUTES_H
|
#endif // PlatformLogEvent_h
|
||||||
|
|
80
src/jdk.incubator.jpackage/windows/native/common/WinDll.cpp
Normal file
80
src/jdk.incubator.jpackage/windows/native/common/WinDll.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Dll.h"
|
||||||
|
#include "SysInfo.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
#include "WinSysInfo.h"
|
||||||
|
#include "WinErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Dll::Handle loadLibrary(const std::wstring& path) {
|
||||||
|
HMODULE h = LoadLibraryW(path.c_str());
|
||||||
|
if (!h) {
|
||||||
|
JP_THROW(SysError(tstrings::any() << "LoadLibraryW(" <<
|
||||||
|
path << ") failed", LoadLibraryW));
|
||||||
|
}
|
||||||
|
return Dll::Handle(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namesace
|
||||||
|
|
||||||
|
Dll::Dll(const tstrings::any &libPath): thePath(libPath.tstr()),
|
||||||
|
handle(loadLibrary(libPath.wstr())) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Dll::Dll(const tstrings::any &libName, const System &tag):
|
||||||
|
thePath(FileUtils::combinePath(SysInfo::getSystem32Dir(),
|
||||||
|
libName.tstr())),
|
||||||
|
handle(loadLibrary(tstrings::any(thePath).wstr())) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Dll::Dll(const Dll& other): thePath(other.thePath) {
|
||||||
|
HMODULE h = NULL;
|
||||||
|
if (!GetModuleHandleExW(0, thePath.c_str(), &h)) {
|
||||||
|
JP_THROW(SysError(tstrings::any() << "GetModuleHandleExW("
|
||||||
|
<< thePath << ") failed", GetModuleHandleExW));
|
||||||
|
}
|
||||||
|
handle = Handle(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Dll::getFunction(const std::string &name, bool throwIfNotFound) const {
|
||||||
|
void *ptr = GetProcAddress(handle.get(), name.c_str());
|
||||||
|
if (throwIfNotFound && ptr == NULL) {
|
||||||
|
JP_THROW(SysError(tstrings::any() << "GetProcAddress(" << thePath
|
||||||
|
<< ", " << name << ") failed", GetProcAddress));
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
void Dll::freeLibrary(HMODULE h) {
|
||||||
|
if (h) {
|
||||||
|
FreeLibrary(h);
|
||||||
|
}
|
||||||
|
}
|
@ -105,7 +105,6 @@ std::wstring getSystemMessageDescription(DWORD messageId, HMODULE moduleHandle)
|
|||||||
|
|
||||||
SysError::SysError(const tstrings::any& msg, const void* caller, DWORD ec,
|
SysError::SysError(const tstrings::any& msg, const void* caller, DWORD ec,
|
||||||
const char* label):
|
const char* label):
|
||||||
|
|
||||||
std::runtime_error(makeMessage(msg.str(), label, caller, ec)) {
|
std::runtime_error(makeMessage(msg.str(), label, caller, ec)) {
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,8 +26,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <direct.h>
|
||||||
|
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
|
#include "WinFileUtils.h"
|
||||||
#include "WinErrorHandling.h"
|
#include "WinErrorHandling.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@ -40,7 +43,6 @@ namespace FileUtils {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
tstring reservedFilenameChars() {
|
tstring reservedFilenameChars() {
|
||||||
tstring buf;
|
tstring buf;
|
||||||
for (char charCode = 0; charCode < 32; ++charCode) {
|
for (char charCode = 0; charCode < 32; ++charCode) {
|
||||||
@ -52,10 +54,6 @@ tstring reservedFilenameChars() {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool isDirSeparator(const tstring::value_type c) {
|
|
||||||
return (c == '/' || c == '\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isFileExists(const tstring &filePath) {
|
bool isFileExists(const tstring &filePath) {
|
||||||
return GetFileAttributes(filePath.c_str()) != INVALID_FILE_ATTRIBUTES;
|
return GetFileAttributes(filePath.c_str()) != INVALID_FILE_ATTRIBUTES;
|
||||||
}
|
}
|
||||||
@ -78,74 +76,33 @@ bool isDirectoryNotEmpty(const tstring &dirPath) {
|
|||||||
return FALSE == PathIsDirectoryEmpty(dirPath.c_str());
|
return FALSE == PathIsDirectoryEmpty(dirPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
tstring dirname(const tstring &path) {
|
|
||||||
tstring::size_type pos = path.find_last_of(_T("\\/"));
|
|
||||||
if (pos != tstring::npos) {
|
|
||||||
pos = path.find_last_not_of(_T("\\/"), pos); // skip trailing slashes
|
|
||||||
}
|
|
||||||
return pos == tstring::npos ? tstring() : path.substr(0, pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
tstring basename(const tstring &path) {
|
tstring toAbsolutePath(const tstring& path) {
|
||||||
const tstring::size_type pos = path.find_last_of(_T("\\/"));
|
|
||||||
if (pos == tstring::npos) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
return path.substr(pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
tstring suffix(const tstring &path) {
|
|
||||||
const tstring::size_type pos = path.rfind('.');
|
|
||||||
if (pos == tstring::npos) {
|
|
||||||
return tstring();
|
|
||||||
}
|
|
||||||
const tstring::size_type dirSepPos = path.find_first_of(_T("\\/"),
|
|
||||||
pos + 1);
|
|
||||||
if (dirSepPos != tstring::npos) {
|
|
||||||
return tstring();
|
|
||||||
}
|
|
||||||
// test for '/..' and '..' cases
|
|
||||||
if (pos != 0 && path[pos - 1] == '.'
|
|
||||||
&& (pos == 1 || isDirSeparator(path[pos - 2]))) {
|
|
||||||
return tstring();
|
|
||||||
}
|
|
||||||
return path.substr(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
tstring combinePath(const tstring& parent, const tstring& child) {
|
|
||||||
if (parent.empty()) {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
if (child.empty()) {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
tstring parentWOSlash = removeTrailingSlash(parent);
|
|
||||||
// also handle the case when child contains starting slash
|
|
||||||
bool childHasSlash = isDirSeparator(child.front());
|
|
||||||
tstring childWOSlash = childHasSlash ? child.substr(1) : child;
|
|
||||||
|
|
||||||
return parentWOSlash + _T("\\") + childWOSlash;
|
|
||||||
}
|
|
||||||
|
|
||||||
tstring removeTrailingSlash(const tstring& path) {
|
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
return path;
|
TCHAR* buf = _tgetcwd(0, 1);
|
||||||
|
if (buf) {
|
||||||
|
const tstring result(buf);
|
||||||
|
free(buf);
|
||||||
|
if (result.empty()) {
|
||||||
|
JP_THROW(tstrings::any() << "_tgetcwd() returned empty string");
|
||||||
}
|
}
|
||||||
tstring::const_reverse_iterator it = path.rbegin();
|
return result;
|
||||||
tstring::const_reverse_iterator end = path.rend();
|
|
||||||
|
|
||||||
while (it != end && isDirSeparator(*it)) {
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
return path.substr(0, end - it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tstring normalizePath(tstring v) {
|
JP_THROW(tstrings::any() << "_tgetcwd() failed");
|
||||||
std::replace(v.begin(), v.end(), '/', '\\');
|
|
||||||
return tstrings::toLower(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TCHAR* buf = _tfullpath(0, path.c_str(), size_t(1));
|
||||||
|
if (buf) {
|
||||||
|
const tstring result(buf);
|
||||||
|
free(buf);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
JP_THROW(tstrings::any() << "_tfullpath(" << path << ") failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool createNewFile(const tstring& path) {
|
bool createNewFile(const tstring& path) {
|
||||||
@ -565,11 +522,6 @@ void iterateDirectory(const tstring &dirPath, DirectoryCallback& callback)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tstring replaceSuffix(const tstring& path, const tstring& newSuffix) {
|
|
||||||
return (path.substr(0, path.size() - suffix(path).size()) + newSuffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DirectoryIterator& DirectoryIterator::findItems(tstring_array& v) {
|
DirectoryIterator& DirectoryIterator::findItems(tstring_array& v) {
|
||||||
if (!isDirectory(root)) {
|
if (!isDirectory(root)) {
|
||||||
return *this;
|
return *this;
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,8 +23,8 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILEUTILS_H
|
#ifndef WINFILEUTILS_H
|
||||||
#define FILEUTILS_H
|
#define WINFILEUTILS_H
|
||||||
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -33,48 +33,6 @@
|
|||||||
|
|
||||||
namespace FileUtils {
|
namespace FileUtils {
|
||||||
|
|
||||||
// Returns 'true' if the given character is a path separator.
|
|
||||||
bool isDirSeparator(const tstring::value_type c);
|
|
||||||
|
|
||||||
// checks if the file or directory exists
|
|
||||||
bool isFileExists(const tstring &filePath);
|
|
||||||
|
|
||||||
// checks is the specified file is a directory
|
|
||||||
// returns false if the path does not exist
|
|
||||||
bool isDirectory(const tstring &filePath);
|
|
||||||
|
|
||||||
// checks if the specified directory is not empty
|
|
||||||
// returns true if the path is an existing directory and
|
|
||||||
// it contains at least one file other than "." or "..".
|
|
||||||
bool isDirectoryNotEmpty(const tstring &dirPath);
|
|
||||||
|
|
||||||
// returns directory part of the path.
|
|
||||||
// returns empty string if the path contains only filename.
|
|
||||||
// if the path ends with slash/backslash,
|
|
||||||
// returns removeTrailingSlashes(path).
|
|
||||||
tstring dirname(const tstring &path);
|
|
||||||
|
|
||||||
// returns basename part of the path
|
|
||||||
// if the path ends with slash/backslash, returns empty string.
|
|
||||||
tstring basename(const tstring &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates forward slashes to back slashes and returns lower case version
|
|
||||||
* of the given string.
|
|
||||||
*/
|
|
||||||
tstring normalizePath(tstring v);
|
|
||||||
|
|
||||||
// Returns suffix of the path. If the given path has a suffix the first
|
|
||||||
// character of the return value is '.'.
|
|
||||||
// Otherwise return value if empty string.
|
|
||||||
tstring suffix(const tstring &path);
|
|
||||||
|
|
||||||
// combines two strings into a path
|
|
||||||
tstring combinePath(const tstring& parent, const tstring& child);
|
|
||||||
|
|
||||||
// removes trailing slashes and backslashes in the path if any
|
|
||||||
tstring removeTrailingSlash(const tstring& path);
|
|
||||||
|
|
||||||
// Creates a file with unique name in the specified base directory,
|
// Creates a file with unique name in the specified base directory,
|
||||||
// throws an exception if operation fails
|
// throws an exception if operation fails
|
||||||
// path is constructed as <prefix><random number><suffix>.
|
// path is constructed as <prefix><random number><suffix>.
|
||||||
@ -166,14 +124,6 @@ namespace FileUtils {
|
|||||||
// the given directory.
|
// the given directory.
|
||||||
void iterateDirectory(const tstring &dirPath, DirectoryCallback& callback);
|
void iterateDirectory(const tstring &dirPath, DirectoryCallback& callback);
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace file suffix, example replaceSuffix("file/path.txt", ".csv")
|
|
||||||
* @param path file path to replace suffix
|
|
||||||
* @param suffix new suffix for path
|
|
||||||
* @return return file path with new suffix
|
|
||||||
*/
|
|
||||||
tstring replaceSuffix(const tstring& path, const tstring& suffix=tstring());
|
|
||||||
|
|
||||||
class DirectoryIterator: DirectoryCallback {
|
class DirectoryIterator: DirectoryCallback {
|
||||||
public:
|
public:
|
||||||
DirectoryIterator(const tstring& root=tstring()): root(root) {
|
DirectoryIterator(const tstring& root=tstring()): root(root) {
|
||||||
@ -225,34 +175,6 @@ namespace FileUtils {
|
|||||||
return DirectoryIterator(basedir).findItems();
|
return DirectoryIterator(basedir).findItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to construct path from multiple components.
|
|
||||||
//
|
|
||||||
// Sample usage:
|
|
||||||
// Construct "c:\Program Files\Java" string from three components
|
|
||||||
//
|
|
||||||
// tstring path = FileUtils::mkpath() << _T("c:")
|
|
||||||
// << _T("Program Files")
|
|
||||||
// << _T("Java");
|
|
||||||
//
|
|
||||||
class mkpath {
|
|
||||||
public:
|
|
||||||
operator const tstring& () const {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
mkpath& operator << (const tstring& p) {
|
|
||||||
path = combinePath(path, p);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mimic std::string
|
|
||||||
const tstring::value_type* c_str() const {
|
|
||||||
return path.c_str();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
tstring path;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Directory {
|
struct Directory {
|
||||||
Directory() {
|
Directory() {
|
||||||
}
|
}
|
||||||
@ -395,4 +317,4 @@ namespace FileUtils {
|
|||||||
};
|
};
|
||||||
} // FileUtils
|
} // FileUtils
|
||||||
|
|
||||||
#endif // FILEUTILS_H
|
#endif // WINFILEUTILS_H
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -97,7 +97,7 @@ tstring getModulePath(HMODULE h)
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
tstring getProcessModulePath() {
|
tstring getProcessModulePath() {
|
||||||
return getModulePath(NULL);
|
return FileUtils::toAbsolutePath(getModulePath(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
HMODULE getCurrentModuleHandle()
|
HMODULE getCurrentModuleHandle()
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <Shellapi.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#define JPACKAGE_LIBRARY TEXT("applauncher.dll")
|
|
||||||
|
|
||||||
typedef bool (*start_launcher)(int argc, TCHAR* argv[]);
|
|
||||||
typedef void (*stop_launcher)();
|
|
||||||
|
|
||||||
std::wstring GetTitle() {
|
|
||||||
std::wstring result;
|
|
||||||
wchar_t buffer[MAX_PATH];
|
|
||||||
GetModuleFileName(NULL, buffer, MAX_PATH - 1);
|
|
||||||
buffer[MAX_PATH - 1] = '\0';
|
|
||||||
result = buffer;
|
|
||||||
size_t slash = result.find_last_of('\\');
|
|
||||||
|
|
||||||
if (slash != std::wstring::npos)
|
|
||||||
result = result.substr(slash + 1, result.size() - slash - 1);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LAUNCHERC
|
|
||||||
int main(int argc0, char *argv0[]) {
|
|
||||||
#else // LAUNCHERC
|
|
||||||
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
||||||
LPTSTR lpCmdLine, int nCmdShow) {
|
|
||||||
#endif // LAUNCHERC
|
|
||||||
int result = 1;
|
|
||||||
TCHAR **argv;
|
|
||||||
int argc;
|
|
||||||
|
|
||||||
// [RT-31061] otherwise UI can be left in back of other windows.
|
|
||||||
::AllowSetForegroundWindow(ASFW_ANY);
|
|
||||||
|
|
||||||
::setlocale(LC_ALL, "en_US.utf8");
|
|
||||||
argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
|
||||||
|
|
||||||
HMODULE library = ::LoadLibrary(JPACKAGE_LIBRARY);
|
|
||||||
|
|
||||||
if (library == NULL) {
|
|
||||||
std::wstring title = GetTitle();
|
|
||||||
std::wstring description = std::wstring(JPACKAGE_LIBRARY)
|
|
||||||
+ std::wstring(TEXT(" not found."));
|
|
||||||
MessageBox(NULL, description.data(),
|
|
||||||
title.data(), MB_ICONERROR | MB_OK);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
start_launcher start =
|
|
||||||
(start_launcher)GetProcAddress(library, "start_launcher");
|
|
||||||
stop_launcher stop =
|
|
||||||
(stop_launcher)GetProcAddress(library, "stop_launcher");
|
|
||||||
|
|
||||||
if (start != NULL && stop != NULL) {
|
|
||||||
if (start(argc, argv) == true) {
|
|
||||||
result = 0;
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::FreeLibrary(library);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argv != NULL) {
|
|
||||||
LocalFree(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FILEATTRIBUTE_H
|
|
||||||
#define FILEATTRIBUTE_H
|
|
||||||
|
|
||||||
enum FileAttribute {
|
|
||||||
faArchive = FILE_ATTRIBUTE_ARCHIVE,
|
|
||||||
faCompressed = FILE_ATTRIBUTE_COMPRESSED,
|
|
||||||
faDevice = FILE_ATTRIBUTE_DEVICE,
|
|
||||||
faDirectory = FILE_ATTRIBUTE_DIRECTORY,
|
|
||||||
faEncrypted = FILE_ATTRIBUTE_ENCRYPTED,
|
|
||||||
faHidden = FILE_ATTRIBUTE_HIDDEN,
|
|
||||||
faNormal = FILE_ATTRIBUTE_NORMAL,
|
|
||||||
faNotContentIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
|
|
||||||
faOffline = FILE_ATTRIBUTE_OFFLINE,
|
|
||||||
faSystem = FILE_ATTRIBUTE_SYSTEM,
|
|
||||||
faSymbolicLink = FILE_ATTRIBUTE_REPARSE_POINT,
|
|
||||||
faSparceFile = FILE_ATTRIBUTE_SPARSE_FILE,
|
|
||||||
faReadOnly = FILE_ATTRIBUTE_READONLY,
|
|
||||||
faTemporary = FILE_ATTRIBUTE_TEMPORARY,
|
|
||||||
faVirtual = FILE_ATTRIBUTE_VIRTUAL
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FILEATTRIBUTE_H
|
|
||||||
|
|
@ -1,468 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "FilePath.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <list>
|
|
||||||
#include <ShellAPI.h>
|
|
||||||
|
|
||||||
bool FilePath::FileExists(const TString FileName) {
|
|
||||||
bool result = false;
|
|
||||||
WIN32_FIND_DATA FindFileData;
|
|
||||||
TString fileName = FixPathForPlatform(FileName);
|
|
||||||
HANDLE handle = FindFirstFile(fileName.data(), &FindFileData);
|
|
||||||
|
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
|
||||||
if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FindClose(handle);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::DirectoryExists(const TString DirectoryName) {
|
|
||||||
bool result = false;
|
|
||||||
WIN32_FIND_DATA FindFileData;
|
|
||||||
TString directoryName = FixPathForPlatform(DirectoryName);
|
|
||||||
HANDLE handle = FindFirstFile(directoryName.data(), &FindFileData);
|
|
||||||
|
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
|
||||||
if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FindClose(handle);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetLastErrorAsString() {
|
|
||||||
// Get the error message, if any.
|
|
||||||
DWORD errorMessageID = ::GetLastError();
|
|
||||||
|
|
||||||
if (errorMessageID == 0) {
|
|
||||||
return "No error message has been recorded";
|
|
||||||
}
|
|
||||||
|
|
||||||
LPSTR messageBuffer = NULL;
|
|
||||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
||||||
| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL,
|
|
||||||
SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
|
||||||
|
|
||||||
std::string message(messageBuffer, size);
|
|
||||||
|
|
||||||
// Free the buffer.
|
|
||||||
LocalFree(messageBuffer);
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::DeleteFile(const TString FileName) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FileExists(FileName) == true) {
|
|
||||||
TString lFileName = FixPathForPlatform(FileName);
|
|
||||||
FileAttributes attributes(lFileName);
|
|
||||||
|
|
||||||
if (attributes.Contains(faReadOnly) == true) {
|
|
||||||
attributes.Remove(faReadOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ::DeleteFile(lFileName.data()) == TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::DeleteDirectory(const TString DirectoryName) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (DirectoryExists(DirectoryName) == true) {
|
|
||||||
SHFILEOPSTRUCTW fos = {0};
|
|
||||||
TString directoryName = FixPathForPlatform(DirectoryName);
|
|
||||||
DynamicBuffer<TCHAR> lDirectoryName(directoryName.size() + 2);
|
|
||||||
if (lDirectoryName.GetData() == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(lDirectoryName.GetData(), directoryName.data(),
|
|
||||||
(directoryName.size() + 2) * sizeof(TCHAR));
|
|
||||||
lDirectoryName[directoryName.size() + 1] = NULL;
|
|
||||||
// Double null terminate for SHFileOperation.
|
|
||||||
|
|
||||||
// Delete the folder and everything inside.
|
|
||||||
fos.wFunc = FO_DELETE;
|
|
||||||
fos.pFrom = lDirectoryName.GetData();
|
|
||||||
fos.fFlags = FOF_NO_UI;
|
|
||||||
result = SHFileOperation(&fos) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::IncludeTrailingSeparator(const TString value) {
|
|
||||||
TString result = value;
|
|
||||||
|
|
||||||
if (value.size() > 0) {
|
|
||||||
TString::iterator i = result.end();
|
|
||||||
i--;
|
|
||||||
|
|
||||||
if (*i != TRAILING_PATHSEPARATOR) {
|
|
||||||
result += TRAILING_PATHSEPARATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::IncludeTrailingSeparator(const char* value) {
|
|
||||||
TString lvalue = PlatformString(value).toString();
|
|
||||||
return IncludeTrailingSeparator(lvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::IncludeTrailingSeparator(const wchar_t* value) {
|
|
||||||
TString lvalue = PlatformString(value).toString();
|
|
||||||
return IncludeTrailingSeparator(lvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ExtractFilePath(TString Path) {
|
|
||||||
TString result;
|
|
||||||
size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
|
|
||||||
if (slash != TString::npos)
|
|
||||||
result = Path.substr(0, slash);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ExtractFileExt(TString Path) {
|
|
||||||
TString result;
|
|
||||||
size_t dot = Path.find_last_of('.');
|
|
||||||
|
|
||||||
if (dot != TString::npos) {
|
|
||||||
result = Path.substr(dot, Path.size() - dot);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ExtractFileName(TString Path) {
|
|
||||||
TString result;
|
|
||||||
|
|
||||||
size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
|
|
||||||
if (slash != TString::npos)
|
|
||||||
result = Path.substr(slash + 1, Path.size() - slash - 1);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::ChangeFileExt(TString Path, TString Extension) {
|
|
||||||
TString result;
|
|
||||||
size_t dot = Path.find_last_of('.');
|
|
||||||
|
|
||||||
if (dot != TString::npos) {
|
|
||||||
result = Path.substr(0, dot) + Extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.empty() == true) {
|
|
||||||
result = Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::FixPathForPlatform(TString Path) {
|
|
||||||
TString result = Path;
|
|
||||||
std::replace(result.begin(), result.end(),
|
|
||||||
BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
|
|
||||||
// The maximum path that does not require long path prefix. On Windows the
|
|
||||||
// maximum path is 260 minus 1 (NUL) but for directories it is 260 minus
|
|
||||||
// 12 minus 1 (to allow for the creation of a 8.3 file in the directory).
|
|
||||||
const int maxPath = 247;
|
|
||||||
if (result.length() > maxPath &&
|
|
||||||
result.find(_T("\\\\?\\")) == TString::npos &&
|
|
||||||
result.find(_T("\\\\?\\UNC")) == TString::npos) {
|
|
||||||
const TString prefix(_T("\\\\"));
|
|
||||||
if (!result.compare(0, prefix.size(), prefix)) {
|
|
||||||
// UNC path, converting to UNC path in long notation
|
|
||||||
result = _T("\\\\?\\UNC") + result.substr(1, result.length());
|
|
||||||
} else {
|
|
||||||
// converting to non-UNC path in long notation
|
|
||||||
result = _T("\\\\?\\") + result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::FixPathSeparatorForPlatform(TString Path) {
|
|
||||||
TString result = Path;
|
|
||||||
std::replace(result.begin(), result.end(),
|
|
||||||
BAD_PATH_SEPARATOR, PATH_SEPARATOR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FilePath::PathSeparator() {
|
|
||||||
TString result;
|
|
||||||
result = PATH_SEPARATOR;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilePath::CreateDirectory(TString Path, bool ownerOnly) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
std::list<TString> paths;
|
|
||||||
TString lpath = Path;
|
|
||||||
|
|
||||||
while (lpath.empty() == false && DirectoryExists(lpath) == false) {
|
|
||||||
paths.push_front(lpath);
|
|
||||||
lpath = ExtractFilePath(lpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::list<TString>::iterator iterator = paths.begin();
|
|
||||||
iterator != paths.end(); iterator++) {
|
|
||||||
lpath = *iterator;
|
|
||||||
|
|
||||||
if (_wmkdir(lpath.data()) == 0) {
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
|
|
||||||
FFileName = FileName;
|
|
||||||
FFollowLink = FollowLink;
|
|
||||||
ReadAttributes();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileAttributes::WriteAttributes() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
DWORD attributes = 0;
|
|
||||||
|
|
||||||
for (std::vector<FileAttribute>::const_iterator iterator =
|
|
||||||
FAttributes.begin();
|
|
||||||
iterator != FAttributes.end(); iterator++) {
|
|
||||||
switch (*iterator) {
|
|
||||||
case faArchive: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_ARCHIVE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faCompressed: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_COMPRESSED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faDevice: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_DEVICE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faDirectory: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faEncrypted: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_ENCRYPTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faHidden: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_HIDDEN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faNormal: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_NORMAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faNotContentIndexed: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faOffline: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_OFFLINE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faSystem: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_SYSTEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faSymbolicLink: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_REPARSE_POINT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faSparceFile: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_SPARSE_FILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faReadOnly: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_READONLY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faTemporary: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_TEMPORARY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case faVirtual: {
|
|
||||||
attributes = attributes & FILE_ATTRIBUTE_VIRTUAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (::SetFileAttributes(FFileName.data(), attributes) != 0) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define S_ISRUSR(m) (((m) & S_IRWXU) == S_IRUSR)
|
|
||||||
#define S_ISWUSR(m) (((m) & S_IRWXU) == S_IWUSR)
|
|
||||||
#define S_ISXUSR(m) (((m) & S_IRWXU) == S_IXUSR)
|
|
||||||
|
|
||||||
#define S_ISRGRP(m) (((m) & S_IRWXG) == S_IRGRP)
|
|
||||||
#define S_ISWGRP(m) (((m) & S_IRWXG) == S_IWGRP)
|
|
||||||
#define S_ISXGRP(m) (((m) & S_IRWXG) == S_IXGRP)
|
|
||||||
|
|
||||||
#define S_ISROTH(m) (((m) & S_IRWXO) == S_IROTH)
|
|
||||||
#define S_ISWOTH(m) (((m) & S_IRWXO) == S_IWOTH)
|
|
||||||
#define S_ISXOTH(m) (((m) & S_IRWXO) == S_IXOTH)
|
|
||||||
|
|
||||||
bool FileAttributes::ReadAttributes() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
DWORD attributes = ::GetFileAttributes(FFileName.data());
|
|
||||||
|
|
||||||
if (attributes != INVALID_FILE_ATTRIBUTES) {
|
|
||||||
result = true;
|
|
||||||
|
|
||||||
if (attributes | FILE_ATTRIBUTE_ARCHIVE) {
|
|
||||||
FAttributes.push_back(faArchive);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_COMPRESSED) {
|
|
||||||
FAttributes.push_back(faCompressed);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_DEVICE) {
|
|
||||||
FAttributes.push_back(faDevice);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_DIRECTORY) {
|
|
||||||
FAttributes.push_back(faDirectory);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_ENCRYPTED) {
|
|
||||||
FAttributes.push_back(faEncrypted);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_HIDDEN) {
|
|
||||||
FAttributes.push_back(faHidden);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_NORMAL) {
|
|
||||||
FAttributes.push_back(faNormal);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) {
|
|
||||||
FAttributes.push_back(faNotContentIndexed);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_SYSTEM) {
|
|
||||||
FAttributes.push_back(faSystem);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_OFFLINE) {
|
|
||||||
FAttributes.push_back(faOffline);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) {
|
|
||||||
FAttributes.push_back(faSymbolicLink);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) {
|
|
||||||
FAttributes.push_back(faSparceFile);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_READONLY ) {
|
|
||||||
FAttributes.push_back(faReadOnly);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_TEMPORARY) {
|
|
||||||
FAttributes.push_back(faTemporary);
|
|
||||||
}
|
|
||||||
if (attributes | FILE_ATTRIBUTE_VIRTUAL) {
|
|
||||||
FAttributes.push_back(faVirtual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileAttributes::Valid(const FileAttribute Value) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
switch (Value) {
|
|
||||||
case faHidden:
|
|
||||||
case faReadOnly: {
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileAttributes::Append(FileAttribute Value) {
|
|
||||||
if (Valid(Value) == true) {
|
|
||||||
FAttributes.push_back(Value);
|
|
||||||
WriteAttributes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileAttributes::Contains(FileAttribute Value) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
std::vector<FileAttribute>::const_iterator iterator =
|
|
||||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
|
||||||
|
|
||||||
if (iterator != FAttributes.end()) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileAttributes::Remove(FileAttribute Value) {
|
|
||||||
if (Valid(Value) == true) {
|
|
||||||
std::vector<FileAttribute>::iterator iterator =
|
|
||||||
std::find(FAttributes.begin(), FAttributes.end(), Value);
|
|
||||||
|
|
||||||
if (iterator != FAttributes.end()) {
|
|
||||||
FAttributes.erase(iterator);
|
|
||||||
WriteAttributes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,765 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
#include "JavaVirtualMachine.h"
|
|
||||||
#include "WindowsPlatform.h"
|
|
||||||
#include "Package.h"
|
|
||||||
#include "Helpers.h"
|
|
||||||
#include "PlatformString.h"
|
|
||||||
#include "Macros.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <regex>
|
|
||||||
#include <fstream>
|
|
||||||
#include <locale>
|
|
||||||
#include <codecvt>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#define WINDOWS_JPACKAGE_TMP_DIR \
|
|
||||||
L"\\AppData\\Local\\Java\\JPackage\\tmp"
|
|
||||||
|
|
||||||
class Registry {
|
|
||||||
private:
|
|
||||||
HKEY FKey;
|
|
||||||
HKEY FOpenKey;
|
|
||||||
bool FOpen;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Registry(HKEY Key) {
|
|
||||||
FOpen = false;
|
|
||||||
FKey = Key;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Registry() {
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Close() {
|
|
||||||
if (FOpen == true) {
|
|
||||||
RegCloseKey(FOpenKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Open(TString SubKey) {
|
|
||||||
bool result = false;
|
|
||||||
Close();
|
|
||||||
|
|
||||||
if (RegOpenKeyEx(FKey, SubKey.data(), 0, KEY_READ, &FOpenKey) ==
|
|
||||||
ERROR_SUCCESS) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> GetKeys() {
|
|
||||||
std::list<TString> result;
|
|
||||||
DWORD count;
|
|
||||||
|
|
||||||
if (RegQueryInfoKey(FOpenKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
&count, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
|
|
||||||
|
|
||||||
DWORD length = 255;
|
|
||||||
DynamicBuffer<TCHAR> buffer(length);
|
|
||||||
if (buffer.GetData() == NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int index = 0; index < count; index++) {
|
|
||||||
buffer.Zero();
|
|
||||||
DWORD status = RegEnumValue(FOpenKey, index, buffer.GetData(),
|
|
||||||
&length, NULL, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
while (status == ERROR_MORE_DATA) {
|
|
||||||
length = length * 2;
|
|
||||||
if (!buffer.Resize(length)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
status = RegEnumValue(FOpenKey, index, buffer.GetData(),
|
|
||||||
&length, NULL, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == ERROR_SUCCESS) {
|
|
||||||
TString value = buffer.GetData();
|
|
||||||
result.push_back(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString ReadString(TString Name) {
|
|
||||||
TString result;
|
|
||||||
DWORD length;
|
|
||||||
DWORD dwRet;
|
|
||||||
DynamicBuffer<wchar_t> buffer(0);
|
|
||||||
length = 0;
|
|
||||||
|
|
||||||
dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL, NULL,
|
|
||||||
&length);
|
|
||||||
if (dwRet == ERROR_MORE_DATA || dwRet == 0) {
|
|
||||||
if (!buffer.Resize(length + 1)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL,
|
|
||||||
(LPBYTE) buffer.GetData(), &length);
|
|
||||||
result = buffer.GetData();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
WindowsPlatform::WindowsPlatform(void) : Platform() {
|
|
||||||
FMainThread = ::GetCurrentThreadId();
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowsPlatform::~WindowsPlatform(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetPackageAppDirectory() {
|
|
||||||
return FilePath::IncludeTrailingSeparator(
|
|
||||||
GetPackageRootDirectory()) + _T("app");
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetPackageLauncherDirectory() {
|
|
||||||
return GetPackageRootDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetPackageRuntimeBinDirectory() {
|
|
||||||
return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime\\bin");
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR* WindowsPlatform::ConvertStringToFileSystemString(TCHAR* Source,
|
|
||||||
bool &release) {
|
|
||||||
// Not Implemented.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR* WindowsPlatform::ConvertFileSystemStringToString(TCHAR* Source,
|
|
||||||
bool &release) {
|
|
||||||
// Not Implemented.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetPackageRootDirectory() {
|
|
||||||
TString result;
|
|
||||||
TString filename = GetModuleFileName();
|
|
||||||
return FilePath::ExtractFilePath(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetAppDataDirectory() {
|
|
||||||
TString result;
|
|
||||||
TCHAR path[MAX_PATH];
|
|
||||||
|
|
||||||
if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path) == S_OK) {
|
|
||||||
result = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetAppName() {
|
|
||||||
TString result = GetModuleFileName();
|
|
||||||
result = FilePath::ExtractFileName(result);
|
|
||||||
result = FilePath::ChangeFileExt(result, _T(""));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsPlatform::ShowMessage(TString title, TString description) {
|
|
||||||
MessageBox(NULL, description.data(),
|
|
||||||
!title.empty() ? title.data() : description.data(),
|
|
||||||
MB_ICONERROR | MB_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsPlatform::ShowMessage(TString description) {
|
|
||||||
TString appname = GetModuleFileName();
|
|
||||||
appname = FilePath::ExtractFileName(appname);
|
|
||||||
MessageBox(NULL, description.data(), appname.data(), MB_ICONERROR | MB_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageResponse WindowsPlatform::ShowResponseMessage(TString title,
|
|
||||||
TString description) {
|
|
||||||
MessageResponse result = mrCancel;
|
|
||||||
|
|
||||||
if (::MessageBox(NULL, description.data(), title.data(), MB_OKCANCEL) ==
|
|
||||||
IDOK) {
|
|
||||||
result = mrOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetBundledJavaLibraryFileName(TString RuntimePath) {
|
|
||||||
TString result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
|
||||||
_T("jre\\bin\\jli.dll");
|
|
||||||
|
|
||||||
if (FilePath::FileExists(result) == false) {
|
|
||||||
result = FilePath::IncludeTrailingSeparator(RuntimePath) +
|
|
||||||
_T("bin\\jli.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISectionalPropertyContainer* WindowsPlatform::GetConfigFile(TString FileName) {
|
|
||||||
IniFile *result = new IniFile();
|
|
||||||
if (result == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result->LoadFromFile(FileName);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetModuleFileName() {
|
|
||||||
TString result;
|
|
||||||
DynamicBuffer<wchar_t> buffer(MAX_PATH);
|
|
||||||
if (buffer.GetData() == NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
::GetModuleFileName(NULL, buffer.GetData(),
|
|
||||||
static_cast<DWORD> (buffer.GetSize()));
|
|
||||||
|
|
||||||
while (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
|
|
||||||
if (!buffer.Resize(buffer.GetSize() * 2)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
::GetModuleFileName(NULL, buffer.GetData(),
|
|
||||||
static_cast<DWORD> (buffer.GetSize()));
|
|
||||||
}
|
|
||||||
|
|
||||||
result = buffer.GetData();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Module WindowsPlatform::LoadLibrary(TString FileName) {
|
|
||||||
return ::LoadLibrary(FileName.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsPlatform::FreeLibrary(Module AModule) {
|
|
||||||
::FreeLibrary((HMODULE) AModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
Procedure WindowsPlatform::GetProcAddress(Module AModule,
|
|
||||||
std::string MethodName) {
|
|
||||||
return ::GetProcAddress((HMODULE) AModule, MethodName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsPlatform::IsMainThread() {
|
|
||||||
bool result = (FMainThread == ::GetCurrentThreadId());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString WindowsPlatform::GetTempDirectory() {
|
|
||||||
TString result;
|
|
||||||
PWSTR userDir = 0;
|
|
||||||
|
|
||||||
if (SUCCEEDED(SHGetKnownFolderPath(
|
|
||||||
FOLDERID_Profile,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&userDir))) {
|
|
||||||
result = userDir;
|
|
||||||
result += WINDOWS_JPACKAGE_TMP_DIR;
|
|
||||||
CoTaskMemFree(userDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL CALLBACK enumWindows(HWND winHandle, LPARAM lParam) {
|
|
||||||
DWORD pid = (DWORD) lParam, wPid = 0;
|
|
||||||
GetWindowThreadProcessId(winHandle, &wPid);
|
|
||||||
if (pid == wPid) {
|
|
||||||
SetForegroundWindow(winHandle);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TPlatformNumber WindowsPlatform::GetMemorySize() {
|
|
||||||
SYSTEM_INFO si;
|
|
||||||
GetSystemInfo(&si);
|
|
||||||
size_t result = (size_t) si.lpMaximumApplicationAddress;
|
|
||||||
result = result / 1048576; // Convert from bytes to megabytes.
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> FilterList(std::vector<TString> &Items,
|
|
||||||
std::wregex Pattern) {
|
|
||||||
std::vector<TString> result;
|
|
||||||
|
|
||||||
for (std::vector<TString>::iterator it = Items.begin();
|
|
||||||
it != Items.end(); ++it) {
|
|
||||||
TString item = *it;
|
|
||||||
std::wsmatch match;
|
|
||||||
|
|
||||||
if (std::regex_search(item, match, Pattern)) {
|
|
||||||
result.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Process* WindowsPlatform::CreateProcess() {
|
|
||||||
return new WindowsProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsPlatform::InitStreamLocale(wios *stream) {
|
|
||||||
const std::locale empty_locale = std::locale::empty();
|
|
||||||
const std::locale utf8_locale =
|
|
||||||
std::locale(empty_locale, new std::codecvt_utf8<wchar_t>());
|
|
||||||
stream->imbue(utf8_locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) {
|
|
||||||
if (pJavaLibrary == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FilePath::FileExists(_T("msvcr100.dll")) == true) {
|
|
||||||
pJavaLibrary->AddDependency(_T("msvcr100.dll"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TString runtimeBin = GetPackageRuntimeBinDirectory();
|
|
||||||
SetDllDirectory(runtimeBin.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Platform::CopyString(char *Destination,
|
|
||||||
size_t NumberOfElements, const char *Source) {
|
|
||||||
strcpy_s(Destination, NumberOfElements, Source);
|
|
||||||
|
|
||||||
if (NumberOfElements > 0) {
|
|
||||||
Destination[NumberOfElements - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Platform::CopyString(wchar_t *Destination,
|
|
||||||
size_t NumberOfElements, const wchar_t *Source) {
|
|
||||||
wcscpy_s(Destination, NumberOfElements, Source);
|
|
||||||
|
|
||||||
if (NumberOfElements > 0) {
|
|
||||||
Destination[NumberOfElements - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owner must free the return value.
|
|
||||||
MultibyteString Platform::WideStringToMultibyteString(
|
|
||||||
const wchar_t* value) {
|
|
||||||
MultibyteString result;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (value == NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = WideCharToMultiByte(CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL);
|
|
||||||
|
|
||||||
if (count > 0) {
|
|
||||||
result.data = new char[count + 1];
|
|
||||||
result.length = WideCharToMultiByte(CP_UTF8, 0, value, -1,
|
|
||||||
result.data, (int)count, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Owner must free the return value.
|
|
||||||
WideString Platform::MultibyteStringToWideString(const char* value) {
|
|
||||||
WideString result;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (value == NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
|
|
||||||
value, -1, NULL, 0);
|
|
||||||
|
|
||||||
if (count > 0) {
|
|
||||||
result.data = new wchar_t[count];
|
|
||||||
result.length = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
|
|
||||||
value, -1, result.data, (int)count);
|
|
||||||
if (result.length == 0) {
|
|
||||||
delete[] result.data;
|
|
||||||
result.data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileHandle::FileHandle(std::wstring FileName) {
|
|
||||||
FHandle = ::CreateFile(FileName.data(), GENERIC_READ, FILE_SHARE_READ,
|
|
||||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileHandle::~FileHandle() {
|
|
||||||
if (IsValid() == true) {
|
|
||||||
::CloseHandle(FHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileHandle::IsValid() {
|
|
||||||
return FHandle != INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE FileHandle::GetHandle() {
|
|
||||||
return FHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileMappingHandle::FileMappingHandle(HANDLE FileHandle) {
|
|
||||||
FHandle = ::CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileMappingHandle::IsValid() {
|
|
||||||
return FHandle != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileMappingHandle::~FileMappingHandle() {
|
|
||||||
if (IsValid() == true) {
|
|
||||||
::CloseHandle(FHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE FileMappingHandle::GetHandle() {
|
|
||||||
return FHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileData::FileData(HANDLE Handle) {
|
|
||||||
FBaseAddress = ::MapViewOfFile(Handle, FILE_MAP_READ, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileData::~FileData() {
|
|
||||||
if (IsValid() == true) {
|
|
||||||
::UnmapViewOfFile(FBaseAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileData::IsValid() {
|
|
||||||
return FBaseAddress != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPVOID FileData::GetBaseAddress() {
|
|
||||||
return FBaseAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowsLibrary::WindowsLibrary(std::wstring FileName) {
|
|
||||||
FFileName = FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> WindowsLibrary::GetImports() {
|
|
||||||
std::vector<TString> result;
|
|
||||||
FileHandle library(FFileName);
|
|
||||||
|
|
||||||
if (library.IsValid() == true) {
|
|
||||||
FileMappingHandle mapping(library.GetHandle());
|
|
||||||
|
|
||||||
if (mapping.IsValid() == true) {
|
|
||||||
FileData fileData(mapping.GetHandle());
|
|
||||||
|
|
||||||
if (fileData.IsValid() == true) {
|
|
||||||
PIMAGE_DOS_HEADER dosHeader =
|
|
||||||
(PIMAGE_DOS_HEADER) fileData.GetBaseAddress();
|
|
||||||
PIMAGE_FILE_HEADER pImgFileHdr =
|
|
||||||
(PIMAGE_FILE_HEADER) fileData.GetBaseAddress();
|
|
||||||
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
|
|
||||||
result = DumpPEFile(dosHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given an RVA, look up the section header that encloses it and return a
|
|
||||||
// pointer to its IMAGE_SECTION_HEADER
|
|
||||||
|
|
||||||
PIMAGE_SECTION_HEADER WindowsLibrary::GetEnclosingSectionHeader(DWORD rva,
|
|
||||||
PIMAGE_NT_HEADERS pNTHeader) {
|
|
||||||
PIMAGE_SECTION_HEADER result = 0;
|
|
||||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
|
|
||||||
|
|
||||||
for (unsigned index = 0; index < pNTHeader->FileHeader.NumberOfSections;
|
|
||||||
index++, section++) {
|
|
||||||
// Is the RVA is within this section?
|
|
||||||
if ((rva >= section->VirtualAddress) &&
|
|
||||||
(rva < (section->VirtualAddress + section->Misc.VirtualSize))) {
|
|
||||||
result = section;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPVOID WindowsLibrary::GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader,
|
|
||||||
DWORD imageBase) {
|
|
||||||
LPVOID result = 0;
|
|
||||||
PIMAGE_SECTION_HEADER pSectionHdr = GetEnclosingSectionHeader(rva,
|
|
||||||
pNTHeader);
|
|
||||||
|
|
||||||
if (pSectionHdr != NULL) {
|
|
||||||
INT delta = (INT) (
|
|
||||||
pSectionHdr->VirtualAddress - pSectionHdr->PointerToRawData);
|
|
||||||
DWORD_PTR dwp = (DWORD_PTR) (imageBase + rva - delta);
|
|
||||||
result = reinterpret_cast<LPVOID> (dwp); // VS2017 - FIXME
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> WindowsLibrary::GetImportsSection(DWORD base,
|
|
||||||
PIMAGE_NT_HEADERS pNTHeader) {
|
|
||||||
std::vector<TString> result;
|
|
||||||
|
|
||||||
// Look up where the imports section is located. Normally in
|
|
||||||
// the .idata section,
|
|
||||||
// but not necessarily so. Therefore, grab the RVA from the data dir.
|
|
||||||
DWORD importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[
|
|
||||||
IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
|
||||||
|
|
||||||
if (importsStartRVA != NULL) {
|
|
||||||
// Get the IMAGE_SECTION_HEADER that contains the imports. This is
|
|
||||||
// usually the .idata section, but doesn't have to be.
|
|
||||||
PIMAGE_SECTION_HEADER pSection =
|
|
||||||
GetEnclosingSectionHeader(importsStartRVA, pNTHeader);
|
|
||||||
|
|
||||||
if (pSection != NULL) {
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR importDesc =
|
|
||||||
(PIMAGE_IMPORT_DESCRIPTOR) GetPtrFromRVA(
|
|
||||||
importsStartRVA, pNTHeader, base);
|
|
||||||
|
|
||||||
if (importDesc != NULL) {
|
|
||||||
while (true) {
|
|
||||||
// See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR
|
|
||||||
if ((importDesc->TimeDateStamp == 0) &&
|
|
||||||
(importDesc->Name == 0)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string filename = (char*) GetPtrFromRVA(
|
|
||||||
importDesc->Name, pNTHeader, base);
|
|
||||||
result.push_back(PlatformString(filename));
|
|
||||||
importDesc++; // advance to next IMAGE_IMPORT_DESCRIPTOR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TString> WindowsLibrary::DumpPEFile(PIMAGE_DOS_HEADER dosHeader) {
|
|
||||||
std::vector<TString> result;
|
|
||||||
// all of this is VS2017 - FIXME
|
|
||||||
DWORD_PTR dwDosHeaders = reinterpret_cast<DWORD_PTR> (dosHeader);
|
|
||||||
DWORD_PTR dwPIHeaders = dwDosHeaders + (DWORD) (dosHeader->e_lfanew);
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNTHeader =
|
|
||||||
reinterpret_cast<PIMAGE_NT_HEADERS> (dwPIHeaders);
|
|
||||||
|
|
||||||
// Verify that the e_lfanew field gave us a reasonable
|
|
||||||
// pointer and the PE signature.
|
|
||||||
// TODO: To really fix JDK-8131321 this condition needs to be changed.
|
|
||||||
// There is a matching change
|
|
||||||
// in JavaVirtualMachine.cpp that also needs to be changed.
|
|
||||||
if (pNTHeader->Signature == IMAGE_NT_SIGNATURE) {
|
|
||||||
DWORD base = (DWORD) (dwDosHeaders);
|
|
||||||
result = GetImportsSection(base, pNTHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <TlHelp32.h>
|
|
||||||
|
|
||||||
WindowsJob::WindowsJob() {
|
|
||||||
FHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowsJob::~WindowsJob() {
|
|
||||||
if (FHandle != NULL) {
|
|
||||||
CloseHandle(FHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE WindowsJob::GetHandle() {
|
|
||||||
if (FHandle == NULL) {
|
|
||||||
FHandle = CreateJobObject(NULL, NULL); // GLOBAL
|
|
||||||
|
|
||||||
if (FHandle == NULL) {
|
|
||||||
::MessageBox(0, _T("Could not create job object"),
|
|
||||||
_T("TEST"), MB_OK);
|
|
||||||
} else {
|
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};
|
|
||||||
|
|
||||||
// Configure all child processes associated with
|
|
||||||
// the job to terminate when the
|
|
||||||
jeli.BasicLimitInformation.LimitFlags =
|
|
||||||
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
|
||||||
if (0 == SetInformationJobObject(FHandle,
|
|
||||||
JobObjectExtendedLimitInformation, &jeli, sizeof (jeli))) {
|
|
||||||
::MessageBox(0, _T("Could not SetInformationJobObject"),
|
|
||||||
_T("TEST"), MB_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize static member of WindowsProcess
|
|
||||||
WindowsJob WindowsProcess::FJob;
|
|
||||||
|
|
||||||
WindowsProcess::WindowsProcess() : Process() {
|
|
||||||
FRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowsProcess::~WindowsProcess() {
|
|
||||||
Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsProcess::Cleanup() {
|
|
||||||
CloseHandle(FProcessInfo.hProcess);
|
|
||||||
CloseHandle(FProcessInfo.hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsProcess::IsRunning() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
|
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PROCESSENTRY32 process = {0};
|
|
||||||
process.dwSize = sizeof (process);
|
|
||||||
|
|
||||||
if (::Process32First(handle, &process)) {
|
|
||||||
do {
|
|
||||||
if (process.th32ProcessID == FProcessInfo.dwProcessId) {
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (::Process32Next(handle, &process));
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(handle);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsProcess::Terminate() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (IsRunning() == true && FRunning == true) {
|
|
||||||
FRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsProcess::Execute(const TString Application,
|
|
||||||
const std::vector<TString> Arguments, bool AWait) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (FRunning == false) {
|
|
||||||
FRunning = true;
|
|
||||||
|
|
||||||
STARTUPINFO startupInfo;
|
|
||||||
ZeroMemory(&startupInfo, sizeof (startupInfo));
|
|
||||||
startupInfo.cb = sizeof (startupInfo);
|
|
||||||
ZeroMemory(&FProcessInfo, sizeof (FProcessInfo));
|
|
||||||
|
|
||||||
TString command = Application;
|
|
||||||
|
|
||||||
for (std::vector<TString>::const_iterator iterator = Arguments.begin();
|
|
||||||
iterator != Arguments.end(); iterator++) {
|
|
||||||
command += TString(_T(" ")) + *iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (::CreateProcess(Application.data(), (wchar_t*)command.data(), NULL,
|
|
||||||
NULL, FALSE, 0, NULL, NULL, &startupInfo, &FProcessInfo)
|
|
||||||
== FALSE) {
|
|
||||||
TString message = PlatformString::Format(
|
|
||||||
_T("Error: Unable to create process %s"),
|
|
||||||
Application.data());
|
|
||||||
throw Exception(message);
|
|
||||||
} else {
|
|
||||||
if (FJob.GetHandle() != NULL) {
|
|
||||||
if (::AssignProcessToJobObject(FJob.GetHandle(),
|
|
||||||
FProcessInfo.hProcess) == 0) {
|
|
||||||
// Failed to assign process to job. It doesn't prevent
|
|
||||||
// anything from continuing so continue.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait until child process exits.
|
|
||||||
if (AWait == true) {
|
|
||||||
Wait();
|
|
||||||
// Close process and thread handles.
|
|
||||||
Cleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsProcess::Wait() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
WaitForSingleObject(FProcessInfo.hProcess, INFINITE);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TProcessID WindowsProcess::GetProcessID() {
|
|
||||||
return FProcessInfo.dwProcessId;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsProcess::ReadOutput() {
|
|
||||||
bool result = false;
|
|
||||||
// TODO implement
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsProcess::SetInput(TString Value) {
|
|
||||||
// TODO implement
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<TString> WindowsProcess::GetOutput() {
|
|
||||||
ReadOutput();
|
|
||||||
return Process::GetOutput();
|
|
||||||
}
|
|
@ -1,171 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WINDOWSPLATFORM_H
|
|
||||||
#define WINDOWSPLATFORM_H
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
#include "Platform.h"
|
|
||||||
|
|
||||||
class WindowsPlatform : virtual public Platform {
|
|
||||||
private:
|
|
||||||
DWORD FMainThread;
|
|
||||||
|
|
||||||
public:
|
|
||||||
WindowsPlatform(void);
|
|
||||||
virtual ~WindowsPlatform(void);
|
|
||||||
|
|
||||||
virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source,
|
|
||||||
bool &release);
|
|
||||||
virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source,
|
|
||||||
bool &release);
|
|
||||||
|
|
||||||
virtual void ShowMessage(TString title, TString description);
|
|
||||||
virtual void ShowMessage(TString description);
|
|
||||||
virtual MessageResponse ShowResponseMessage(TString title,
|
|
||||||
TString description);
|
|
||||||
|
|
||||||
virtual TString GetPackageRootDirectory();
|
|
||||||
virtual TString GetAppDataDirectory();
|
|
||||||
virtual TString GetAppName();
|
|
||||||
virtual TString GetBundledJavaLibraryFileName(TString RuntimePath);
|
|
||||||
TString GetPackageAppDirectory();
|
|
||||||
TString GetPackageLauncherDirectory();
|
|
||||||
TString GetPackageRuntimeBinDirectory();
|
|
||||||
|
|
||||||
virtual ISectionalPropertyContainer* GetConfigFile(TString FileName);
|
|
||||||
|
|
||||||
virtual TString GetModuleFileName();
|
|
||||||
virtual Module LoadLibrary(TString FileName);
|
|
||||||
virtual void FreeLibrary(Module AModule);
|
|
||||||
virtual Procedure GetProcAddress(Module AModule, std::string MethodName);
|
|
||||||
|
|
||||||
virtual Process* CreateProcess();
|
|
||||||
|
|
||||||
virtual bool IsMainThread();
|
|
||||||
virtual TPlatformNumber GetMemorySize();
|
|
||||||
|
|
||||||
virtual TString GetTempDirectory();
|
|
||||||
void InitStreamLocale(wios *stream);
|
|
||||||
void addPlatformDependencies(JavaLibrary *pJavaLibrary);
|
|
||||||
};
|
|
||||||
|
|
||||||
class FileHandle {
|
|
||||||
private:
|
|
||||||
HANDLE FHandle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileHandle(std::wstring FileName);
|
|
||||||
~FileHandle();
|
|
||||||
|
|
||||||
bool IsValid();
|
|
||||||
HANDLE GetHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FileMappingHandle {
|
|
||||||
private:
|
|
||||||
HANDLE FHandle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileMappingHandle(HANDLE FileHandle);
|
|
||||||
~FileMappingHandle();
|
|
||||||
|
|
||||||
bool IsValid();
|
|
||||||
HANDLE GetHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FileData {
|
|
||||||
private:
|
|
||||||
LPVOID FBaseAddress;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileData(HANDLE Handle);
|
|
||||||
~FileData();
|
|
||||||
|
|
||||||
bool IsValid();
|
|
||||||
LPVOID GetBaseAddress();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class WindowsLibrary {
|
|
||||||
private:
|
|
||||||
TString FFileName;
|
|
||||||
|
|
||||||
// Given an RVA, look up the section header that encloses it and return a
|
|
||||||
// pointer to its IMAGE_SECTION_HEADER
|
|
||||||
static PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva,
|
|
||||||
PIMAGE_NT_HEADERS pNTHeader);
|
|
||||||
static LPVOID GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader,
|
|
||||||
DWORD imageBase);
|
|
||||||
static std::vector<TString> GetImportsSection(DWORD base,
|
|
||||||
PIMAGE_NT_HEADERS pNTHeader);
|
|
||||||
static std::vector<TString> DumpPEFile(PIMAGE_DOS_HEADER dosHeader);
|
|
||||||
|
|
||||||
public:
|
|
||||||
WindowsLibrary(const TString FileName);
|
|
||||||
|
|
||||||
std::vector<TString> GetImports();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class WindowsJob {
|
|
||||||
private:
|
|
||||||
HANDLE FHandle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
WindowsJob();
|
|
||||||
~WindowsJob();
|
|
||||||
|
|
||||||
HANDLE GetHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class WindowsProcess : public Process {
|
|
||||||
private:
|
|
||||||
bool FRunning;
|
|
||||||
|
|
||||||
PROCESS_INFORMATION FProcessInfo;
|
|
||||||
static WindowsJob FJob;
|
|
||||||
|
|
||||||
void Cleanup();
|
|
||||||
bool ReadOutput();
|
|
||||||
|
|
||||||
public:
|
|
||||||
WindowsProcess();
|
|
||||||
virtual ~WindowsProcess();
|
|
||||||
|
|
||||||
virtual bool IsRunning();
|
|
||||||
virtual bool Terminate();
|
|
||||||
virtual bool Execute(const TString Application,
|
|
||||||
const std::vector<TString> Arguments, bool AWait = false);
|
|
||||||
virtual bool Wait();
|
|
||||||
virtual TProcessID GetProcessID();
|
|
||||||
virtual void SetInput(TString Value);
|
|
||||||
virtual std::list<TString> GetOutput();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WINDOWSPLATFORM_H
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#pragma comment(lib, "advapi32")
|
||||||
|
|
||||||
// Max value name size per MSDN plus NULL
|
// Max value name size per MSDN plus NULL
|
||||||
#define VALUE_NAME_SIZE 16384
|
#define VALUE_NAME_SIZE 16384
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -105,11 +105,6 @@ extern "C" {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
|
|
||||||
LPVOID lpvReserved) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "SysInfo.h"
|
#include "SysInfo.h"
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
|
#include "WinFileUtils.h"
|
||||||
#include "Executor.h"
|
#include "Executor.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
#include "WinErrorHandling.h"
|
#include "WinErrorHandling.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
|
#include "WinFileUtils.h"
|
||||||
#include "WinErrorHandling.h"
|
#include "WinErrorHandling.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,6 +22,7 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdk.jpackage.test;
|
package jdk.jpackage.test;
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -733,10 +736,10 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
|
|||||||
|
|
||||||
return args.stream().map(v -> {
|
return args.stream().map(v -> {
|
||||||
String str = v;
|
String str = v;
|
||||||
// Escape quotes.
|
|
||||||
str = str.replace("\"", "\\\"");
|
|
||||||
// Escape backslashes.
|
// Escape backslashes.
|
||||||
str = str.replace("\\", "\\\\");
|
str = str.replace("\\", "\\\\");
|
||||||
|
// Escape quotes.
|
||||||
|
str = str.replace("\"", "\\\"");
|
||||||
// If value contains whitespace characters, put the value in quotes
|
// If value contains whitespace characters, put the value in quotes
|
||||||
if (whitespaceRegexp.matcher(str).find()) {
|
if (whitespaceRegexp.matcher(str).find()) {
|
||||||
str = "\"" + str + "\"";
|
str = "\"" + str + "\"";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -82,7 +82,6 @@ public class ApplicationLayoutTest {
|
|||||||
assertTrue(Files.isDirectory(layout.appModsDirectory()));
|
assertTrue(Files.isDirectory(layout.appModsDirectory()));
|
||||||
assertTrue(Files.isRegularFile(layout.launchersDirectory().resolve("Foo")));
|
assertTrue(Files.isRegularFile(layout.launchersDirectory().resolve("Foo")));
|
||||||
assertTrue(Files.isRegularFile(layout.destktopIntegrationDirectory().resolve("Foo.png")));
|
assertTrue(Files.isRegularFile(layout.destktopIntegrationDirectory().resolve("Foo.png")));
|
||||||
assertTrue(Files.isRegularFile(layout.dllDirectory().resolve("libapplauncher.so")));
|
|
||||||
assertTrue(Files.isRegularFile(layout.runtimeDirectory().resolve("bin/java")));
|
assertTrue(Files.isRegularFile(layout.runtimeDirectory().resolve("bin/java")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jdk.jpackage.tests;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import jdk.jpackage.test.Annotations.Test;
|
||||||
|
import jdk.jpackage.test.Annotations.Parameter;
|
||||||
|
import jdk.jpackage.test.HelloApp;
|
||||||
|
import jdk.jpackage.test.JavaAppDesc;
|
||||||
|
import jdk.jpackage.test.JPackageCommand;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary jpackage application packed in multiple jars
|
||||||
|
* @library ../../../../helpers
|
||||||
|
* @build jdk.jpackage.test.*
|
||||||
|
* @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal
|
||||||
|
* @compile MultipleJarAppTest.java
|
||||||
|
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||||
|
* --jpt-run=jdk.jpackage.tests.MultipleJarAppTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class MultipleJarAppTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Parameter("B")
|
||||||
|
@Parameter("C")
|
||||||
|
public void test(String mainClass) {
|
||||||
|
JPackageCommand cmd = JPackageCommand.helloAppImage("a.jar:A");
|
||||||
|
HelloApp.createBundle(JavaAppDesc.parse("b.jar:B"), cmd.inputDir());
|
||||||
|
HelloApp.createBundle(JavaAppDesc.parse("c.jar:C"), cmd.inputDir());
|
||||||
|
|
||||||
|
cmd.setArgumentValue("--main-class", mainClass);
|
||||||
|
cmd.executeAndAssertHelloAppImageCreated();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user