From 1b8e1ede30e6583d4546965b34a4a4a4e794748b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=CD=ACe=CD=A5b=CD=ADa=CD=ADs=CD=A4t=CD=ACian?= Date: Wed, 25 Sep 2024 17:08:36 +0200 Subject: [PATCH] extends java.io.File, java.nio.ByteBuffer and java.util.Date implementations --- .../JavApi\342\201\264Swift.docc/Java_1.0.md" | 155 ++++++++++++++++++ Sources/JavApi/io/File.swift | 14 ++ Sources/JavApi/nio/ByteBuffer.swift | 38 ++++- Sources/JavApi/nio/ByteOrder.swift | 2 +- Sources/JavApi/util/Date.swift | 33 +++- 5 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 "Sources/JavApi/JavApi\342\201\264Swift.docc/Java_1.0.md" diff --git "a/Sources/JavApi/JavApi\342\201\264Swift.docc/Java_1.0.md" "b/Sources/JavApi/JavApi\342\201\264Swift.docc/Java_1.0.md" new file mode 100644 index 00000000..721bda75 --- /dev/null +++ "b/Sources/JavApi/JavApi\342\201\264Swift.docc/Java_1.0.md" @@ -0,0 +1,155 @@ +# Java 1.0 + +1995-05-23 the first appeared of Java also called Java birthday. + +## Overview + + +### Compiler directives (expermimental) + +By default the lates Java behavior is implemented but checked at runtime against other wishes (over explicit method parameter extension and / or system property). Another way is to set compiler directives to build special Java like version. + +- term: Java10Compiler activates static compiling like Java 1.0 behavior +- term: JavaOtherCompiler activates static compiling other than explicit defined Java version (see Java10Compiler) + +## Java Documentation + +_based on JDK Documentation at [https://javaalmanac.io](https://javaalmanac.io/jdk/1.0/api/)_ + +Java 1.0 splits his packages in two parts. + +1. **Core Packages** +- term java.lang: the Java language package +- term java.io: the Java input/output package +- term java.net: the Java network specific input/output package +- term java.util: the Java utilities and data structures package +2. **UI Packages** +- term java.applet: the UI in the browser package +- term java.awt: the native Abstract Window Toolkit UI package +- term java.awt.image: the Image package for AWT +- term java.awt.peer: the peer package for AWT + + +### Java Core packages + +#### java.lang + + + +version | implemented | tested | type | name | more informations +------- | ----------- | -------- | ------------- | -------------- | ----------------- +1.0.2 | ✔️ | ⭕️ | Class | Boolean | typealias and extension of `Bool` +1.0.2 | ✔️ | ⭕️ | final field | Boolean.FALSE | +1.0.2 | ✔️ | ⭕️ | final field | Boolean.TRUE | +1.0.2 | ✔️ | 🪄 | constructor | Boolean() | (boolean) buildin over typealias +1.0.2 | ✔️ | ⭕️ | constructor | Boolean() | (String?) +1.0.2 | ✔️ | ⭕️ | method | booleanValue() | ()->boolean +1.0.2 | ✔️ | ⭕️ | method | equals() | (Object)->boolean +1.0.2 | ✔️ | ⭕️ | static method | getBoolean() | (String)->boolean, in result since Java 1.1 it is case insensitive the Java 1.0 case sensitive behavior must be explicit activated +1.1 | ✔️ | ⭕️ | static method | getBoolean() | (String)->boolean +1.0.2 | ✔️ | ⭕️ | method | hashcode() | ()->int +1.0.2 | ✔️ | ⭕️ | method | toString() | ()->String +1.0.2 | ✔️ | ⭕️ | static method | valueOf() | (String)->Boolean + +##### java.lang.Character (24/?/?) + +version | implemented | tested | type | name | more informations +------- | ----------- | -------- | ------------- | -------------- | ----------------- +1.0.2 | ✔️ | ⭕️ | Class | Boolean | typealias and extension of `char` +1.0.2 | ⭕️ | ⭕️ | final field | MAX_RADIX | +1.0.2 | ⭕️ | ⭕️ | final field | MAX_VALUE | +1.0.2 | ⭕️ | ⭕️ | final field | MIN_RADIX | +1.0.2 | ⭕️ | ⭕️ | final field | MIN_VALUE | +1.0.2 | ✔️ | ⭕️ | constructor | Character() | (char) +1.0.2 | ✔️ | ⭕️ | method | charValue() | ()->Character +1.0.2 | ⭕️ | ⭕️ | static method | digit() | (char,int)->int +1.0.2 | ⭕️ | ⭕️ | method | equals() | (Object)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | forDigit() | (char,int)->int +1.1 | ✔️ | ⭕️ | static method | getNumericValue() | (char)->int +1.0.2 | ⭕️ | ⭕️ | method | hashCode() | ()->int +1.0.2 | ⭕️ | ⭕️ | static method | isDefined() | (char)->boolean +1.0.2 | ✔️ | ⭕️ | static method | isDigit() | (char)->boolean +5 | ✔️ | ⭕️ | static method | isDigit() | (int)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isJavaLetter() | (char)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isJavaLetterOrDigit() | (char)->boolean +1.0.2 | ✔️ | ⭕️ | static method | isLetter() | (char)->boolean +5 | ✔️ | ⭕️ | static method | isLetter() | (int)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isLetterOrDigit() | (char)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isLowerCase() | (char)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isSpace() | (char)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isTitleCase() | (char)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | isUpperCase() | (char)->boolean +1.0.2 | ⭕️ | ⭕️ | static method | toLowerCase() | (char)->char +1.0.2 | ⭕️ | ⭕️ | static method | toString() | ()->String +1.0.2 | ⭕️ | ⭕️ | static method | toTitelCase() | (char)->char +1.0.2 | ⭕️ | ⭕️ | static method | toUpperCase() | (char)->char +1.1 | ✔️ | ⭕️ | static method | isWhiteSpace() | (char)->boolean + + +##### java.lang.Class (8/?/?) + +version | implemented | tested | type | name | more informations +------- | ----------- | -------- | ------------- | -------------- | ----------------- +1.0.2 | ⭕️ | ⭕️ | static method | forName() | (String)->Class +1.0.2 | ⭕️ | ⭕️ | method | getClassLoader() | ()->ClassLoader +1.0.2 | ⭕️ | ⭕️ | method | getInterfaces() | ()->Class[] +1.0.2 | ✔️ | ✔️ | method | getName() | ()->String +1.0.2 | ⭕️ | ⭕️ | method | getSuperclass() | ()->Class +1.0.2 | ⭕️ | ⭕️ | method | isInterface() | ()->boolean +1.0.2 | ⭕️ | ⭕️ | method | newInstance() | ()->Object +1.0.2 | ⭕️ | ⭕️ | method | toString() | ()->String + + +##### java.lang.ClassLoader (5/?/?) + +##### java.lang.Compiler (5/?/?) + +##### java.lang.Double (22/?/?) + +##### java.lang.Float (23/?/?) + +##### java.lang.Integer (23/?/?) + +##### java.lang.Long (23/?/?) + +##### java.lang.Math (32/?/?) + +##### java.lang.Number (4/?/?) + +##### java.lang.Object (11/?/?) + +##### java.lang.Process (7/?/?) + +##### java.lang.Runtime (16/?/?) + +##### java.lang.SecurityManager (32/?/?) + +##### java.lang.String (48/?/?) + +##### java.lang.StringBuffer (31/?/?) + +##### java.lang.System (16/?/?) + +##### java.lang.Thread (41/?/?) + +##### java.lang.ThreadGroup (23/?/?) + +##### java.lang.Throwable (7/?/?) + + + + + +#### java.io + +#### java.net + +#### java.util + +- [x] #739 +- [ ] https://github.com/octo-org/octo-repo/issues/740 +- [ ] Add delight to the experience when all tasks are complete :tada: diff --git a/Sources/JavApi/io/File.swift b/Sources/JavApi/io/File.swift index e784efb4..690ffe72 100644 --- a/Sources/JavApi/io/File.swift +++ b/Sources/JavApi/io/File.swift @@ -220,6 +220,20 @@ extension java.io { } } + /// System depend last modified data of the underlying file. The default implementation returns the time since 1. January 1970 in milliseconds + /// - Returns last modified time stamp of file + /// - Since: JavaApi > 0.17.0 (Java 1.0) + open func lastModified () -> Int64 { + do { + let attributes = try FileManager.default.attributesOfItem(atPath: self.getAbsolutePath()) + if let lastModifiedDate = attributes[.modificationDate] as? Date { + return Int64(lastModifiedDate.timeIntervalSince1970) * 1000 + } + } catch { + } + return 0 + } + /// List all files of directory. /// If self isn't a directory returns ``nil`` /// - Returns array of directory entries or ``nil`` diff --git a/Sources/JavApi/nio/ByteBuffer.swift b/Sources/JavApi/nio/ByteBuffer.swift index 51954ea1..2220ac3f 100644 --- a/Sources/JavApi/nio/ByteBuffer.swift +++ b/Sources/JavApi/nio/ByteBuffer.swift @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 - Sebastian Ritter + * SPDX-FileCopyrightText: 2023, 2024 - Sebastian Ritter * SPDX-License-Identifier: MIT */ @@ -10,7 +10,10 @@ extension java.nio { } /// Abstract type for working with bytes -public class ByteBuffer { +open class ByteBuffer { + + /// The default byte order of ``ByteBuffer`` is `BIG_ENDIAN`. + private var SELF_BYTE_ORDER = java.nio.ByteOrder.BIG_ENDIAN /// byte buffer internal var content : [UInt8] = [] @@ -32,6 +35,37 @@ public class ByteBuffer { return self.content } + /// Returns the order of this ``ByteBuffer``. The default value is ``java.nio.ByteOrder.BIG_ENDIAN`` + /// - Returns order of ``ByteBuffer`` + /// - Since: JavaApi > 0.17.0 (Java 1.4) + open func order () -> java.nio.ByteOrder { + return SELF_BYTE_ORDER + } + + /// Modify the order of ``ByteBuffer`` if required + /// - Parameter order the new order of bytes + /// - Returns ``ByteBuffer`` self + /// - Since: JavaApi > 0.17.0 (Java 1.4) + open func order(_ order: java.nio.ByteOrder) -> ByteBuffer { + guard SELF_BYTE_ORDER != order else { + return self + } + guard SELF_BYTE_ORDER == .BIG_ENDIAN || SELF_BYTE_ORDER == .LITTLE_ENDIAN else { + /// FIXME: create a log message + return self + } + + // reverse byte order + self.content.reverse() + if SELF_BYTE_ORDER == .LITTLE_ENDIAN { + self.SELF_BYTE_ORDER = .BIG_ENDIAN + } + else { + self.SELF_BYTE_ORDER = .LITTLE_ENDIAN + } + return self + } + open func put (_ byte : UInt8) throws -> ByteBuffer { self.content.append(byte) return self diff --git a/Sources/JavApi/nio/ByteOrder.swift b/Sources/JavApi/nio/ByteOrder.swift index 69141986..d5907185 100644 --- a/Sources/JavApi/nio/ByteOrder.swift +++ b/Sources/JavApi/nio/ByteOrder.swift @@ -8,7 +8,7 @@ import Foundation extension java.nio { public final class ByteOrder : Equatable { - private let asString : String + internal let asString : String public static let BIG_ENDIAN : ByteOrder = ByteOrder("BIG_ENDIAN") public static let LITTLE_ENDIAN : ByteOrder = ByteOrder("LITTLE_ENDIAN") diff --git a/Sources/JavApi/util/Date.swift b/Sources/JavApi/util/Date.swift index c19e5f69..1e8c2149 100644 --- a/Sources/JavApi/util/Date.swift +++ b/Sources/JavApi/util/Date.swift @@ -14,7 +14,38 @@ extension java.util { self.delegate = Foundation.Date.now } - public func toString() -> String { + /// Create a new ``java.util.Date`` instance at 1. Januar 1970 + /// - Parameters: + /// - Parameter millisecondsSince1970 milliseconds since 1970 + /// - Note: In result of Swift works with seconds instead of milliseconds the milliseconds part are ignored + /// - Since: JavaApi > 0.17.0 (Java 1.0) + public convenience init(_ millisecondsSince1970: Int64) { + self.init() + let secondsSince1970 = millisecondsSince1970 / 1000 + let interval = TimeInterval(secondsSince1970) + delegate = Foundation.Date(timeIntervalSince1970: interval) + } + + /// time in milliseconds since 1. January 1970 + /// - Note: In result of Swift works with seconds instead of milliseconds this implementation it returns time in seconds `*` 1000 + /// - Returns: milliseconds since 1. January 1970 + /// - Since: JavaApi > 0.17.0 (Java 1.0) + open func getTime() -> Int64 { + return Int64(self.delegate.timeIntervalSince1970) * 1000 + } + + /// set the ``Date`` object with the new milliseconds relative to 1. January 1970 + /// - Parameters: + /// - Parameter millisecondsSince1970 milliseconds since 1970 + /// - Note: In result of Swift works with seconds instead of milliseconds the milliseconds part are ignored + /// - Since: JavaApi > 0.17.0 (Java 1.0) + open func setTime(_ millisecondsSince1970: Int64) { + let secondsSince1970 = millisecondsSince1970 / 1000 + let interval = TimeInterval(secondsSince1970) + self.delegate = Foundation.Date(timeIntervalSince1970: interval) + } + + open func toString() -> String { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "EEE MMM dd hh:mm:ss zzz yyyy"