Base compilation steps
This commit is contained in:
parent
5015236ff2
commit
4c297a51b6
75
compile_td.sh
Executable file
75
compile_td.sh
Executable file
@ -0,0 +1,75 @@
|
||||
#!/bin/bash -e
|
||||
# REQUIRED PARAMETERS:
|
||||
# OPERATING_SYSTEM_NAME = <windows | linux | osx>
|
||||
# CPU_ARCHITECTURE_NAME = <amd64 | aarch64>
|
||||
# IMPLEMENTATION_NAME = <tdlib | tdlight>
|
||||
# CPU_CORES = <cores>
|
||||
|
||||
# Check variables correctness
|
||||
if [ -z "${OPERATING_SYSTEM_NAME}" ]; then
|
||||
echo "Missing parameter: OPERATING_SYSTEM_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_ARCHITECTURE_NAME}" ]; then
|
||||
echo "Missing parameter: CPU_ARCHITECTURE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IMPLEMENTATION_NAME}" ]; then
|
||||
echo "Missing parameter: IMPLEMENTATION_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_CORES}" ]; then
|
||||
echo "Missing parameter: CPU_CORES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../
|
||||
|
||||
# Print details
|
||||
echo "Compiling tdjni..."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo "Operating system: ${OPERATING_SYSTEM_NAME}"
|
||||
echo "Architecture: ${CPU_ARCHITECTURE_NAME}"
|
||||
echo "Td implementation: ${IMPLEMENTATION_NAME}"
|
||||
|
||||
# Delete old data
|
||||
echo "Deleting old data..."
|
||||
[ -d ./generated/tdjni_build/ ] && rm -r ./generated/tdjni_build/
|
||||
[ -d ./generated/tdjni_bin/ ] && rm -r ./generated/tdjni_bin/
|
||||
[ -d ./generated/tdjni_docs/ ] && rm -r ./generated/tdjni_docs/
|
||||
[ -d ./generated/src/jni-cpp-src/ ] && rm -r ./generated/src/jni-cpp-src/
|
||||
[ -d ./generated/src/jni-java-src/ ] && rm -r ./generated/src/jni-java-src/
|
||||
|
||||
# Create missing folders
|
||||
echo "Creating missing folders..."
|
||||
[ -d ./generated/tdjni_build/ ] || mkdir ./generated/tdjni_build/
|
||||
[ -d ./generated/tdjni_bin/ ] || mkdir ./generated/tdjni_bin/
|
||||
[ -d ./generated/tdjni_docs/ ] || mkdir ./generated/tdjni_docs/
|
||||
|
||||
# Copy source files
|
||||
echo "Copying source files..."
|
||||
cp -r ./src/main/jni-cpp-src ./generated/src/main/jni-cpp-src
|
||||
cp -r ./src/main/jni-java-src ./generated/src/main/jni-java-src
|
||||
|
||||
# Configure cmake
|
||||
echo "Configuring CMake..."
|
||||
cd ./generated/tdjni_build/
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DTD_GENERATED_BINARIES_DIR=$(realpath ../td_tools/td/generate) \
|
||||
-DTD_SRC_DIR=$(realpath ../implementation/) \
|
||||
-DTDNATIVES_BIN_DIR=$(realpath ../tdjni_bin/) \
|
||||
-DTDNATIVES_DOCS_BIN_DIR=$(realpath ../tdjni_docs/) \
|
||||
-DTd_DIR=$(realpath ../td_bin/lib/cmake/Td/) \
|
||||
-DJAVA_SRC_DIR=$(realpath ../src/main/jni-java-src/) \
|
||||
-DTDNATIVES_CPP_SRC_DIR:PATH=$(realpath ../src/main/jni-cpp-src/) \
|
||||
-DOPENSSL_USE_STATIC_LIBS=True \
|
||||
$(realpath ../src/main/jni-cpp-src/)
|
||||
|
||||
# Build
|
||||
echo "Compiling ${IMPLEMENTATION_NAME} jni..."
|
||||
cmake --build . --target install --parallel ${CPU_CORES}
|
||||
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
@ -1 +0,0 @@
|
||||
|
59
scripts/compile_td.sh
Executable file
59
scripts/compile_td.sh
Executable file
@ -0,0 +1,59 @@
|
||||
#!/bin/bash -e
|
||||
# REQUIRED PARAMETERS:
|
||||
# OPERATING_SYSTEM_NAME = <windows | linux | osx>
|
||||
# CPU_ARCHITECTURE_NAME = <amd64 | aarch64>
|
||||
# IMPLEMENTATION_NAME = <tdlib | tdlight>
|
||||
# CPU_CORES = <cores>
|
||||
|
||||
# Check variables correctness
|
||||
if [ -z "${OPERATING_SYSTEM_NAME}" ]; then
|
||||
echo "Missing parameter: OPERATING_SYSTEM_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_ARCHITECTURE_NAME}" ]; then
|
||||
echo "Missing parameter: CPU_ARCHITECTURE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IMPLEMENTATION_NAME}" ]; then
|
||||
echo "Missing parameter: IMPLEMENTATION_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_CORES}" ]; then
|
||||
echo "Missing parameter: CPU_CORES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../
|
||||
|
||||
# Print details
|
||||
echo "Compiling td..."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo "Operating system: ${OPERATING_SYSTEM_NAME}"
|
||||
echo "Architecture: ${CPU_ARCHITECTURE_NAME}"
|
||||
echo "Td implementation: ${IMPLEMENTATION_NAME}"
|
||||
|
||||
# Delete old data
|
||||
echo "Deleting old data..."
|
||||
[ -d ./generated/td_build/ ] && rm -r ./generated/td_build/
|
||||
[ -d ./generated/td_bin/ ] && rm -r ./generated/td_bin/
|
||||
|
||||
# Create missing folders
|
||||
echo "Creating missing folders..."
|
||||
[ -d ./generated/td_build/ ] || mkdir ./generated/td_build/
|
||||
[ -d ./generated/td_bin/ ] || mkdir ./generated/td_bin/
|
||||
|
||||
# Configure cmake
|
||||
echo "Configuring CMake..."
|
||||
cd ./generated/td_build/
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=$(realpath ../td_bin/) \
|
||||
-DTD_ENABLE_JNI=ON \
|
||||
../implementation
|
||||
|
||||
# Build
|
||||
echo "Compiling ${IMPLEMENTATION_NAME} td..."
|
||||
cmake --build . --target install --parallel ${CPU_CORES}
|
||||
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
76
scripts/compile_tdjni.sh
Executable file
76
scripts/compile_tdjni.sh
Executable file
@ -0,0 +1,76 @@
|
||||
#!/bin/bash -e
|
||||
# REQUIRED PARAMETERS:
|
||||
# OPERATING_SYSTEM_NAME = <windows | linux | osx>
|
||||
# CPU_ARCHITECTURE_NAME = <amd64 | aarch64>
|
||||
# IMPLEMENTATION_NAME = <tdlib | tdlight>
|
||||
# CPU_CORES = <cores>
|
||||
|
||||
# Check variables correctness
|
||||
if [ -z "${OPERATING_SYSTEM_NAME}" ]; then
|
||||
echo "Missing parameter: OPERATING_SYSTEM_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_ARCHITECTURE_NAME}" ]; then
|
||||
echo "Missing parameter: CPU_ARCHITECTURE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IMPLEMENTATION_NAME}" ]; then
|
||||
echo "Missing parameter: IMPLEMENTATION_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_CORES}" ]; then
|
||||
echo "Missing parameter: CPU_CORES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../
|
||||
|
||||
# Print details
|
||||
echo "Compiling tdjni..."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo "Operating system: ${OPERATING_SYSTEM_NAME}"
|
||||
echo "Architecture: ${CPU_ARCHITECTURE_NAME}"
|
||||
echo "Td implementation: ${IMPLEMENTATION_NAME}"
|
||||
|
||||
# Delete old data
|
||||
echo "Deleting old data..."
|
||||
[ -d ./generated/tdjni_build/ ] && rm -r ./generated/tdjni_build/
|
||||
[ -d ./generated/tdjni_bin/ ] && rm -r ./generated/tdjni_bin/
|
||||
[ -d ./generated/tdjni_docs/ ] && rm -r ./generated/tdjni_docs/
|
||||
[ -d ./generated/src/main/jni-cpp-src/ ] && rm -r ./generated/src/main/jni-cpp-src/
|
||||
[ -d ./generated/src/main/jni-java-src/ ] && rm -r ./generated/src/main/jni-java-src/
|
||||
|
||||
# Create missing folders
|
||||
echo "Creating missing folders..."
|
||||
[ -d ./generated/tdjni_build/ ] || mkdir ./generated/tdjni_build/
|
||||
[ -d ./generated/tdjni_bin/ ] || mkdir ./generated/tdjni_bin/
|
||||
[ -d ./generated/tdjni_docs/ ] || mkdir ./generated/tdjni_docs/
|
||||
|
||||
# Copy source files
|
||||
echo "Copying source files..."
|
||||
cp -r ./src/main/jni-cpp-src ./generated/src/main/jni-cpp-src
|
||||
cp -r ./src/main/jni-java-src ./generated/src/main/jni-java-src
|
||||
cp ./generated/src/main/java/it/tdlight/jni/TdApi.java ./generated/src/main/jni-java-src/it/tdlight/jni/TdApi.java
|
||||
|
||||
# Configure cmake
|
||||
echo "Configuring CMake..."
|
||||
cd ./generated/tdjni_build/
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DTD_GENERATED_BINARIES_DIR=$(realpath ../td_tools/td/generate/) \
|
||||
-DTD_SRC_DIR=$(realpath ../implementation/) \
|
||||
-DTDNATIVES_BIN_DIR=$(realpath ../tdjni_bin/) \
|
||||
-DTDNATIVES_DOCS_BIN_DIR=$(realpath ../tdjni_docs/) \
|
||||
-DTd_DIR=$(realpath ../td_bin/lib/cmake/Td/) \
|
||||
-DJAVA_SRC_DIR=$(realpath ../src/main/jni-java-src/) \
|
||||
-DTDNATIVES_CPP_SRC_DIR:PATH=$(realpath ../src/main/jni-cpp-src/) \
|
||||
-DOPENSSL_USE_STATIC_LIBS=True \
|
||||
$(realpath ../src/main/jni-cpp-src/)
|
||||
|
||||
# Build
|
||||
echo "Compiling ${IMPLEMENTATION_NAME} jni..."
|
||||
cmake --build . --target install --parallel ${CPU_CORES}
|
||||
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
70
scripts/generate_td_tools.sh
Executable file
70
scripts/generate_td_tools.sh
Executable file
@ -0,0 +1,70 @@
|
||||
#!/bin/bash -e
|
||||
# REQUIRED PARAMETERS:
|
||||
# OPERATING_SYSTEM_NAME = <windows | linux | osx>
|
||||
# CPU_ARCHITECTURE_NAME = <amd64 | aarch64>
|
||||
# IMPLEMENTATION_NAME = <tdlib | tdlight>
|
||||
# CPU_CORES = <cores>
|
||||
|
||||
# Check variables correctness
|
||||
if [ -z "${OPERATING_SYSTEM_NAME}" ]; then
|
||||
echo "Missing parameter: OPERATING_SYSTEM_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_ARCHITECTURE_NAME}" ]; then
|
||||
echo "Missing parameter: CPU_ARCHITECTURE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IMPLEMENTATION_NAME}" ]; then
|
||||
echo "Missing parameter: IMPLEMENTATION_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_CORES}" ]; then
|
||||
echo "Missing parameter: CPU_CORES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../
|
||||
|
||||
# Print details
|
||||
echo "Generating td tools..."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo "Operating system: ${OPERATING_SYSTEM_NAME}"
|
||||
echo "Architecture: ${CPU_ARCHITECTURE_NAME}"
|
||||
echo "Td implementation: ${IMPLEMENTATION_NAME}"
|
||||
|
||||
# Delete old data
|
||||
echo "Deleting old data..."
|
||||
[ -d ./generated/implementation/ ] && rm -r ./generated/implementation/
|
||||
[ -d ./generated/td_tools/ ] && rm -r ./generated/td_tools/
|
||||
|
||||
# Copy implementation files
|
||||
echo "Copying implementation files..."
|
||||
cp -r implementations/${IMPLEMENTATION_NAME} ./generated/implementation
|
||||
|
||||
# Configure cmake
|
||||
echo "Configuring CMake..."
|
||||
mkdir ./generated/td_tools/
|
||||
cd ./generated/td_tools/
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DTD_ENABLE_JNI=ON \
|
||||
../implementation/
|
||||
|
||||
# Run cmake to generate common tools
|
||||
echo "Generating cross compilation tools..."
|
||||
cmake --build . --target prepare_cross_compiling --parallel ${CPU_CORES}
|
||||
|
||||
# Run cmake to generate java tools
|
||||
echo "Generating java tools..."
|
||||
cmake --build . --target td_generate_java_api --parallel ${CPU_CORES}
|
||||
|
||||
echo "Generated executable '$(realpath ./td/generate/generate_common)'"
|
||||
echo "Generated executable '$(realpath ./td/generate/td_generate_java_api)'"
|
||||
echo "Generated executable '$(realpath ./td/generate/td_generate_json)'"
|
||||
echo "Generated executable '$(realpath ../implementation/td/generate/JavadocTlDocumentationGenerator.php)'"
|
||||
echo "Generated executable '$(realpath ../implementation/td/generate/TlDocumentationGenerator.php)'"
|
||||
echo "Generated executable '$(realpath ../implementation/td/generate/scheme/td_api.tl)'"
|
||||
echo "Generated executable '$(realpath ../implementation/td/generate/scheme/td_api.tlo)'"
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
85
scripts/generate_tdapi_java_file.sh
Executable file
85
scripts/generate_tdapi_java_file.sh
Executable file
@ -0,0 +1,85 @@
|
||||
#!/bin/bash -e
|
||||
# REQUIRED PARAMETERS:
|
||||
# OPERATING_SYSTEM_NAME = <windows | linux | osx>
|
||||
# CPU_ARCHITECTURE_NAME = <amd64 | aarch64>
|
||||
# IMPLEMENTATION_NAME = <tdlib | tdlight>
|
||||
# CPU_CORES = <cores>
|
||||
|
||||
# Check variables correctness
|
||||
if [ -z "${OPERATING_SYSTEM_NAME}" ]; then
|
||||
echo "Missing parameter: OPERATING_SYSTEM_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_ARCHITECTURE_NAME}" ]; then
|
||||
echo "Missing parameter: CPU_ARCHITECTURE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IMPLEMENTATION_NAME}" ]; then
|
||||
echo "Missing parameter: IMPLEMENTATION_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CPU_CORES}" ]; then
|
||||
echo "Missing parameter: CPU_CORES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../
|
||||
|
||||
# Print details
|
||||
echo "Generating TdApi.java..."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo "Operating system: ${OPERATING_SYSTEM_NAME}"
|
||||
echo "Architecture: ${CPU_ARCHITECTURE_NAME}"
|
||||
echo "Td implementation: ${IMPLEMENTATION_NAME}"
|
||||
|
||||
# Delete old data
|
||||
echo "Deleting old data..."
|
||||
[ -d ./generated/tdapi_java_build/ ] && rm -r ./generated/tdapi_java_build/
|
||||
[ -d ./generated/tdjni_build/ ] && rm -r ./generated/tdjni_build/
|
||||
[ -d ./generated/tdjni_bin/ ] && rm -r ./generated/tdjni_bin/
|
||||
[ -d ./generated/tdjni_docs/ ] && rm -r ./generated/tdjni_docs/
|
||||
[ -d ./generated/src/main/jni-cpp-src/ ] && rm -r ./generated/src/main/jni-cpp-src/
|
||||
[ -d ./generated/src/main/jni-java-src/ ] && rm -r ./generated/src/main/jni-java-src/
|
||||
[ -f ./generated/src/main/java/it/tdlight/jni/TdApi.java ] && rm ./generated/src/main/java/it/tdlight/jni/TdApi.java
|
||||
|
||||
# Create missing folders
|
||||
echo "Creating missing folders..."
|
||||
[ -d ./generated/tdapi_java_build/ ] || mkdir ./generated/tdapi_java_build/
|
||||
[ -d ./generated/tdjni_build/ ] || mkdir ./generated/tdjni_build/
|
||||
[ -d ./generated/tdjni_bin/ ] || mkdir ./generated/tdjni_bin/
|
||||
[ -d ./generated/tdjni_docs/ ] || mkdir ./generated/tdjni_docs/
|
||||
|
||||
# Copy source files
|
||||
echo "Copying source files..."
|
||||
cp -r ./src/main/jni-cpp-src ./generated/src/main/jni-cpp-src
|
||||
cp -r ./src/main/jni-java-src ./generated/src/main/jni-java-src
|
||||
|
||||
# Configure cmake
|
||||
echo "Configuring CMake..."
|
||||
cd ./generated/tdapi_java_build/
|
||||
echo "Telegram source path: '$(realpath ../implementation/)'"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DTD_SRC_DIR=$(realpath ../implementation/) \
|
||||
-DTD_GENERATED_BINARIES_DIR=$(realpath ../td_tools/td/generate) \
|
||||
-DTd_DIR=$(realpath ../td_bin/lib/cmake/Td/) \
|
||||
-DTDNATIVES_BIN_DIR=$(realpath ../tdjni_bin/) \
|
||||
-DTDNATIVES_DOCS_BIN_DIR=$(realpath ../tdjni_docs/) \
|
||||
-DJAVA_SRC_DIR=$(realpath ../src/main/jni-java-src/) \
|
||||
$(realpath ../src/main/jni-cpp-src/)
|
||||
|
||||
# Run cmake to generate TdApi.java
|
||||
echo "Generating TdApi.java..."
|
||||
cmake --build . --target td_generate_java_api --config Release --parallel ${CPU_CORES}
|
||||
cd ..
|
||||
|
||||
echo "Patching TdApi.java..."
|
||||
python3 ../tdlib-serializer/ $(realpath ./src/main/jni-java-src/it/tdlight/jni/TdApi.java) $(realpath ./src/main/jni-java-src/it/tdlight/jni/new_TdApi.java) $(realpath ../tdlib-serializer/headers.txt)
|
||||
rm ./src/main/jni-java-src/it/tdlight/jni/TdApi.java
|
||||
unexpand --tabs=2 ./src/main/jni-java-src/it/tdlight/jni/new_TdApi.java > ./src/main/jni-java-src/it/tdlight/jni/TdApi.java
|
||||
rm ./src/main/jni-java-src/it/tdlight/jni/new_TdApi.java
|
||||
cp ./src/main/jni-java-src/it/tdlight/jni/TdApi.java ./src/main/java/it/tdlight/jni/TdApi.java
|
||||
|
||||
echo "Generated '$(realpath ./src/main/java/it/tdlight/jni/TdApi.java)'"
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
16
scripts/run-all.sh
Executable file
16
scripts/run-all.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash -e
|
||||
# REQUIRED PARAMETERS:
|
||||
# OPERATING_SYSTEM_NAME = <windows | linux | osx>
|
||||
# CPU_ARCHITECTURE_NAME = <amd64 | aarch64>
|
||||
# IMPLEMENTATION_NAME = <tdlib | tdlight>
|
||||
# CPU_CORES = <cores>
|
||||
|
||||
./generate_maven_project.sh
|
||||
./generate_td_tools.sh
|
||||
./compile_td.sh
|
||||
./generate_tdapi_java_file.sh
|
||||
./compile_tdjni.sh
|
||||
./build_generated_maven_project.sh
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
112
src/main/jni-cpp-src/CMakeLists.txt
Normal file
112
src/main/jni-cpp-src/CMakeLists.txt
Normal file
@ -0,0 +1,112 @@
|
||||
cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR)
|
||||
|
||||
project(JTDLib VERSION 1.0 LANGUAGES CXX)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
set(TD_ENABLE_JNI ON)
|
||||
|
||||
if (POLICY CMP0054)
|
||||
# do not expand quoted arguments
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
|
||||
find_package(Td REQUIRED)
|
||||
|
||||
if (NOT JNI_FOUND)
|
||||
find_package(JNI REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Found JNI: ${JNI_INCLUDE_DIRS} ${JNI_LIBRARIES}")
|
||||
|
||||
if (NOT Java_FOUND)
|
||||
find_package(Java 1.6 REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Found Java: ${Java_JAVAC_EXECUTABLE} ${Java_JAVADOC_EXECUTABLE}")
|
||||
|
||||
message(STATUS "Java Source Directory: ${JAVA_SRC_DIR}")
|
||||
|
||||
# Generating TdApi.java
|
||||
find_program(PHP_EXECUTABLE php)
|
||||
|
||||
message(STATUS "PHP Executable: ${PHP_EXECUTABLE}")
|
||||
|
||||
set(TD_API_JAVA_PACKAGE "it/tdlight/jni")
|
||||
set(TD_API_JAVA_PATH ${JAVA_SRC_DIR})
|
||||
set(TD_API_TLO_PATH ${TD_SRC_DIR}/td/generate/scheme/td_api.tlo)
|
||||
set(TD_API_TL_PATH ${TD_SRC_DIR}/td/generate/scheme/td_api.tl)
|
||||
set(JAVADOC_TL_DOCUMENTATION_GENERATOR_PATH ${TD_SRC_DIR}/td/generate/JavadocTlDocumentationGenerator.php)
|
||||
set(GENERATE_JAVA_API_CMD ${TD_GENERATED_BINARIES_DIR}/td_generate_java_api TdApi ${TD_API_TLO_PATH} ${TD_API_JAVA_PATH} ${TD_API_JAVA_PACKAGE})
|
||||
if (PHP_EXECUTABLE)
|
||||
set(GENERATE_JAVA_API_CMD ${GENERATE_JAVA_API_CMD} && ${PHP_EXECUTABLE} ${JAVADOC_TL_DOCUMENTATION_GENERATOR_PATH} ${TD_API_TL_PATH} ${TD_API_JAVA_PATH}/${TD_API_JAVA_PACKAGE}/TdApi.java)
|
||||
endif()
|
||||
|
||||
add_custom_target(td_generate_java_api
|
||||
COMMAND ${GENERATE_JAVA_API_CMD}
|
||||
COMMENT "Generating Java TDLib API source files"
|
||||
DEPENDS ${TD_GENERATED_BINARIES_DIR}/td_generate_java_api ${TD_API_TLO_PATH} ${TD_API_TL_PATH} ${JAVADOC_TL_DOCUMENTATION_GENERATOR_PATH}
|
||||
)
|
||||
|
||||
get_filename_component(JAVA_OUTPUT_DIRECTORY ${TDNATIVES_BIN_DIR}/java-classes REALPATH BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY ${JAVA_OUTPUT_DIRECTORY})
|
||||
add_custom_target(build_java
|
||||
COMMAND ${Java_JAVAC_EXECUTABLE} -d ${JAVA_OUTPUT_DIRECTORY} @${TDNATIVES_CPP_SRC_DIR}/sources.txt
|
||||
COMMENT "Building Java code"
|
||||
DEPENDS td_generate_java_api
|
||||
)
|
||||
|
||||
add_custom_target(generate_javadoc
|
||||
COMMAND ${Java_JAVADOC_EXECUTABLE} -d ${TDNATIVES_DOCS_BIN_DIR} it.tdlight.jni
|
||||
WORKING_DIRECTORY ${TD_API_JAVA_PATH}
|
||||
COMMENT "Generating Javadoc documentation"
|
||||
DEPENDS td_generate_java_api
|
||||
)
|
||||
|
||||
# Building shared library
|
||||
add_library(tdjni SHARED
|
||||
td_jni.cpp
|
||||
)
|
||||
target_include_directories(tdjni PRIVATE ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
|
||||
target_link_libraries(tdjni PRIVATE Td::TdStatic ${JAVA_JVM_LIBRARY})
|
||||
target_compile_definitions(tdjni PRIVATE PACKAGE_NAME="${TD_API_JAVA_PACKAGE}")
|
||||
set_property(TARGET tdjni PROPERTY CXX_STANDARD 14)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(GCC 1)
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CLANG 1)
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
|
||||
set(INTEL 1)
|
||||
elseif (NOT MSVC)
|
||||
message(FATAL_ERROR "Compiler isn't supported")
|
||||
endif()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
if (GCC OR CLANG OR INTEL)
|
||||
if (WIN32 AND INTEL)
|
||||
set(STD14_FLAG /Qstd=c++14)
|
||||
else()
|
||||
set(STD14_FLAG -std=c++14)
|
||||
endif()
|
||||
check_cxx_compiler_flag(${STD14_FLAG} HAVE_STD14)
|
||||
if (NOT HAVE_STD14)
|
||||
string(REPLACE "c++14" "c++1y" STD14_FLAG "${STD14_FLAG}")
|
||||
check_cxx_compiler_flag(${STD14_FLAG} HAVE_STD1Y)
|
||||
set(HAVE_STD14 ${HAVE_STD1Y})
|
||||
endif()
|
||||
|
||||
target_compile_options(tdjni PRIVATE "${STD14_FLAG}")
|
||||
elseif (MSVC)
|
||||
set(HAVE_STD14 MSVC_VERSION>=1900)
|
||||
endif()
|
||||
|
||||
if (NOT HAVE_STD14)
|
||||
message(FATAL_ERROR "No C++14 support in the compiler. Please upgrade the compiler.")
|
||||
endif()
|
||||
|
||||
add_dependencies(tdjni td_generate_java_api build_java generate_javadoc)
|
||||
|
||||
install(TARGETS tdjni
|
||||
LIBRARY DESTINATION ${TDNATIVES_BIN_DIR}
|
||||
RUNTIME DESTINATION ${TDNATIVES_BIN_DIR}
|
||||
)
|
5
src/main/jni-cpp-src/sources.txt
Normal file
5
src/main/jni-cpp-src/sources.txt
Normal file
@ -0,0 +1,5 @@
|
||||
../src/main/jni-java-src/it/tdlight/jni/NativeClient.java
|
||||
../src/main/jni-java-src/it/tdlight/jni/NativeLog.java
|
||||
../src/main/jni-java-src/it/tdlight/jni/TdApi.java
|
||||
../src/main/jni-java-src/it/tdlight/jni/FatalErrorCallbackPtr.java
|
||||
../src/main/jni-java-src/it/tdlight/jni/ObjectsUtils.java
|
196
src/main/jni-cpp-src/td_jni.cpp
Normal file
196
src/main/jni-cpp-src/td_jni.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include <td/telegram/Client.h>
|
||||
#include <td/telegram/Log.h>
|
||||
#include <td/telegram/td_api.h>
|
||||
|
||||
#include <td/tl/tl_jni_object.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace td_jni {
|
||||
|
||||
static td::td_api::object_ptr<td::td_api::Function> fetch_function(JNIEnv *env, jobject function) {
|
||||
td::jni::reset_parse_error();
|
||||
auto result = td::td_api::Function::fetch(env, function);
|
||||
if (td::jni::have_parse_error()) {
|
||||
std::abort();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static td::Client *get_client(jlong client_id) {
|
||||
return reinterpret_cast<td::Client *>(static_cast<std::uintptr_t>(client_id));
|
||||
}
|
||||
|
||||
static jlong Client_createNativeClient(JNIEnv *env, jclass clazz) {
|
||||
return static_cast<jlong>(reinterpret_cast<std::uintptr_t>(new td::Client()));
|
||||
}
|
||||
|
||||
static void Client_nativeClientSend(JNIEnv *env, jclass clazz, jlong client_id, jlong id, jobject function) {
|
||||
get_client(client_id)->send({static_cast<std::uint64_t>(id), fetch_function(env, function)});
|
||||
}
|
||||
|
||||
static jint Client_nativeClientReceive(JNIEnv *env, jclass clazz, jlong client_id, jlongArray ids, jobjectArray events,
|
||||
jdouble timeout) {
|
||||
auto client = get_client(client_id);
|
||||
jsize events_size = env->GetArrayLength(ids); // ids and events size must be of equal size
|
||||
if (events_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
jsize result_size = 0;
|
||||
|
||||
auto response = client->receive(timeout);
|
||||
while (response.object) {
|
||||
jlong result_id = static_cast<jlong>(response.id);
|
||||
env->SetLongArrayRegion(ids, result_size, 1, &result_id);
|
||||
|
||||
jobject object;
|
||||
response.object->store(env, object);
|
||||
env->SetObjectArrayElement(events, result_size, object);
|
||||
env->DeleteLocalRef(object);
|
||||
|
||||
result_size++;
|
||||
if (result_size == events_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
response = client->receive(0);
|
||||
}
|
||||
return result_size;
|
||||
}
|
||||
|
||||
static jint Client_nativeClientReceiveAdvanced(JNIEnv *env, jclass clazz, jlong client_id, jlongArray ids, jobjectArray events,
|
||||
jdouble timeout, jboolean include_responses, jboolean include_updates) {
|
||||
auto client = get_client(client_id);
|
||||
jsize events_size = env->GetArrayLength(ids); // ids and events size must be of equal size
|
||||
if (events_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
jsize result_size = 0;
|
||||
|
||||
auto response = client->receive(timeout, include_responses, include_updates);
|
||||
while (response.object) {
|
||||
jlong result_id = static_cast<jlong>(response.id);
|
||||
env->SetLongArrayRegion(ids, result_size, 1, &result_id);
|
||||
|
||||
jobject object;
|
||||
response.object->store(env, object);
|
||||
env->SetObjectArrayElement(events, result_size, object);
|
||||
env->DeleteLocalRef(object);
|
||||
|
||||
result_size++;
|
||||
if (result_size == events_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
response = client->receive(0, include_responses, include_updates);
|
||||
}
|
||||
return result_size;
|
||||
}
|
||||
|
||||
static jobject Client_nativeClientExecute(JNIEnv *env, jclass clazz, jobject function) {
|
||||
jobject result;
|
||||
td::Client::execute({0, fetch_function(env, function)}).object->store(env, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Client_destroyNativeClient(JNIEnv *env, jclass clazz, jlong client_id) {
|
||||
delete get_client(client_id);
|
||||
}
|
||||
|
||||
static void Log_setVerbosityLevel(JNIEnv *env, jclass clazz, jint new_log_verbosity_level) {
|
||||
td::Log::set_verbosity_level(static_cast<int>(new_log_verbosity_level));
|
||||
}
|
||||
|
||||
static jboolean Log_setFilePath(JNIEnv *env, jclass clazz, jstring file_path) {
|
||||
return td::Log::set_file_path(td::jni::from_jstring(env, file_path)) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
static void Log_setMaxFileSize(JNIEnv *env, jclass clazz, jlong max_file_size) {
|
||||
td::Log::set_max_file_size(max_file_size);
|
||||
}
|
||||
|
||||
static jstring Object_toString(JNIEnv *env, jobject object) {
|
||||
return td::jni::to_jstring(env, to_string(td::td_api::Object::fetch(env, object)));
|
||||
}
|
||||
|
||||
static jstring Function_toString(JNIEnv *env, jobject object) {
|
||||
return td::jni::to_jstring(env, to_string(td::td_api::Function::fetch(env, object)));
|
||||
}
|
||||
|
||||
static constexpr jint JAVA_VERSION = JNI_VERSION_1_6;
|
||||
static JavaVM *java_vm;
|
||||
static jclass log_class;
|
||||
|
||||
static void on_fatal_error(const char *error_message) {
|
||||
auto env = td::jni::get_jni_env(java_vm, JAVA_VERSION);
|
||||
jmethodID on_fatal_error_method = env->GetStaticMethodID(log_class, "onFatalError", "(Ljava/lang/String;)V");
|
||||
if (env && on_fatal_error_method) {
|
||||
jstring error_str = td::jni::to_jstring(env.get(), error_message);
|
||||
env->CallStaticVoidMethod(log_class, on_fatal_error_method, error_str);
|
||||
if (error_str) {
|
||||
env->DeleteLocalRef(error_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static jint register_native(JavaVM *vm) {
|
||||
JNIEnv *env;
|
||||
if (vm->GetEnv(reinterpret_cast<void **>(&env), JAVA_VERSION) != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
java_vm = vm;
|
||||
|
||||
auto register_method = [env](jclass clazz, std::string name, std::string signature, auto function_ptr) {
|
||||
td::jni::register_native_method(env, clazz, std::move(name), std::move(signature),
|
||||
reinterpret_cast<void *>(function_ptr));
|
||||
};
|
||||
|
||||
auto client_class = td::jni::get_jclass(env, PACKAGE_NAME "/NativeClient");
|
||||
log_class = td::jni::get_jclass(env, PACKAGE_NAME "/NativeLog");
|
||||
auto object_class = td::jni::get_jclass(env, PACKAGE_NAME "/TdApi$Object");
|
||||
auto function_class = td::jni::get_jclass(env, PACKAGE_NAME "/TdApi$Function");
|
||||
|
||||
#define TD_OBJECT "L" PACKAGE_NAME "/TdApi$Object;"
|
||||
#define TD_FUNCTION "L" PACKAGE_NAME "/TdApi$Function;"
|
||||
register_method(client_class, "createNativeClient", "()J", Client_createNativeClient);
|
||||
register_method(client_class, "nativeClientSend", "(JJ" TD_FUNCTION ")V", Client_nativeClientSend);
|
||||
register_method(client_class, "nativeClientReceive", "(J[J[" TD_OBJECT "D)I", Client_nativeClientReceive);
|
||||
register_method(client_class, "nativeClientReceive", "(J[J[" TD_OBJECT "DZZ)I", Client_nativeClientReceiveAdvanced);
|
||||
register_method(client_class, "nativeClientExecute", "(" TD_FUNCTION ")" TD_OBJECT, Client_nativeClientExecute);
|
||||
register_method(client_class, "destroyNativeClient", "(J)V", Client_destroyNativeClient);
|
||||
|
||||
register_method(log_class, "setVerbosityLevel", "(I)V", Log_setVerbosityLevel);
|
||||
register_method(log_class, "setFilePath", "(Ljava/lang/String;)Z", Log_setFilePath);
|
||||
register_method(log_class, "setMaxFileSize", "(J)V", Log_setMaxFileSize);
|
||||
|
||||
register_method(object_class, "toString", "()Ljava/lang/String;", Object_toString);
|
||||
|
||||
register_method(function_class, "toString", "()Ljava/lang/String;", Function_toString);
|
||||
#undef TD_FUNCTION
|
||||
#undef TD_OBJECT
|
||||
|
||||
td::jni::init_vars(env, PACKAGE_NAME);
|
||||
td::td_api::Object::init_jni_vars(env, PACKAGE_NAME);
|
||||
td::td_api::Function::init_jni_vars(env, PACKAGE_NAME);
|
||||
td::Log::set_fatal_error_callback(on_fatal_error);
|
||||
|
||||
return JAVA_VERSION;
|
||||
}
|
||||
|
||||
} // namespace td_jni
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
static jint jni_version = td_jni::register_native(vm); // call_once
|
||||
return jni_version;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018. Ernesto Castellotti <erny.castell@gmail.com>
|
||||
* This file is part of JTdlib.
|
||||
*
|
||||
* JTdlib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License.
|
||||
*
|
||||
* JTdlib 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with JTdlib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package it.tdlight.jni;
|
||||
|
||||
/**
|
||||
* A type of callback function that will be called when a fatal error happens.
|
||||
*/
|
||||
public interface FatalErrorCallbackPtr {
|
||||
/**
|
||||
* Send error message to callback.
|
||||
* @param error_message String with a description of a happened fatal error.
|
||||
*/
|
||||
void onFatalError(String error_message);
|
||||
}
|
31
src/main/jni-java-src/it/tdlight/jni/NativeClient.java
Normal file
31
src/main/jni-java-src/it/tdlight/jni/NativeClient.java
Normal file
@ -0,0 +1,31 @@
|
||||
package it.tdlight.jni;
|
||||
/*
|
||||
* Copyright (c) 2018. Ernesto Castellotti <erny.castell@gmail.com>
|
||||
* This file is part of JTdlib.
|
||||
*
|
||||
* JTdlib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License.
|
||||
*
|
||||
* JTdlib 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with JTdlib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import it.tdlight.jni.TdApi.Function;
|
||||
import it.tdlight.jni.TdApi.Object;
|
||||
|
||||
public class NativeClient {
|
||||
protected static native long createNativeClient();
|
||||
protected static native void nativeClientSend(long nativeClientId, long eventId, Function function);
|
||||
protected static native int nativeClientReceive(long nativeClientId, long[] eventIds, Object[] events, double timeout);
|
||||
protected static native int nativeClientReceive(long nativeClientId, long[] eventIds, Object[] events, double timeout, boolean include_responses, boolean include_updates);
|
||||
protected static native Object nativeClientExecute(Function function);
|
||||
protected static native void destroyNativeClient(long nativeClientId);
|
||||
}
|
85
src/main/jni-java-src/it/tdlight/jni/NativeLog.java
Normal file
85
src/main/jni-java-src/it/tdlight/jni/NativeLog.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2018. Ernesto Castellotti <erny.castell@gmail.com>
|
||||
* This file is part of JTdlib.
|
||||
*
|
||||
* JTdlib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License.
|
||||
*
|
||||
* JTdlib 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with JTdlib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package it.tdlight.jni;
|
||||
|
||||
/**
|
||||
* Class used for managing internal TDLib logging.
|
||||
* Use TdApi.*Log* methods instead.
|
||||
*/
|
||||
public class NativeLog {
|
||||
|
||||
private static final FatalErrorCallbackPtr defaultFatalErrorCallbackPtr = System.err::println;
|
||||
private static FatalErrorCallbackPtr fatalErrorCallback = defaultFatalErrorCallbackPtr;
|
||||
|
||||
/**
|
||||
* Sets file path for writing TDLib internal log. By default TDLib writes logs to the System.err.
|
||||
* Use this method to write the log to a file instead.
|
||||
*
|
||||
* @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogStream}, to be removed in the future.
|
||||
* @param filePath Path to a file for writing TDLib internal log. Use an empty path to
|
||||
* switch back to logging to the System.err.
|
||||
* @return whether opening the log file succeeded.
|
||||
*/
|
||||
@Deprecated
|
||||
public static native boolean setFilePath(String filePath);
|
||||
|
||||
/**
|
||||
* Changes the maximum size of TDLib log file.
|
||||
*
|
||||
* @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogStream}, to be removed in the future.
|
||||
* @param maxFileSize The maximum size of the file to where the internal TDLib log is written
|
||||
* before the file will be auto-rotated. Must be positive. Defaults to 10 MB.
|
||||
*/
|
||||
@Deprecated
|
||||
public static native void setMaxFileSize(long maxFileSize);
|
||||
|
||||
/**
|
||||
* Changes TDLib log verbosity.
|
||||
*
|
||||
* @deprecated As of TDLib 1.4.0 in favor of {@link TdApi.SetLogVerbosityLevel}, to be removed in the future.
|
||||
* @param verbosityLevel New value of log verbosity level. Must be non-negative.
|
||||
* Value 0 corresponds to fatal errors,
|
||||
* value 1 corresponds to java.util.logging.Level.SEVERE,
|
||||
* value 2 corresponds to java.util.logging.Level.WARNING,
|
||||
* value 3 corresponds to java.util.logging.Level.INFO,
|
||||
* value 4 corresponds to java.util.logging.Level.FINE,
|
||||
* value 5 corresponds to java.util.logging.Level.FINER,
|
||||
* value greater than 5 can be used to enable even more logging.
|
||||
* Default value of the log verbosity level is 5.
|
||||
*/
|
||||
@Deprecated
|
||||
public static native void setVerbosityLevel(int verbosityLevel);
|
||||
|
||||
/**
|
||||
* This function is called from the JNI when a fatal error happens to provide a better error message.
|
||||
* The function does not return.
|
||||
*
|
||||
* @param errorMessage Error message.
|
||||
*/
|
||||
private static synchronized void onFatalError(String errorMessage) {
|
||||
new Thread(() -> NativeLog.fatalErrorCallback.onFatalError(errorMessage)).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the callback that will be called when a fatal error happens. None of the TDLib methods can be called from the callback. The TDLib will crash as soon as callback returns. By default the callback set to print in stderr.
|
||||
* @param fatalErrorCallback Callback that will be called when a fatal error happens. Pass null to restore default callback.
|
||||
*/
|
||||
public static synchronized void setFatalErrorCallback(FatalErrorCallbackPtr fatalErrorCallback) {
|
||||
NativeLog.fatalErrorCallback = ObjectsUtils.requireNonNullElse(fatalErrorCallback, defaultFatalErrorCallbackPtr);
|
||||
}
|
||||
}
|
67
src/main/jni-java-src/it/tdlight/jni/ObjectsUtils.java
Normal file
67
src/main/jni-java-src/it/tdlight/jni/ObjectsUtils.java
Normal file
@ -0,0 +1,67 @@
|
||||
package it.tdlight.jni;
|
||||
|
||||
public class ObjectsUtils {
|
||||
/**
|
||||
* Returns the first argument if it is non-{@code null} and
|
||||
* otherwise returns the non-{@code null} second argument.
|
||||
*
|
||||
* @param obj an object
|
||||
* @param defaultObj a non-{@code null} object to return if the first argument
|
||||
* is {@code null}
|
||||
* @param <T> the type of the reference
|
||||
* @return the first argument if it is non-{@code null} and
|
||||
* otherwise the second argument if it is non-{@code null}
|
||||
* @throws NullPointerException if both {@code obj} is null and
|
||||
* {@code defaultObj} is {@code null}
|
||||
* @since 9
|
||||
*/
|
||||
public static <T> T requireNonNullElse(T obj, T defaultObj) {
|
||||
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null}. This
|
||||
* method is designed primarily for doing parameter validation in methods
|
||||
* and constructors, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* public Foo(Bar bar) {
|
||||
* this.bar = Objects.requireNonNull(bar);
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
*/
|
||||
public static <T> T requireNonNull(T obj) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null} and
|
||||
* throws a customized {@link NullPointerException} if it is. This method
|
||||
* is designed primarily for doing parameter validation in methods and
|
||||
* constructors with multiple parameters, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* public Foo(Bar bar, Baz baz) {
|
||||
* this.bar = Objects.requireNonNull(bar, "bar must not be null");
|
||||
* this.baz = Objects.requireNonNull(baz, "baz must not be null");
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param message detail message to be used in the event that a {@code
|
||||
* NullPointerException} is thrown
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
*/
|
||||
public static <T> T requireNonNull(T obj, String message) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(message);
|
||||
return obj;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user