diff --git "a/Sources/JavApi/JavApi\342\201\264Swift.docc/Java2Swift.md" "b/Sources/JavApi/JavApi\342\201\264Swift.docc/Java2Swift.md" index a45e85b3..91ec255e 100644 --- "a/Sources/JavApi/JavApi\342\201\264Swift.docc/Java2Swift.md" +++ "b/Sources/JavApi/JavApi\342\201\264Swift.docc/Java2Swift.md" @@ -10,6 +10,12 @@ Most modern programming language can be easy translate between. But the detail m This bullet point list is an overview over methods. Look into source code for more informations. But some things can do before. For example kill all `for` loops or at minimum do not complex statements and checks in the a look header. +### Some steps I do + +0. Exit factor: Find a Swift project that already meets your requirements. +1. Problem factor: In result of hidden check 3rd party dependencies. +2. Problem factor: In result of sometimes complex test, check loops in code. Sometime refactoring of loops especially for loops on Java site is a good idea. Do same if you translate Non-Java code like C. A good for loop only iterate over elements, that is equal to count as iterate over number range. + #### abstract classes Abstract classes are implemented as interface with default methods. diff --git a/Sources/JavApi/lang/Throwable.swift b/Sources/JavApi/lang/Throwable.swift index 673506e0..45963984 100644 --- a/Sources/JavApi/lang/Throwable.swift +++ b/Sources/JavApi/lang/Throwable.swift @@ -7,6 +7,7 @@ public enum Throwable : Error { case ArithmeticException (_ message : String = "ArithmeticException") case ArrayIndexOutOfBoundsException (_ offset : Int) + case ArrayIndexOutOfBoundsException (_ offset : Int, _ message : String = "ArrayIndexOutOfBoundsException") case AssertionError (_ message : String = "AssertionError") case CloneNotSupportedException (_ message : String = "CloneNotSupportedException") case Exception (_ message : String = "Exception") @@ -18,6 +19,7 @@ public enum Throwable : Error { case OutOfMemoryError (_ message : String = "OutOfMemoryError") case RuntimeException (_ message : String = "RuntimeException") case UnsupportedEncodingException (_ message : String = "UnsupportedEncodingException") + case UnsupportedOperationException (_ message : String = "UnsupportedOperationException") } extension java.io { diff --git a/Sources/JavApi/util/Calendar+Swiftify.swift b/Sources/JavApi/util/Calendar+Swiftify.swift new file mode 100644 index 00000000..48171e74 --- /dev/null +++ b/Sources/JavApi/util/Calendar+Swiftify.swift @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 - Sebastian Ritter + * SPDX-License-Identifier: MIT + */ + +import Foundation + +extension java.util.Calender { + public enum DateComponents : Int { + case YEAR = 1 + case DAY_OF_WEEK = 7 + case DAY_OF_MONTH = 8 + case HOUR_OF_DAY = 11 + case MINUTE = 12 + case SECOND = 13 + } + + public func setTime (from newDate: Foundation.Date) { + let calendar = Foundation.Calendar(identifier: .gregorian) + var components : Foundation.DateComponents + if #available(macOS 14, *) /* .isLeapMonth */{ + components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .weekdayOrdinal, .weekday, .weekOfYear, .weekOfMonth, .timeZone, .quarter, .nanosecond, .isLeapMonth, .era], from: newDate ) + } else { + components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .weekdayOrdinal, .weekday, .weekOfYear, .weekOfMonth, .timeZone, .quarter, .nanosecond, .era], from: newDate) + } + self.dateComponents = components + } +} diff --git a/Sources/JavApi/util/Calendar.swift b/Sources/JavApi/util/Calendar.swift new file mode 100644 index 00000000..88c73846 --- /dev/null +++ b/Sources/JavApi/util/Calendar.swift @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2024 - Sebastian Ritter + * SPDX-License-Identifier: MIT + */ + +import Foundation + +extension java.util { + /// Abstract Java type + /// + open class Calender { + internal var dateComponents : Foundation.DateComponents = Foundation.DateComponents() + + public init (){ + let calendar = Foundation.Calendar(identifier: .gregorian) + let now = Foundation.Date() + var components : Foundation.DateComponents + if #available(macOS 14, *) /* .isLeapMonth */{ + components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .weekdayOrdinal, .weekday, .weekOfYear, .weekOfMonth, .timeZone, .quarter, .nanosecond, .isLeapMonth, .era], from:now) + } else { + components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .weekdayOrdinal, .weekday, .weekOfYear, .weekOfMonth, .timeZone, .quarter, .nanosecond, .era], from:now) + } + self.dateComponents = components + } + + public static let SECOND = 13 + public static let MINUTE = 12 + public static let HOUR_OF_DAY = 11 + public static let YEAR = 1 + public static let DAY_OF_MONTH = 8 + public static let DAY_OF_WEEK = 7 + + open func get (_ field : Int) throws -> Int { + throw java.lang.Throwable.UnsupportedOperationException("Calendar is a abstract type, use subtypes like GregorianCalendar") + } + + public func setTime (_ newDate :java.util.Date) { + self.setTime(from: newDate.delegate) + } + + } +} diff --git a/Sources/JavApi/util/Date.swift b/Sources/JavApi/util/Date.swift index 758c1c0c..41a0e01b 100644 --- a/Sources/JavApi/util/Date.swift +++ b/Sources/JavApi/util/Date.swift @@ -9,7 +9,7 @@ extension java.util { open class Date { - fileprivate var delegate : Foundation.Date + internal var delegate : Foundation.Date public init () { self.delegate = Foundation.Date.now } diff --git a/Sources/JavApi/util/GregorianCalendar+Swiftify.swift b/Sources/JavApi/util/GregorianCalendar+Swiftify.swift index 48b45a76..4ec41ec2 100644 --- a/Sources/JavApi/util/GregorianCalendar+Swiftify.swift +++ b/Sources/JavApi/util/GregorianCalendar+Swiftify.swift @@ -9,5 +9,11 @@ extension java.util.GregorianCalendar { public convenience init (_ happyNewYear : any FixedWidthInteger, _ newMonth : any FixedWidthInteger, _ newDayOfMonth : any FixedWidthInteger, _ newHourOfDay : any FixedWidthInteger, _ newMinute : any FixedWidthInteger, _ newSecond : any FixedWidthInteger) { self.init(Int(happyNewYear), Int(newMonth), Int(newDayOfMonth), Int(newHourOfDay), Int(newMinute), Int(newSecond)) } + + + + public func get (_ what : java.util.Calender.DateComponents) -> Int { + return try! self.get(what.rawValue) + } } diff --git a/Sources/JavApi/util/GregorianCalendar.swift b/Sources/JavApi/util/GregorianCalendar.swift index 3a6c01c6..517e0985 100644 --- a/Sources/JavApi/util/GregorianCalendar.swift +++ b/Sources/JavApi/util/GregorianCalendar.swift @@ -6,21 +6,32 @@ import Foundation extension java.util { + + /// The Gregorian calendar is the calendar used in not too less parts of the world. + /// + /// Port of ``java.util.GregorianCalendar`` to Swift. + /// + /// ## Sample for port Java to Swift without [JavApi⁴Swift](https://github.com/bastie/JavApi4Swift) + /// + /// ```Java + /// GregorianCalendar calendar = new GregorianCalendar(); + /// calendar.set(Calendar.YEAR, 2023); + /// calendar.set(Calendar.MONTH, Calendar.NOVEMBER); + /// calendar.set(Calendar.DAY_OF_MONTH, 24); + /// ``` + /// + /// ```Swift + /// let calendar = Foundation.Calendar.current + /// let components = DateComponents(year: 2023, month: 11, day: 24) + /// let date = calendar.date(from: components) + /// ``` - open class GregorianCalendar { - /* Java - GregorianCalendar calendar = new GregorianCalendar(); - calendar.set(Calendar.YEAR, 2023); - calendar.set(Calendar.MONTH, Calendar.NOVEMBER); - calendar.set(Calendar.DAY_OF_MONTH, 24); - */ - /* Swift - let calendar = Calendar.current - let components = DateComponents(year: 2023, month: 11, day: 24) - let date = calendar.date(from: components) - */ + open class GregorianCalendar : java.util.Calender { - internal var dateComponents : DateComponents = DateComponents() + // Constructor to init ``Foundation.DateComponents`` with all fields + public override init () { + super.init() + } public convenience init (_ happyNewYear : Int, _ newMonth : Int, _ newDayOfMonth : Int) { self.init(happyNewYear, newMonth, newDayOfMonth, 0, 0, 0) @@ -28,7 +39,8 @@ extension java.util { public convenience init (_ happyNewYear : Int, _ newMonth : Int, _ newDayOfMonth : Int, _ newHourOfDay : Int, _ newMinute : Int) { self.init(happyNewYear, newMonth, newDayOfMonth, newHourOfDay, newMinute, 0) } - public init (_ happyNewYear : Int, _ newMonth : Int, _ newDayOfMonth : Int, _ newHourOfDay : Int, _ newMinute : Int, _ newSecond : Int) { + public convenience init (_ happyNewYear : Int, _ newMonth : Int, _ newDayOfMonth : Int, _ newHourOfDay : Int, _ newMinute : Int, _ newSecond : Int) { + self.init() dateComponents.year = happyNewYear dateComponents.month = newMonth dateComponents.day = newDayOfMonth @@ -42,5 +54,26 @@ extension java.util { return javaDate } + /// Returns the value of given ``java.util.Calendar`` field + /// - Returns ``Int`` value of expected field or throws exception + /// - Note: Can throw a hidden Java runtime Exception. Use Swift DateComponents or secure extension function `get (_ java.util.Calendar.DateComponets` + open override func get (_ field : Int) throws -> Int { + switch field { + case Calender.SECOND : + return dateComponents.second! + case Calender.MINUTE : + return dateComponents.minute! + case Calender.HOUR_OF_DAY : + return dateComponents.hour! + case Calender.YEAR : + return dateComponents.year! + case Calender.DAY_OF_MONTH : + return dateComponents.month! + case Calender.DAY_OF_WEEK : + return dateComponents.weekday! + default : + throw java.lang.Throwable.ArrayIndexOutOfBoundsException(field, "if the specified field is out of range or not implemented") + } + } } }