From 86dc85a12e89700db7771e1a5fa7d6b2db1c8777 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 10:01:08 +0800 Subject: [PATCH 1/8] fix --- java/pom.xml | 10 - java/tools/pom.xml | 8 - .../org/apache/tsfile/tools/TsFileTool.java | 4 +- java/tsfile/pom.xml | 8 - .../org/apache/commons/codec/binary/Hex.java | 118 ++ .../codec/binary/MessageDigestAlgorithms.java | 52 + .../commons/codec/binary/StringUtils.java | 54 + .../commons/codec/digest/DigestUtils.java | 121 ++ .../commons/collections4/BoundedMap.java | 44 + .../commons/collections4/CollectionUtils.java | 52 + .../org/apache/commons/collections4/Get.java | 91 ++ .../commons/collections4/IterableGet.java | 47 + .../commons/collections4/IterableMap.java | 43 + .../apache/commons/collections4/KeyValue.java | 44 + .../commons/collections4/MapIterator.java | 110 ++ .../apache/commons/collections4/MapUtils.java | 39 + .../commons/collections4/OrderedIterator.java | 46 + .../commons/collections4/OrderedMap.java | 70 + .../collections4/OrderedMapIterator.java | 46 + .../org/apache/commons/collections4/Put.java | 60 + .../collections4/ResettableIterator.java | 33 + .../comparators/ComparatorChain.java | 335 ++++ .../iterators/AbstractEmptyIterator.java | 72 + .../iterators/AbstractEmptyMapIterator.java | 44 + .../collections4/iterators/EmptyIterator.java | 74 + .../iterators/EmptyMapIterator.java | 55 + .../iterators/EmptyOrderedIterator.java | 53 + .../iterators/EmptyOrderedMapIterator.java | 55 + .../collections4/map/AbstractHashedMap.java | 1394 +++++++++++++++++ .../collections4/map/AbstractLinkedMap.java | 610 ++++++++ .../commons/collections4/map/LRUMap.java | 572 +++++++ .../java/org/apache/commons/io/Charsets.java | 211 +++ .../commons/io/FileExistsException.java | 53 + .../java/org/apache/commons/io/FileUtils.java | 884 +++++++++++ .../org/apache/commons/io/FilenameUtils.java | 290 ++++ .../java/org/apache/commons/io/IOCase.java | 247 +++ .../apache/commons/io/IOExceptionList.java | 140 ++ .../apache/commons/io/IOIndexedException.java | 68 + .../java/org/apache/commons/io/IOUtils.java | 462 ++++++ .../commons/io/RandomAccessFileMode.java | 96 ++ .../apache/commons/io/RandomAccessFiles.java | 46 + .../commons/io/build/AbstractOrigin.java | 530 +++++++ .../io/build/AbstractOriginSupplier.java | 315 ++++ .../io/build/AbstractStreamBuilder.java | 329 ++++ .../commons/io/build/AbstractSupplier.java | 41 + .../commons/io/charset/CharsetDecoders.java | 44 + .../commons/io/charset/CharsetEncoders.java | 58 + .../org/apache/commons/io/file/Counters.java | 419 +++++ .../commons/io/file/CountingPathVisitor.java | 195 +++ .../apache/commons/io/file/DeleteOption.java | 30 + .../commons/io/file/DeletingPathVisitor.java | 188 +++ .../apache/commons/io/file/PathFilter.java | 40 + .../org/apache/commons/io/file/PathUtils.java | 539 +++++++ .../apache/commons/io/file/PathVisitor.java | 30 + .../commons/io/file/SimplePathVisitor.java | 57 + .../commons/io/file/StandardDeleteOption.java | 51 + .../io/filefilter/AbstractFileFilter.java | 177 +++ .../commons/io/filefilter/AndFileFilter.java | 192 +++ .../io/filefilter/ConditionalFileFilter.java | 60 + .../io/filefilter/FalseFileFilter.java | 114 ++ .../commons/io/filefilter/FileFileFilter.java | 111 ++ .../commons/io/filefilter/IOFileFilter.java | 119 ++ .../commons/io/filefilter/NotFileFilter.java | 104 ++ .../commons/io/filefilter/OrFileFilter.java | 182 +++ .../io/filefilter/SuffixFileFilter.java | 214 +++ .../io/filefilter/SymbolicLinkFileFilter.java | 141 ++ .../commons/io/filefilter/TrueFileFilter.java | 114 ++ .../apache/commons/io/function/Constants.java | 60 + .../org/apache/commons/io/function/Erase.java | 191 +++ .../commons/io/function/IOBaseStream.java | 153 ++ .../io/function/IOBaseStreamAdapter.java | 50 + .../commons/io/function/IOBiConsumer.java | 87 + .../commons/io/function/IOBiFunction.java | 76 + .../commons/io/function/IOBinaryOperator.java | 75 + .../commons/io/function/IOComparator.java | 58 + .../commons/io/function/IOConsumer.java | 145 ++ .../commons/io/function/IOFunction.java | 199 +++ .../commons/io/function/IOIntSupplier.java | 50 + .../commons/io/function/IOIterator.java | 116 ++ .../io/function/IOIteratorAdapter.java | 55 + .../commons/io/function/IOLongSupplier.java | 37 + .../commons/io/function/IOPredicate.java | 134 ++ .../commons/io/function/IOQuadFunction.java | 51 + .../commons/io/function/IORunnable.java | 36 + .../commons/io/function/IOSpliterator.java | 146 ++ .../io/function/IOSpliteratorAdapter.java | 44 + .../apache/commons/io/function/IOStream.java | 633 ++++++++ .../commons/io/function/IOStreamAdapter.java | 44 + .../apache/commons/io/function/IOStreams.java | 91 ++ .../commons/io/function/IOSupplier.java | 65 + .../commons/io/function/IOTriConsumer.java | 78 + .../commons/io/function/IOTriFunction.java | 66 + .../commons/io/function/IOUnaryOperator.java | 54 + .../apache/commons/io/function/Uncheck.java | 310 ++++ .../io/function/UncheckedIOBaseStream.java | 88 ++ .../io/function/UncheckedIOIterator.java | 60 + .../io/function/UncheckedIOSpliterator.java | 82 + .../commons/io/input/ClosedInputStream.java | 58 + .../commons/io/input/ReaderInputStream.java | 453 ++++++ .../UnsynchronizedByteArrayInputStream.java | 276 ++++ .../output/AbstractByteArrayOutputStream.java | 394 +++++ .../io/output/ByteArrayOutputStream.java | 162 ++ .../commons/io/output/NullOutputStream.java | 86 + .../io/output/StringBuilderWriter.java | 160 ++ .../io/output/ThresholdingOutputStream.java | 257 +++ .../UnsynchronizedByteArrayOutputStream.java | 229 +++ .../commons/io/output/WriterOutputStream.java | 479 ++++++ .../org/apache/commons/lang3/ArrayFill.java | 40 + .../org/apache/commons/lang3/ArrayUtils.java | 355 +++++ .../commons/lang3/CharSequenceUtils.java | 163 ++ .../org/apache/commons/lang3/ClassUtils.java | 34 + .../lang3/NotImplementedException.java | 143 ++ .../org/apache/commons/lang3/ObjectUtils.java | 148 ++ .../org/apache/commons/lang3/StringUtils.java | 498 ++++++ .../org/apache/commons/lang3/Strings.java | 464 ++++++ .../commons/lang3/SystemProperties.java | 94 ++ .../org/apache/commons/lang3/SystemUtils.java | 144 ++ .../org/apache/commons/lang3/Validate.java | 97 ++ .../lang3/exception/ExceptionUtils.java | 70 + .../lang3/function/FailableBiConsumer.java | 78 + .../lang3/function/FailableBiFunction.java | 77 + .../lang3/function/FailableFunction.java | 114 ++ .../commons/lang3/function/Suppliers.java | 71 + .../commons/lang3/function/TriFunction.java | 65 + .../commons/lang3/math/NumberUtils.java | 153 ++ .../commons/lang3/tuple/ImmutablePair.java | 204 +++ .../commons/lang3/tuple/ImmutableTriple.java | 168 ++ .../org/apache/commons/lang3/tuple/Pair.java | 264 ++++ .../apache/commons/lang3/tuple/Triple.java | 205 +++ .../common/block/column/DictionaryColumn.java | 6 +- .../java/org/apache/tsfile/utils/Pair.java | 1 + ...leGeneratorForSeriesReaderByTimestamp.java | 10 +- .../tsfile/utils/FilePathUtilsTest.java | 6 +- .../{FileUtils.java => FileTestUtils.java} | 2 +- ...eUtilsTest.java => FileTestUtilsTest.java} | 26 +- .../org/apache/tsfile/parser/PathLexer.java | 2 +- .../org/apache/tsfile/parser/PathParser.java | 2 +- .../tsfile/parser/PathParserBaseVisitor.java | 2 +- .../tsfile/parser/PathParserVisitor.java | 2 +- 139 files changed, 20799 insertions(+), 52 deletions(-) create mode 100644 java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/Get.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/Put.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/Charsets.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/IOCase.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java create mode 100644 java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java rename java/tsfile/src/test/java/org/apache/tsfile/utils/{FileUtils.java => FileTestUtils.java} (98%) rename java/tsfile/src/test/java/org/apache/tsfile/utils/{FileUtilsTest.java => FileTestUtilsTest.java} (58%) mode change 100755 => 100644 diff --git a/java/pom.xml b/java/pom.xml index a380d4a4a..b8e5a5517 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -48,16 +48,6 @@ snappy-java 1.1.10.5 - - commons-io - commons-io - 2.17.0 - - - org.apache.commons - commons-lang3 - 3.18.0 - org.lz4 lz4-java diff --git a/java/tools/pom.xml b/java/tools/pom.xml index c8a76f97f..80549e7c2 100644 --- a/java/tools/pom.xml +++ b/java/tools/pom.xml @@ -39,14 +39,6 @@ commons-cli 1.9.0 - - commons-io - commons-io - - - org.apache.commons - commons-lang3 - org.apache.tsfile tsfile diff --git a/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java b/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java index 5dd2afe53..559c8377e 100644 --- a/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java +++ b/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java @@ -36,7 +36,6 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,6 +54,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -318,7 +318,7 @@ private static void cpFile(String sourceFilePath, String targetDirectoryPath) { public static void writeToNewCSV( String headerLine, String fileAbsolutePath, List data, String newFileName) { - if (schema.hasHeader && StringUtils.isNotEmpty(headerLine)) { + if (schema.hasHeader && Objects.nonNull(headerLine) && !headerLine.isEmpty()) { data.add(0, headerLine); } String inputFileAbsolutePath = new File(inputDirectoryStr).getAbsolutePath(); diff --git a/java/tsfile/pom.xml b/java/tsfile/pom.xml index 9187b60e8..6d0d41b07 100644 --- a/java/tsfile/pom.xml +++ b/java/tsfile/pom.xml @@ -48,14 +48,6 @@ org.xerial.snappy snappy-java - - commons-io - commons-io - - - org.apache.commons - commons-lang3 - org.lz4 lz4-java diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java b/java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java new file mode 100644 index 000000000..01b92eee8 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.codec.binary; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class Hex { + + /** Used to build output as hex. */ + private static final char[] DIGITS_LOWER = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + /** Used to build output as hex. */ + private static final char[] DIGITS_UPPER = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + /** + * Converts an array of bytes into a String representing the hexadecimal values of each byte in + * order. The returned String will be double the length of the passed array, as it takes two + * characters to represent any given byte. + * + * @param data a byte[] to convert to hexadecimal characters + * @return A String containing lower-case hexadecimal characters + * @since 1.4 + */ + public static String encodeHexString(final byte[] data) { + return new String(encodeHex(data)); + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of + * each byte in order. The returned array will be double the length of the passed array, as it + * takes two characters to represent any given byte. + * + * @param data a byte[] to convert to hexadecimal characters + * @return A char[] containing lower-case hexadecimal characters + */ + public static char[] encodeHex(final byte[] data) { + return encodeHex(data, true); + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of + * each byte in order. The returned array will be double the length of the passed array, as it + * takes two characters to represent any given byte. + * + * @param data a byte[] to convert to Hex characters + * @param toLowerCase {@code true} converts to lowercase, {@code false} to uppercase + * @return A char[] containing hexadecimal characters in the selected case + * @since 1.4 + */ + public static char[] encodeHex(final byte[] data, final boolean toLowerCase) { + return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of + * each byte in order. The returned array will be double the length of the passed array, as it + * takes two characters to represent any given byte. + * + * @param data a byte[] to convert to hexadecimal characters + * @param toDigits the output alphabet (must contain at least 16 chars) + * @return A char[] containing the appropriate characters from the alphabet For best results, this + * should be either upper- or lower-case hex. + * @since 1.4 + */ + protected static char[] encodeHex(final byte[] data, final char[] toDigits) { + final int dataLength = data.length; + final char[] out = new char[dataLength << 1]; + encodeHex(data, 0, dataLength, toDigits, out, 0); + return out; + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of + * each byte in order. + * + * @param data a byte[] to convert to hexadecimal characters + * @param dataOffset the position in {@code data} to start encoding from + * @param dataLen the number of bytes from {@code dataOffset} to encode + * @param toDigits the output alphabet (must contain at least 16 chars) + * @param out a char[] which will hold the resultant appropriate characters from the alphabet. + * @param outOffset the position within {@code out} at which to start writing the encoded + * characters. + */ + private static void encodeHex( + final byte[] data, + final int dataOffset, + final int dataLen, + final char[] toDigits, + final char[] out, + final int outOffset) { + // two characters form the hex value. + for (int i = dataOffset, j = outOffset; i < dataOffset + dataLen; i++) { + out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; + out[j++] = toDigits[0x0F & data[i]]; + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java b/java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java new file mode 100644 index 000000000..f27532699 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.codec.binary; + +import java.security.MessageDigest; + +/** + * Standard {@link MessageDigest} algorithm names from the Java Cryptography Architecture + * Standard Algorithm Name Documentation. + * + *

This class is immutable and thread-safe. + * + *

+ * + * @see + * Java 8 Cryptography Architecture Standard Algorithm Name Documentation + * @see + * Java 11 Cryptography Architecture Standard Algorithm Name Documentation + * @see + * Java 17 Cryptography Architecture Standard Algorithm Name Documentation + * @see + * Java 21 Cryptography Architecture Standard Algorithm Name Documentation + * @see FIPS PUB 180-4 + * @see FIPS PUB 202 + * @since 1.7 + */ +public class MessageDigestAlgorithms { + /** The MD2 message digest algorithm defined in RFC 1319. */ + public static final String MD2 = "MD2"; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java b/java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java new file mode 100644 index 000000000..fe13454fe --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.codec.binary; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class StringUtils { + /** + * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result + * into a new byte array. + * + * @param string the String to encode, may be {@code null} + * @return encoded bytes, or {@code null} if the input string was {@code null} + * @throws NullPointerException Thrown if {@link StandardCharsets#UTF_8} is not initialized, which + * should never happen since it is required by the Java platform specification. + * @since As of 1.7, throws {@link NullPointerException} instead of UnsupportedEncodingException + * @see Charset + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesUtf8(final String string) { + return getBytes(string, StandardCharsets.UTF_8); + } + + /** + * Calls {@link String#getBytes(Charset)} + * + * @param string The string to encode (if null, return null). + * @param charset The {@link Charset} to encode the {@code String} + * @return the encoded bytes + */ + private static byte[] getBytes(final String string, final Charset charset) { + return string == null ? null : string.getBytes(charset); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java b/java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java new file mode 100644 index 000000000..5f1b742c0 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.codec.digest; + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.binary.MessageDigestAlgorithms; +import org.apache.commons.codec.binary.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class DigestUtils { + + /** + * Calculates the MD2 digest and returns the value as a 32 character hexadecimal string. + * + * @param data Data to digest + * @return MD2 digest as a hexadecimal string + * @since 1.7 + */ + public static String md2Hex(final String data) { + return Hex.encodeHexString(md2(data)); + } + + /** + * Calculates the MD2 digest and returns the value as a 16 element {@code byte[]}. + * + * @param data Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)} + * @return MD2 digest + * @since 1.7 + */ + public static byte[] md2(final String data) { + return md2(StringUtils.getBytesUtf8(data)); + } + + /** + * Calculates the MD2 digest and returns the value as a 16 element {@code byte[]}. + * + * @param data Data to digest + * @return MD2 digest + * @since 1.7 + */ + public static byte[] md2(final byte[] data) { + return getMd2Digest().digest(data); + } + + /** + * Gets an MD2 MessageDigest. + * + * @return An MD2 digest instance. + * @throws IllegalArgumentException when a {@link NoSuchAlgorithmException} is caught, which + * should never happen because MD2 is a built-in algorithm + * @see MessageDigestAlgorithms#MD2 + * @since 1.7 + */ + public static MessageDigest getMd2Digest() { + return getDigest(MessageDigestAlgorithms.MD2); + } + + public static String md5Hex(InputStream data) throws IOException { + return Hex.encodeHexString(md5(data)); + } + + public static byte[] md5(InputStream data) throws IOException { + return digest(getMd5Digest(), data); + } + + public static byte[] digest(MessageDigest messageDigest, InputStream data) throws IOException { + return updateDigest(messageDigest, data).digest(); + } + + public static MessageDigest updateDigest(MessageDigest digest, InputStream inputStream) + throws IOException { + byte[] buffer = new byte[1024]; + + for (int read = inputStream.read(buffer, 0, 1024); + read > -1; + read = inputStream.read(buffer, 0, 1024)) { + digest.update(buffer, 0, read); + } + + return digest; + } + + public static MessageDigest getMd5Digest() { + return getDigest("MD5"); + } + + public static MessageDigest getDigest(String algorithm) { + try { + return getMessageDigest(algorithm); + } catch (NoSuchAlgorithmException var2) { + throw new IllegalArgumentException(var2); + } + } + + private static MessageDigest getMessageDigest(String algorithm) throws NoSuchAlgorithmException { + return MessageDigest.getInstance(algorithm); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java b/java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java new file mode 100644 index 000000000..8ac6bc769 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +/** + * Defines a map that is bounded in size. + * + *

The size of the map can vary, but it can never exceed a preset maximum number of elements. + * This interface allows the querying of details associated with the maximum number of elements. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 3.0 + */ +public interface BoundedMap extends IterableMap { + + /** + * Returns true if this map is full and no new elements can be added. + * + * @return true if the map is full + */ + boolean isFull(); + + /** + * Gets the maximum size of the map (the bound). + * + * @return the maximum number of elements the map can hold + */ + int maxSize(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java b/java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java new file mode 100644 index 000000000..37eb6806d --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.collections4; + +import java.util.Collection; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class CollectionUtils { + /** + * Null-safe check if the specified collection is empty. + * + *

Null returns true. + * + * @param coll the collection to check, may be null + * @return true if empty or null + * @since 3.2 + */ + public static boolean isEmpty(final Collection coll) { + return coll == null || coll.isEmpty(); + } + + /** + * Null-safe check if the specified collection is not empty. + * + *

Null returns false. + * + * @param coll the collection to check, may be null + * @return true if non-null and non-empty + * @since 3.2 + */ + public static boolean isNotEmpty(final Collection coll) { + return !isEmpty(coll); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/Get.java b/java/tsfile/src/main/java/org/apache/commons/collections4/Get.java new file mode 100644 index 000000000..7f14acb45 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/Get.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +import java.util.Collection; +import java.util.Set; + +/** + * The "read" subset of the {@link java.util.Map} interface. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 4.0 + * @see Put + */ +public interface Get { + + /** + * @param key key whose presence in this map is to be tested + * @return true if this map contains a mapping for the specified key + * @see java.util.Map#containsKey(Object) + */ + boolean containsKey(Object key); + + /** + * @param value value whose presence in this map is to be tested + * @return true if this map maps one or more keys to the specified value + * @see java.util.Map#containsValue(Object) + */ + boolean containsValue(Object value); + + /** + * @return a set view of the mappings contained in this map + * @see java.util.Map#entrySet() + */ + Set> entrySet(); + + /** + * @param key the key whose associated value is to be returned + * @return the value to which the specified key is mapped, or {@code null} if this map contains no + * mapping for the key + * @see java.util.Map#get(Object) + */ + V get(Object key); + + /** + * @param key key whose mapping is to be removed from the map + * @return the previous value associated with key, or null if there was + * no mapping for key. + * @see java.util.Map#remove(Object) + */ + V remove(Object key); + + /** + * @return true if this map contains no key-value mappings + * @see java.util.Map#isEmpty() + */ + boolean isEmpty(); + + /** + * @return a set view of the keys contained in this map + * @see java.util.Map#keySet() + */ + Set keySet(); + + /** + * @return the number of key-value mappings in this map + * @see java.util.Map#size() + */ + int size(); + + /** + * @return a collection view of the values contained in this map + * @see java.util.Map#values() + */ + Collection values(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java b/java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java new file mode 100644 index 000000000..485acc7df --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +/** + * The "read" subset of the {@link java.util.Map} interface. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 4.0 + * @see Put + */ +public interface IterableGet extends Get { + /** + * Obtains a MapIterator over the map. + * + *

A map iterator is an efficient way of iterating over maps. There is no need to access the + * entry set or use Map Entry objects. + * + *

+   * IterableMap<String,Integer> map = new HashedMap<String,Integer>();
+   * MapIterator<String,Integer> it = map.mapIterator();
+   * while (it.hasNext()) {
+   *   String key = it.next();
+   *   Integer value = it.getValue();
+   *   it.setValue(value + 1);
+   * }
+   * 
+ * + * @return a map iterator + */ + MapIterator mapIterator(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java b/java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java new file mode 100644 index 000000000..c46366ffb --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +import java.util.Map; + +/** + * Defines a map that can be iterated directly without needing to create an entry set. + * + *

A map iterator is an efficient way of iterating over maps. There is no need to access the + * entry set or use Map Entry objects. + * + *

+ * IterableMap<String,Integer> map = new HashedMap<String,Integer>();
+ * MapIterator<String,Integer> it = map.mapIterator();
+ * while (it.hasNext()) {
+ *   String key = it.next();
+ *   Integer value = it.getValue();
+ *   it.setValue(value + 1);
+ * }
+ * 
+ * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 3.0 + */ +public interface IterableMap extends Map, Put, IterableGet { + // empty +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java b/java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java new file mode 100644 index 000000000..1956c7a67 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +/** + * Defines a simple key value pair. + * + *

A Map Entry has considerable additional semantics over and above a simple key-value pair. This + * interface defines the minimum key value, with just the two get methods. + * + * @param the type of the key + * @param the type of the value + * @since 3.0 + */ +public interface KeyValue { + + /** + * Gets the key from the pair. + * + * @return the key + */ + K getKey(); + + /** + * Gets the value from the pair. + * + * @return the value + */ + V getValue(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java new file mode 100644 index 000000000..68198f7d8 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +import java.util.Iterator; + +/** + * Defines an iterator that operates over a Map. + * + *

This iterator is a special version designed for maps. It can be more efficient to use this + * rather than an entry set iterator where the option is available, and it is certainly more + * convenient. + * + *

A map that provides this interface may not hold the data internally using Map Entry objects, + * thus this interface can avoid lots of object creation. + * + *

In use, this iterator iterates through the keys in the map. After each call to next() + * , the getValue() method provides direct access to the value. The value can + * also be set using setValue(). + * + *

{@code
+ * MapIterator it = map.mapIterator();
+ * while (it.hasNext()) {
+ *   String key = it.next();
+ *   Integer value = it.getValue();
+ *   it.setValue(value + 1);
+ * }
+ * }
+ * + * @param the type of the keys in the map + * @param the type of the values in the map + * @since 3.0 + */ +public interface MapIterator extends Iterator { + + /** + * Checks to see if there are more entries still to be iterated. + * + * @return true if the iterator has more elements + */ + @Override + boolean hasNext(); + + /** + * Gets the next key from the Map. + * + * @return the next key in the iteration + * @throws java.util.NoSuchElementException if the iteration is finished + */ + @Override + K next(); + + // ----------------------------------------------------------------------- + /** + * Gets the current key, which is the key returned by the last call to next(). + * + * @return the current key + * @throws IllegalStateException if next() has not yet been called + */ + K getKey(); + + /** + * Gets the current value, which is the value associated with the last key returned by + * next(). + * + * @return the current value + * @throws IllegalStateException if next() has not yet been called + */ + V getValue(); + + // ----------------------------------------------------------------------- + /** + * Removes the last returned key from the underlying Map (optional operation). + * + *

This method can be called once per call to next(). + * + * @throws UnsupportedOperationException if remove is not supported by the map + * @throws IllegalStateException if next() has not yet been called + * @throws IllegalStateException if remove() has already been called since the last + * call to next() + */ + @Override + void remove(); + + /** + * Sets the value associated with the current key (optional operation). + * + * @param value the new value + * @return the previous value + * @throws UnsupportedOperationException if setValue is not supported by the map + * @throws IllegalStateException if next() has not yet been called + * @throws IllegalStateException if remove() has been called since the last call to + * next() + */ + V setValue(V value); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java b/java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java new file mode 100644 index 000000000..d9240870a --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.collections4; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +import java.util.Map; + +public class MapUtils { + /** + * Null-safe check if the specified map is empty. + * + *

Null returns true. + * + * @param map the map to check, may be null + * @return true if empty or null + * @since 3.2 + */ + public static boolean isEmpty(final Map map) { + return map == null || map.isEmpty(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java new file mode 100644 index 000000000..44aa020f3 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +import java.util.Iterator; + +/** + * Defines an iterator that operates over an ordered container. Subset of {@link + * java.util.ListIterator}. + * + *

This iterator allows both forward and reverse iteration through the container. + * + * @param the type of elements returned by this iterator + * @since 3.0 + */ +public interface OrderedIterator extends Iterator { + + /** + * Checks to see if there is a previous element that can be iterated to. + * + * @return true if the iterator has a previous element + */ + boolean hasPrevious(); + + /** + * Gets the previous element from the container. + * + * @return the previous element in the iteration + * @throws java.util.NoSuchElementException if the iteration is finished + */ + E previous(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java b/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java new file mode 100644 index 000000000..7239f6deb --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +/** + * Defines a map that maintains order and allows both forward and backward iteration through that + * order. + * + * @param the type of the keys in the map + * @param the type of the values in the map + * @since 3.0 + */ +public interface OrderedMap extends IterableMap { + + /** + * Obtains an OrderedMapIterator over the map. + * + *

A ordered map iterator is an efficient way of iterating over maps in both directions. + * + * @return a map iterator + */ + @Override + OrderedMapIterator mapIterator(); + + /** + * Gets the first key currently in this map. + * + * @return the first key currently in this map + * @throws java.util.NoSuchElementException if this map is empty + */ + K firstKey(); + + /** + * Gets the last key currently in this map. + * + * @return the last key currently in this map + * @throws java.util.NoSuchElementException if this map is empty + */ + K lastKey(); + + /** + * Gets the next key after the one specified. + * + * @param key the key to search for next from + * @return the next key, null if no match or at end + */ + K nextKey(K key); + + /** + * Gets the previous key before the one specified. + * + * @param key the key to search for previous from + * @return the previous key, null if no match or at start + */ + K previousKey(K key); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java new file mode 100644 index 000000000..72a4f7b87 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +/** + * Defines an iterator that operates over an ordered Map. + * + *

This iterator allows both forward and reverse iteration through the map. + * + * @param the type of the keys in the map + * @param the type of the values in the map + * @since 3.0 + */ +public interface OrderedMapIterator extends MapIterator, OrderedIterator { + + /** + * Checks to see if there is a previous entry that can be iterated to. + * + * @return true if the iterator has a previous element + */ + @Override + boolean hasPrevious(); + + /** + * Gets the previous key from the Map. + * + * @return the previous key in the iteration + * @throws java.util.NoSuchElementException if the iteration is finished + */ + @Override + K previous(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/Put.java b/java/tsfile/src/main/java/org/apache/commons/collections4/Put.java new file mode 100644 index 000000000..2bff27d5e --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/Put.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +import java.util.Map; + +/** + * The "write" subset of the {@link Map} interface. + * + *

NOTE: in the original {@link Map} interface, {@link Map#put(Object, Object)} is known to have + * the same return type as {@link Map#get(Object)}, namely {@code V}. {@link Put} makes no + * assumptions in this regard (there is no association with, nor even knowledge of, a "reading" + * interface) and thus defines {@link #put(Object, Object)} as returning {@link Object}. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 4.0 + * @see Get + */ +public interface Put { + + /** + * @see Map#clear() + */ + void clear(); + + /** + * Note that the return type is Object, rather than V as in the Map interface. See the class + * Javadoc for further info. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with key, or null if there was + * no mapping for key. (A null return can also indicate that the map + * previously associated null with key, if the implementation + * supports null values.) + * @see Map#put(Object, Object) + */ + Object put(K key, V value); + + /** + * @param t mappings to be stored in this map + * @see Map#putAll(Map) + */ + void putAll(Map t); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java new file mode 100644 index 000000000..c798c3b30 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4; + +import java.util.Iterator; + +/** + * Defines an iterator that can be reset back to an initial state. + * + *

This interface allows an iterator to be repeatedly reused. + * + * @param the type of elements returned by this iterator + * @since 3.0 + */ +public interface ResettableIterator extends Iterator { + + /** Resets the iterator back to the position at which the iterator was created. */ + void reset(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java b/java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java new file mode 100644 index 000000000..69de70464 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java @@ -0,0 +1,335 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.comparators; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +/** + * A ComparatorChain is a Comparator that wraps one or more Comparators in sequence. The + * ComparatorChain calls each Comparator in sequence until either 1) any single Comparator returns a + * non-zero result (and that result is then returned), or 2) the ComparatorChain is exhausted (and + * zero is returned). This type of sorting is very similar to multi-column sorting in SQL, and this + * class allows Java classes to emulate that kind of behaviour when sorting a List. + * + *

To further facilitate SQL-like sorting, the order of any single Comparator in the list can be + * reversed. + * + *

Calling a method that adds new Comparators or changes the ascend/descend sort after + * compare(Object, Object) has been called will result in an UnsupportedOperationException. + * However, take care to not alter the underlying List of Comparators or the BitSet that + * defines the sort order. + * + *

Instances of ComparatorChain are not synchronized. The class is not thread-safe at + * construction time, but it is thread-safe to perform multiple comparisons after all the + * setup operations are complete. + * + * @param the type of objects compared by this comparator + * @since 2.0 + */ +public class ComparatorChain implements Comparator, Serializable { + + /** Serialization version from Collections 2.0. */ + private static final long serialVersionUID = -721644942746081630L; + + /** The list of comparators in the chain. */ + private final List> comparatorChain; + + /** Order - false (clear) = ascend; true (set) = descend. */ + private BitSet orderingBits = null; + + /** Whether the chain has been "locked". */ + private boolean isLocked = false; + + // ----------------------------------------------------------------------- + /** + * Construct a ComparatorChain with no Comparators. You must add at least one Comparator before + * calling the compare(Object,Object) method, or an UnsupportedOperationException is thrown + */ + public ComparatorChain() { + this(new ArrayList>(), new BitSet()); + } + + /** + * Construct a ComparatorChain with a single Comparator, sorting in the forward order + * + * @param comparator First comparator in the Comparator chain + */ + public ComparatorChain(final Comparator comparator) { + this(comparator, false); + } + + /** + * Construct a Comparator chain with a single Comparator, sorting in the given order + * + * @param comparator First Comparator in the ComparatorChain + * @param reverse false = forward sort; true = reverse sort + */ + public ComparatorChain(final Comparator comparator, final boolean reverse) { + comparatorChain = new ArrayList<>(1); + comparatorChain.add(comparator); + orderingBits = new BitSet(1); + if (reverse == true) { + orderingBits.set(0); + } + } + + /** + * Construct a ComparatorChain from the Comparators in the List. All Comparators will default to + * the forward sort order. + * + * @param list List of Comparators + * @see #ComparatorChain(List,BitSet) + */ + public ComparatorChain(final List> list) { + this(list, new BitSet(list.size())); + } + + /** + * Construct a ComparatorChain from the Comparators in the given List. The sort order of each + * column will be drawn from the given BitSet. When determining the sort order for Comparator at + * index i in the List, the ComparatorChain will call BitSet.get(i). If that method + * returns false, the forward sort order is used; a return value of true indicates + * reverse sort order. + * + * @param list List of Comparators. NOTE: This constructor does not perform a defensive copy of + * the list + * @param bits Sort order for each Comparator. Extra bits are ignored, unless extra Comparators + * are added by another method. + */ + public ComparatorChain(final List> list, final BitSet bits) { + comparatorChain = list; + orderingBits = bits; + } + + // ----------------------------------------------------------------------- + /** + * Add a Comparator to the end of the chain using the forward sort order + * + * @param comparator Comparator with the forward sort order + */ + public void addComparator(final Comparator comparator) { + addComparator(comparator, false); + } + + /** + * Add a Comparator to the end of the chain using the given sort order + * + * @param comparator Comparator to add to the end of the chain + * @param reverse false = forward sort order; true = reverse sort order + */ + public void addComparator(final Comparator comparator, final boolean reverse) { + checkLocked(); + + comparatorChain.add(comparator); + if (reverse == true) { + orderingBits.set(comparatorChain.size() - 1); + } + } + + /** + * Replace the Comparator at the given index, maintaining the existing sort order. + * + * @param index index of the Comparator to replace + * @param comparator Comparator to place at the given index + * @throws IndexOutOfBoundsException if index < 0 or index >= size() + */ + public void setComparator(final int index, final Comparator comparator) + throws IndexOutOfBoundsException { + setComparator(index, comparator, false); + } + + /** + * Replace the Comparator at the given index in the ComparatorChain, using the given sort order + * + * @param index index of the Comparator to replace + * @param comparator Comparator to set + * @param reverse false = forward sort order; true = reverse sort order + */ + public void setComparator( + final int index, final Comparator comparator, final boolean reverse) { + checkLocked(); + + comparatorChain.set(index, comparator); + if (reverse == true) { + orderingBits.set(index); + } else { + orderingBits.clear(index); + } + } + + /** + * Change the sort order at the given index in the ComparatorChain to a forward sort. + * + * @param index Index of the ComparatorChain + */ + public void setForwardSort(final int index) { + checkLocked(); + orderingBits.clear(index); + } + + /** + * Change the sort order at the given index in the ComparatorChain to a reverse sort. + * + * @param index Index of the ComparatorChain + */ + public void setReverseSort(final int index) { + checkLocked(); + orderingBits.set(index); + } + + /** + * Number of Comparators in the current ComparatorChain. + * + * @return Comparator count + */ + public int size() { + return comparatorChain.size(); + } + + /** + * Determine if modifications can still be made to the ComparatorChain. ComparatorChains cannot be + * modified once they have performed a comparison. + * + * @return true = ComparatorChain cannot be modified; false = ComparatorChain can still be + * modified. + */ + public boolean isLocked() { + return isLocked; + } + + /** + * Throws an exception if the {@link ComparatorChain} is locked. + * + * @throws UnsupportedOperationException if the {@link ComparatorChain} is locked + */ + private void checkLocked() { + if (isLocked == true) { + throw new UnsupportedOperationException( + "Comparator ordering cannot be changed after the first comparison is performed"); + } + } + + /** + * Throws an exception if the {@link ComparatorChain} is empty. + * + * @throws UnsupportedOperationException if the {@link ComparatorChain} is empty + */ + private void checkChainIntegrity() { + if (comparatorChain.size() == 0) { + throw new UnsupportedOperationException( + "ComparatorChains must contain at least one Comparator"); + } + } + + // ----------------------------------------------------------------------- + /** + * Perform comparisons on the Objects as per Comparator.compare(o1,o2). + * + * @param o1 the first object to compare + * @param o2 the second object to compare + * @return -1, 0, or 1 + * @throws UnsupportedOperationException if the ComparatorChain does not contain at least one + * Comparator + */ + @Override + public int compare(final E o1, final E o2) throws UnsupportedOperationException { + if (isLocked == false) { + checkChainIntegrity(); + isLocked = true; + } + + // iterate over all comparators in the chain + final Iterator> comparators = comparatorChain.iterator(); + for (int comparatorIndex = 0; comparators.hasNext(); ++comparatorIndex) { + + final Comparator comparator = comparators.next(); + int retval = comparator.compare(o1, o2); + if (retval != 0) { + // invert the order if it is a reverse sort + if (orderingBits.get(comparatorIndex) == true) { + if (retval > 0) { + retval = -1; + } else { + retval = 1; + } + } + return retval; + } + } + + // if comparators are exhausted, return 0 + return 0; + } + + // ----------------------------------------------------------------------- + /** + * Implement a hash code for this comparator that is consistent with {@link #equals(Object) + * equals}. + * + * @return a suitable hash code + * @since 3.0 + */ + @Override + public int hashCode() { + int hash = 0; + if (null != comparatorChain) { + hash ^= comparatorChain.hashCode(); + } + if (null != orderingBits) { + hash ^= orderingBits.hashCode(); + } + return hash; + } + + /** + * Returns true iff that Object is is a {@link Comparator} whose ordering is + * known to be equivalent to mine. + * + *

This implementation returns true iff + * object.{@link Object#getClass() getClass()} equals this.getClass(), + * and the underlying comparators and order bits are equal. Subclasses may want to override this + * behavior to remain consistent with the {@link Comparator#equals(Object)} contract. + * + * @param object the object to compare with + * @return true if equal + * @since 3.0 + */ + @Override + public boolean equals(final Object object) { + if (this == object) { + return true; + } + if (null == object) { + return false; + } + if (object.getClass().equals(this.getClass())) { + final ComparatorChain chain = (ComparatorChain) object; + return (null == orderingBits + ? null == chain.orderingBits + : orderingBits.equals(chain.orderingBits)) + && (null == comparatorChain + ? null == chain.comparatorChain + : comparatorChain.equals(chain.comparatorChain)); + } + return false; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java new file mode 100644 index 000000000..b16d8b4a8 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import java.util.NoSuchElementException; + +/** + * Provides an implementation of an empty iterator. + * + * @since 3.1 + */ +abstract class AbstractEmptyIterator { + + /** Constructor. */ + protected AbstractEmptyIterator() { + super(); + } + + public boolean hasNext() { + return false; + } + + public E next() { + throw new NoSuchElementException("Iterator contains no elements"); + } + + public boolean hasPrevious() { + return false; + } + + public E previous() { + throw new NoSuchElementException("Iterator contains no elements"); + } + + public int nextIndex() { + return 0; + } + + public int previousIndex() { + return -1; + } + + public void add(final E obj) { + throw new UnsupportedOperationException("add() not supported for empty Iterator"); + } + + public void set(final E obj) { + throw new IllegalStateException("Iterator contains no elements"); + } + + public void remove() { + throw new IllegalStateException("Iterator contains no elements"); + } + + public void reset() { + // do nothing + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java new file mode 100644 index 000000000..cb9b0b604 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +/** + * Provides an implementation of an empty map iterator. + * + * @param the type of keys + * @param the type of mapped values + * @since 4.0 + */ +public abstract class AbstractEmptyMapIterator extends AbstractEmptyIterator { + + /** Create a new AbstractEmptyMapIterator. */ + public AbstractEmptyMapIterator() { + super(); + } + + public K getKey() { + throw new IllegalStateException("Iterator contains no elements"); + } + + public V getValue() { + throw new IllegalStateException("Iterator contains no elements"); + } + + public V setValue(final V value) { + throw new IllegalStateException("Iterator contains no elements"); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java new file mode 100644 index 000000000..1342809e2 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableIterator; + +import java.util.Iterator; + +/** + * Provides an implementation of an empty iterator. + * + *

This class provides an implementation of an empty iterator. This class provides for binary + * compatibility between Commons Collections 2.1.1 and 3.1 due to issues with IteratorUtils + * . + * + * @since 2.1.1 and 3.1 + */ +public class EmptyIterator extends AbstractEmptyIterator implements ResettableIterator { + + /** + * Singleton instance of the iterator. + * + * @since 3.1 + */ + @SuppressWarnings("rawtypes") + public static final ResettableIterator RESETTABLE_INSTANCE = new EmptyIterator<>(); + + /** + * Singleton instance of the iterator. + * + * @since 2.1.1 and 3.1 + */ + @SuppressWarnings("rawtypes") + public static final Iterator INSTANCE = RESETTABLE_INSTANCE; + + /** + * Get a typed resettable empty iterator instance. + * + * @param the element type + * @return ResettableIterator<E> + */ + public static ResettableIterator resettableEmptyIterator() { + return RESETTABLE_INSTANCE; + } + + /** + * Get a typed empty iterator instance. + * + * @param the element type + * @return Iterator<E> + */ + public static Iterator emptyIterator() { + return INSTANCE; + } + + /** Constructor. */ + protected EmptyIterator() { + super(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java new file mode 100644 index 000000000..18acaace4 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.ResettableIterator; + +/** + * Provides an implementation of an empty map iterator. + * + * @param the type of keys + * @param the type of mapped values + * @since 3.1 + */ +public class EmptyMapIterator extends AbstractEmptyMapIterator + implements MapIterator, ResettableIterator { + + /** + * Singleton instance of the iterator. + * + * @since 3.1 + */ + @SuppressWarnings("rawtypes") + public static final MapIterator INSTANCE = new EmptyMapIterator<>(); + + /** + * Get a typed instance of the iterator. + * + * @param the key type + * @param the value type + * @return {@link MapIterator}<K, V> + */ + public static MapIterator emptyMapIterator() { + return INSTANCE; + } + + /** Constructor. */ + protected EmptyMapIterator() { + super(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java new file mode 100644 index 000000000..90582e208 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.OrderedIterator; +import org.apache.commons.collections4.ResettableIterator; + +/** + * Provides an implementation of an empty ordered iterator. + * + * @param the type to iterate. + * @since 3.1 + */ +public class EmptyOrderedIterator extends AbstractEmptyIterator + implements OrderedIterator, ResettableIterator { + + /** + * Singleton instance of the iterator. + * + * @since 3.1 + */ + @SuppressWarnings("rawtypes") + public static final OrderedIterator INSTANCE = new EmptyOrderedIterator<>(); + + /** + * Typed instance of the iterator. + * + * @param the element type + * @return OrderedIterator<E> + */ + public static OrderedIterator emptyOrderedIterator() { + return INSTANCE; + } + + /** Constructor. */ + protected EmptyOrderedIterator() { + super(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java new file mode 100644 index 000000000..9a3682e18 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.ResettableIterator; + +/** + * Provides an implementation of an empty ordered map iterator. + * + * @param the type of keys + * @param the type of mapped values + * @since 3.1 + */ +public class EmptyOrderedMapIterator extends AbstractEmptyMapIterator + implements OrderedMapIterator, ResettableIterator { + + /** + * Singleton instance of the iterator. + * + * @since 3.1 + */ + @SuppressWarnings("rawtypes") + public static final OrderedMapIterator INSTANCE = new EmptyOrderedMapIterator<>(); + + /** + * Get a typed instance of the iterator. + * + * @param the key type + * @param the value type + * @return {@link OrderedMapIterator}<K, V> + */ + public static OrderedMapIterator emptyOrderedMapIterator() { + return INSTANCE; + } + + /** Constructor. */ + protected EmptyOrderedMapIterator() { + super(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java b/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java new file mode 100644 index 000000000..a3e9a1454 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java @@ -0,0 +1,1394 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.map; + +import org.apache.commons.collections4.IterableMap; +import org.apache.commons.collections4.KeyValue; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.iterators.EmptyIterator; +import org.apache.commons.collections4.iterators.EmptyMapIterator; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.AbstractCollection; +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * An abstract implementation of a hash-based map which provides numerous points for subclasses to + * override. + * + *

This class implements all the features necessary for a subclass hash-based map. Key-value + * entries are stored in instances of the HashEntry class, which can be overridden and + * replaced. The iterators can similarly be replaced, without the need to replace the KeySet, + * EntrySet and Values view classes. + * + *

Overridable methods are provided to change the default hashing behaviour, and to change how + * entries are added to and removed from the map. Hopefully, all you need for unusual subclasses is + * here. + * + *

NOTE: From Commons Collections 3.1 this class extends AbstractMap. This is to provide + * backwards compatibility for ReferenceMap between v3.0 and v3.1. This extends clause will be + * removed in v5.0. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 3.0 + */ +public class AbstractHashedMap extends AbstractMap implements IterableMap { + + protected static final String NO_NEXT_ENTRY = "No next() entry in the iteration"; + protected static final String NO_PREVIOUS_ENTRY = "No previous() entry in the iteration"; + protected static final String REMOVE_INVALID = "remove() can only be called once after next()"; + protected static final String GETKEY_INVALID = + "getKey() can only be called after next() and before remove()"; + protected static final String GETVALUE_INVALID = + "getValue() can only be called after next() and before remove()"; + protected static final String SETVALUE_INVALID = + "setValue() can only be called after next() and before remove()"; + + /** The default capacity to use */ + protected static final int DEFAULT_CAPACITY = 16; + + /** The default threshold to use */ + protected static final int DEFAULT_THRESHOLD = 12; + + /** The default load factor to use */ + protected static final float DEFAULT_LOAD_FACTOR = 0.75f; + + /** The maximum capacity allowed */ + protected static final int MAXIMUM_CAPACITY = 1 << 30; + + /** An object for masking null */ + protected static final Object NULL = new Object(); + + /** Load factor, normally 0.75 */ + transient float loadFactor; + + /** The size of the map */ + transient int size; + + /** Map entries */ + transient HashEntry[] data; + + /** Size at which to rehash */ + transient int threshold; + + /** Modification count for iterators */ + transient int modCount; + + /** Entry set */ + transient EntrySet entrySet; + + /** Key set */ + transient KeySet keySet; + + /** Values */ + transient Values values; + + /** Constructor only used in deserialization, do not use otherwise. */ + protected AbstractHashedMap() { + super(); + } + + /** + * Constructor which performs no validation on the passed in parameters. + * + * @param initialCapacity the initial capacity, must be a power of two + * @param loadFactor the load factor, must be > 0.0f and generally < 1.0f + * @param threshold the threshold, must be sensible + */ + @SuppressWarnings("unchecked") + protected AbstractHashedMap( + final int initialCapacity, final float loadFactor, final int threshold) { + super(); + this.loadFactor = loadFactor; + this.data = new HashEntry[initialCapacity]; + this.threshold = threshold; + init(); + } + + /** + * Constructs a new, empty map with the specified initial capacity and default load factor. + * + * @param initialCapacity the initial capacity + * @throws IllegalArgumentException if the initial capacity is negative + */ + protected AbstractHashedMap(final int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR); + } + + /** + * Constructs a new, empty map with the specified initial capacity and load factor. + * + * @param initialCapacity the initial capacity + * @param loadFactor the load factor + * @throws IllegalArgumentException if the initial capacity is negative + * @throws IllegalArgumentException if the load factor is less than or equal to zero + */ + @SuppressWarnings("unchecked") + protected AbstractHashedMap(int initialCapacity, final float loadFactor) { + super(); + if (initialCapacity < 0) { + throw new IllegalArgumentException("Initial capacity must be a non negative number"); + } + if (loadFactor <= 0.0f || Float.isNaN(loadFactor)) { + throw new IllegalArgumentException("Load factor must be greater than 0"); + } + this.loadFactor = loadFactor; + initialCapacity = calculateNewCapacity(initialCapacity); + this.threshold = calculateThreshold(initialCapacity, loadFactor); + this.data = new HashEntry[initialCapacity]; + init(); + } + + /** + * Constructor copying elements from another map. + * + * @param map the map to copy + * @throws NullPointerException if the map is null + */ + protected AbstractHashedMap(final Map map) { + this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR); + _putAll(map); + } + + /** Initialise subclasses during construction, cloning or deserialization. */ + protected void init() {} + + // ----------------------------------------------------------------------- + /** + * Gets the value mapped to the key specified. + * + * @param key the key + * @return the mapped value, null if no match + */ + @Override + public V get(Object key) { + key = convertKey(key); + final int hashCode = hash(key); + HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index + while (entry != null) { + if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { + return entry.getValue(); + } + entry = entry.next; + } + return null; + } + + /** + * Gets the size of the map. + * + * @return the size + */ + @Override + public int size() { + return size; + } + + /** + * Checks whether the map is currently empty. + * + * @return true if the map is currently size zero + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + // ----------------------------------------------------------------------- + /** + * Checks whether the map contains the specified key. + * + * @param key the key to search for + * @return true if the map contains the key + */ + @Override + public boolean containsKey(Object key) { + key = convertKey(key); + final int hashCode = hash(key); + HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index + while (entry != null) { + if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { + return true; + } + entry = entry.next; + } + return false; + } + + /** + * Checks whether the map contains the specified value. + * + * @param value the value to search for + * @return true if the map contains the value + */ + @Override + public boolean containsValue(final Object value) { + if (value == null) { + for (final HashEntry element : data) { + HashEntry entry = element; + while (entry != null) { + if (entry.getValue() == null) { + return true; + } + entry = entry.next; + } + } + } else { + for (final HashEntry element : data) { + HashEntry entry = element; + while (entry != null) { + if (isEqualValue(value, entry.getValue())) { + return true; + } + entry = entry.next; + } + } + } + return false; + } + + // ----------------------------------------------------------------------- + /** + * Puts a key-value mapping into this map. + * + * @param key the key to add + * @param value the value to add + * @return the value previously mapped to this key, null if none + */ + @Override + public V put(final K key, final V value) { + final Object convertedKey = convertKey(key); + final int hashCode = hash(convertedKey); + final int index = hashIndex(hashCode, data.length); + HashEntry entry = data[index]; + while (entry != null) { + if (entry.hashCode == hashCode && isEqualKey(convertedKey, entry.key)) { + final V oldValue = entry.getValue(); + updateEntry(entry, value); + return oldValue; + } + entry = entry.next; + } + + addMapping(index, hashCode, key, value); + return null; + } + + /** + * Puts all the values from the specified map into this map. + * + *

This implementation iterates around the specified map and uses {@link #put(Object, Object)}. + * + * @param map the map to add + * @throws NullPointerException if the map is null + */ + @Override + public void putAll(final Map map) { + _putAll(map); + } + + /** + * Puts all the values from the specified map into this map. + * + *

This implementation iterates around the specified map and uses {@link #put(Object, Object)}. + * + *

It is private to allow the constructor to still call it even when putAll is overriden. + * + * @param map the map to add + * @throws NullPointerException if the map is null + */ + private void _putAll(final Map map) { + final int mapSize = map.size(); + if (mapSize == 0) { + return; + } + final int newSize = (int) ((size + mapSize) / loadFactor + 1); + ensureCapacity(calculateNewCapacity(newSize)); + for (final Map.Entry entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + /** + * Removes the specified mapping from this map. + * + * @param key the mapping to remove + * @return the value mapped to the removed key, null if key not in map + */ + @Override + public V remove(Object key) { + key = convertKey(key); + final int hashCode = hash(key); + final int index = hashIndex(hashCode, data.length); + HashEntry entry = data[index]; + HashEntry previous = null; + while (entry != null) { + if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { + final V oldValue = entry.getValue(); + removeMapping(entry, index, previous); + return oldValue; + } + previous = entry; + entry = entry.next; + } + return null; + } + + /** + * Clears the map, resetting the size to zero and nullifying references to avoid garbage + * collection issues. + */ + @Override + public void clear() { + modCount++; + final HashEntry[] data = this.data; + for (int i = data.length - 1; i >= 0; i--) { + data[i] = null; + } + size = 0; + } + + // ----------------------------------------------------------------------- + /** + * Converts input keys to another object for storage in the map. This implementation masks nulls. + * Subclasses can override this to perform alternate key conversions. + * + *

The reverse conversion can be changed, if required, by overriding the getKey() method in the + * hash entry. + * + * @param key the key convert + * @return the converted key + */ + protected Object convertKey(final Object key) { + return key == null ? NULL : key; + } + + /** + * Gets the hash code for the key specified. This implementation uses the additional hashing + * routine from JDK1.4. Subclasses can override this to return alternate hash codes. + * + * @param key the key to get a hash code for + * @return the hash code + */ + protected int hash(final Object key) { + // same as JDK 1.4 + int h = key.hashCode(); + h += ~(h << 9); + h ^= h >>> 14; + h += h << 4; + h ^= h >>> 10; + return h; + } + + /** + * Compares two keys, in internal converted form, to see if they are equal. This implementation + * uses the equals method and assumes neither key is null. Subclasses can override this to match + * differently. + * + * @param key1 the first key to compare passed in from outside + * @param key2 the second key extracted from the entry via entry.key + * @return true if equal + */ + protected boolean isEqualKey(final Object key1, final Object key2) { + return key1 == key2 || key1.equals(key2); + } + + /** + * Compares two values, in external form, to see if they are equal. This implementation uses the + * equals method and assumes neither value is null. Subclasses can override this to match + * differently. + * + * @param value1 the first value to compare passed in from outside + * @param value2 the second value extracted from the entry via getValue() + * @return true if equal + */ + protected boolean isEqualValue(final Object value1, final Object value2) { + return value1 == value2 || value1.equals(value2); + } + + /** + * Gets the index into the data storage for the hashCode specified. This implementation uses the + * least significant bits of the hashCode. Subclasses can override this to return alternate + * bucketing. + * + * @param hashCode the hash code to use + * @param dataSize the size of the data to pick a bucket from + * @return the bucket index + */ + protected int hashIndex(final int hashCode, final int dataSize) { + return hashCode & dataSize - 1; + } + + // ----------------------------------------------------------------------- + /** + * Gets the entry mapped to the key specified. + * + *

This method exists for subclasses that may need to perform a multi-step process accessing + * the entry. The public methods in this class don't use this method to gain a small performance + * boost. + * + * @param key the key + * @return the entry, null if no match + */ + protected HashEntry getEntry(Object key) { + key = convertKey(key); + final int hashCode = hash(key); + HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index + while (entry != null) { + if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { + return entry; + } + entry = entry.next; + } + return null; + } + + // ----------------------------------------------------------------------- + /** + * Updates an existing key-value mapping to change the value. + * + *

This implementation calls setValue() on the entry. Subclasses could override to + * handle changes to the map. + * + * @param entry the entry to update + * @param newValue the new value to store + */ + protected void updateEntry(final HashEntry entry, final V newValue) { + entry.setValue(newValue); + } + + /** + * Reuses an existing key-value mapping, storing completely new data. + * + *

This implementation sets all the data fields on the entry. Subclasses could populate + * additional entry fields. + * + * @param entry the entry to update, not null + * @param hashIndex the index in the data array + * @param hashCode the hash code of the key to add + * @param key the key to add + * @param value the value to add + */ + protected void reuseEntry( + final HashEntry entry, + final int hashIndex, + final int hashCode, + final K key, + final V value) { + entry.next = data[hashIndex]; + entry.hashCode = hashCode; + entry.key = key; + entry.value = value; + } + + // ----------------------------------------------------------------------- + /** + * Adds a new key-value mapping into this map. + * + *

This implementation calls createEntry(), addEntry() and + * checkCapacity(). It also handles changes to modCount and size. + * Subclasses could override to fully control adds to the map. + * + * @param hashIndex the index into the data array to store at + * @param hashCode the hash code of the key to add + * @param key the key to add + * @param value the value to add + */ + protected void addMapping(final int hashIndex, final int hashCode, final K key, final V value) { + modCount++; + final HashEntry entry = createEntry(data[hashIndex], hashCode, key, value); + addEntry(entry, hashIndex); + size++; + checkCapacity(); + } + + /** + * Creates an entry to store the key-value data. + * + *

This implementation creates a new HashEntry instance. Subclasses can override this to return + * a different storage class, or implement caching. + * + * @param next the next entry in sequence + * @param hashCode the hash code to use + * @param key the key to store + * @param value the value to store + * @return the newly created entry + */ + protected HashEntry createEntry( + final HashEntry next, final int hashCode, final K key, final V value) { + return new HashEntry<>(next, hashCode, convertKey(key), value); + } + + /** + * Adds an entry into this map. + * + *

This implementation adds the entry to the data storage table. Subclasses could override to + * handle changes to the map. + * + * @param entry the entry to add + * @param hashIndex the index into the data array to store at + */ + protected void addEntry(final HashEntry entry, final int hashIndex) { + data[hashIndex] = entry; + } + + // ----------------------------------------------------------------------- + /** + * Removes a mapping from the map. + * + *

This implementation calls removeEntry() and destroyEntry(). It + * also handles changes to modCount and size. Subclasses could override + * to fully control removals from the map. + * + * @param entry the entry to remove + * @param hashIndex the index into the data structure + * @param previous the previous entry in the chain + */ + protected void removeMapping( + final HashEntry entry, final int hashIndex, final HashEntry previous) { + modCount++; + removeEntry(entry, hashIndex, previous); + size--; + destroyEntry(entry); + } + + /** + * Removes an entry from the chain stored in a particular index. + * + *

This implementation removes the entry from the data storage table. The size is not updated. + * Subclasses could override to handle changes to the map. + * + * @param entry the entry to remove + * @param hashIndex the index into the data structure + * @param previous the previous entry in the chain + */ + protected void removeEntry( + final HashEntry entry, final int hashIndex, final HashEntry previous) { + if (previous == null) { + data[hashIndex] = entry.next; + } else { + previous.next = entry.next; + } + } + + /** + * Kills an entry ready for the garbage collector. + * + *

This implementation prepares the HashEntry for garbage collection. Subclasses can override + * this to implement caching (override clear as well). + * + * @param entry the entry to destroy + */ + protected void destroyEntry(final HashEntry entry) { + entry.next = null; + entry.key = null; + entry.value = null; + } + + // ----------------------------------------------------------------------- + /** + * Checks the capacity of the map and enlarges it if necessary. + * + *

This implementation uses the threshold to check if the map needs enlarging + */ + protected void checkCapacity() { + if (size >= threshold) { + final int newCapacity = data.length * 2; + if (newCapacity <= MAXIMUM_CAPACITY) { + ensureCapacity(newCapacity); + } + } + } + + /** + * Changes the size of the data structure to the capacity proposed. + * + * @param newCapacity the new capacity of the array (a power of two, less or equal to max) + */ + @SuppressWarnings("unchecked") + protected void ensureCapacity(final int newCapacity) { + final int oldCapacity = data.length; + if (newCapacity <= oldCapacity) { + return; + } + if (size == 0) { + threshold = calculateThreshold(newCapacity, loadFactor); + data = new HashEntry[newCapacity]; + } else { + final HashEntry oldEntries[] = data; + final HashEntry newEntries[] = new HashEntry[newCapacity]; + + modCount++; + for (int i = oldCapacity - 1; i >= 0; i--) { + HashEntry entry = oldEntries[i]; + if (entry != null) { + oldEntries[i] = null; // gc + do { + final HashEntry next = entry.next; + final int index = hashIndex(entry.hashCode, newCapacity); + entry.next = newEntries[index]; + newEntries[index] = entry; + entry = next; + } while (entry != null); + } + } + threshold = calculateThreshold(newCapacity, loadFactor); + data = newEntries; + } + } + + /** + * Calculates the new capacity of the map. This implementation normalizes the capacity to a power + * of two. + * + * @param proposedCapacity the proposed capacity + * @return the normalized new capacity + */ + protected int calculateNewCapacity(final int proposedCapacity) { + int newCapacity = 1; + if (proposedCapacity > MAXIMUM_CAPACITY) { + newCapacity = MAXIMUM_CAPACITY; + } else { + while (newCapacity < proposedCapacity) { + newCapacity <<= 1; // multiply by two + } + if (newCapacity > MAXIMUM_CAPACITY) { + newCapacity = MAXIMUM_CAPACITY; + } + } + return newCapacity; + } + + /** + * Calculates the new threshold of the map, where it will be resized. This implementation uses the + * load factor. + * + * @param newCapacity the new capacity + * @param factor the load factor + * @return the new resize threshold + */ + protected int calculateThreshold(final int newCapacity, final float factor) { + return (int) (newCapacity * factor); + } + + // ----------------------------------------------------------------------- + /** + * Gets the next field from a HashEntry. Used in subclasses that have no + * visibility of the field. + * + * @param entry the entry to query, must not be null + * @return the next field of the entry + * @throws NullPointerException if the entry is null + * @since 3.1 + */ + protected HashEntry entryNext(final HashEntry entry) { + return entry.next; + } + + /** + * Gets the hashCode field from a HashEntry. Used in subclasses that + * have no visibility of the field. + * + * @param entry the entry to query, must not be null + * @return the hashCode field of the entry + * @throws NullPointerException if the entry is null + * @since 3.1 + */ + protected int entryHashCode(final HashEntry entry) { + return entry.hashCode; + } + + /** + * Gets the key field from a HashEntry. Used in subclasses that have no + * visibility of the field. + * + * @param entry the entry to query, must not be null + * @return the key field of the entry + * @throws NullPointerException if the entry is null + * @since 3.1 + */ + protected K entryKey(final HashEntry entry) { + return entry.getKey(); + } + + /** + * Gets the value field from a HashEntry. Used in subclasses that have + * no visibility of the field. + * + * @param entry the entry to query, must not be null + * @return the value field of the entry + * @throws NullPointerException if the entry is null + * @since 3.1 + */ + protected V entryValue(final HashEntry entry) { + return entry.getValue(); + } + + // ----------------------------------------------------------------------- + /** + * Gets an iterator over the map. Changes made to the iterator affect this map. + * + *

A MapIterator returns the keys in the map. It also provides convenient methods to get the + * key and value, and set the value. It avoids the need to create an entrySet/keySet/values + * object. It also avoids creating the Map.Entry object. + * + * @return the map iterator + */ + @Override + public MapIterator mapIterator() { + if (size == 0) { + return EmptyMapIterator.emptyMapIterator(); + } + return new HashMapIterator<>(this); + } + + /** MapIterator implementation. */ + protected static class HashMapIterator extends HashIterator + implements MapIterator { + + protected HashMapIterator(final AbstractHashedMap parent) { + super(parent); + } + + @Override + public K next() { + return super.nextEntry().getKey(); + } + + @Override + public K getKey() { + final HashEntry current = currentEntry(); + if (current == null) { + throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID); + } + return current.getKey(); + } + + @Override + public V getValue() { + final HashEntry current = currentEntry(); + if (current == null) { + throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID); + } + return current.getValue(); + } + + @Override + public V setValue(final V value) { + final HashEntry current = currentEntry(); + if (current == null) { + throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID); + } + return current.setValue(value); + } + } + + // ----------------------------------------------------------------------- + /** + * Gets the entrySet view of the map. Changes made to the view affect this map. To simply iterate + * through the entries, use {@link #mapIterator()}. + * + * @return the entrySet view + */ + @Override + public Set> entrySet() { + if (entrySet == null) { + entrySet = new EntrySet<>(this); + } + return entrySet; + } + + /** + * Creates an entry set iterator. Subclasses can override this to return iterators with different + * properties. + * + * @return the entrySet iterator + */ + protected Iterator> createEntrySetIterator() { + if (size() == 0) { + return EmptyIterator.>emptyIterator(); + } + return new EntrySetIterator<>(this); + } + + /** EntrySet implementation. */ + protected static class EntrySet extends AbstractSet> { + /** The parent map */ + private final AbstractHashedMap parent; + + protected EntrySet(final AbstractHashedMap parent) { + super(); + this.parent = parent; + } + + @Override + public int size() { + return parent.size(); + } + + @Override + public void clear() { + parent.clear(); + } + + @Override + public boolean contains(final Object entry) { + if (entry instanceof Map.Entry) { + final Map.Entry e = (Map.Entry) entry; + final Entry match = parent.getEntry(e.getKey()); + return match != null && match.equals(e); + } + return false; + } + + @Override + public boolean remove(final Object obj) { + if (obj instanceof Map.Entry == false) { + return false; + } + if (contains(obj) == false) { + return false; + } + final Map.Entry entry = (Map.Entry) obj; + parent.remove(entry.getKey()); + return true; + } + + @Override + public Iterator> iterator() { + return parent.createEntrySetIterator(); + } + } + + /** EntrySet iterator. */ + protected static class EntrySetIterator extends HashIterator + implements Iterator> { + + protected EntrySetIterator(final AbstractHashedMap parent) { + super(parent); + } + + @Override + public Map.Entry next() { + return super.nextEntry(); + } + } + + // ----------------------------------------------------------------------- + /** + * Gets the keySet view of the map. Changes made to the view affect this map. To simply iterate + * through the keys, use {@link #mapIterator()}. + * + * @return the keySet view + */ + @Override + public Set keySet() { + if (keySet == null) { + keySet = new KeySet<>(this); + } + return keySet; + } + + /** + * Creates a key set iterator. Subclasses can override this to return iterators with different + * properties. + * + * @return the keySet iterator + */ + protected Iterator createKeySetIterator() { + if (size() == 0) { + return EmptyIterator.emptyIterator(); + } + return new KeySetIterator<>(this); + } + + /** KeySet implementation. */ + protected static class KeySet extends AbstractSet { + /** The parent map */ + private final AbstractHashedMap parent; + + protected KeySet(final AbstractHashedMap parent) { + super(); + this.parent = parent; + } + + @Override + public int size() { + return parent.size(); + } + + @Override + public void clear() { + parent.clear(); + } + + @Override + public boolean contains(final Object key) { + return parent.containsKey(key); + } + + @Override + public boolean remove(final Object key) { + final boolean result = parent.containsKey(key); + parent.remove(key); + return result; + } + + @Override + public Iterator iterator() { + return parent.createKeySetIterator(); + } + } + + /** KeySet iterator. */ + protected static class KeySetIterator extends HashIterator implements Iterator { + + @SuppressWarnings("unchecked") + protected KeySetIterator(final AbstractHashedMap parent) { + super((AbstractHashedMap) parent); + } + + @Override + public K next() { + return super.nextEntry().getKey(); + } + } + + // ----------------------------------------------------------------------- + /** + * Gets the values view of the map. Changes made to the view affect this map. To simply iterate + * through the values, use {@link #mapIterator()}. + * + * @return the values view + */ + @Override + public Collection values() { + if (values == null) { + values = new Values<>(this); + } + return values; + } + + /** + * Creates a values iterator. Subclasses can override this to return iterators with different + * properties. + * + * @return the values iterator + */ + protected Iterator createValuesIterator() { + if (size() == 0) { + return EmptyIterator.emptyIterator(); + } + return new ValuesIterator<>(this); + } + + /** Values implementation. */ + protected static class Values extends AbstractCollection { + /** The parent map */ + private final AbstractHashedMap parent; + + protected Values(final AbstractHashedMap parent) { + super(); + this.parent = parent; + } + + @Override + public int size() { + return parent.size(); + } + + @Override + public void clear() { + parent.clear(); + } + + @Override + public boolean contains(final Object value) { + return parent.containsValue(value); + } + + @Override + public Iterator iterator() { + return parent.createValuesIterator(); + } + } + + /** Values iterator. */ + protected static class ValuesIterator extends HashIterator implements Iterator { + + @SuppressWarnings("unchecked") + protected ValuesIterator(final AbstractHashedMap parent) { + super((AbstractHashedMap) parent); + } + + @Override + public V next() { + return super.nextEntry().getValue(); + } + } + + // ----------------------------------------------------------------------- + /** + * HashEntry used to store the data. + * + *

If you subclass AbstractHashedMap but not HashEntry then you will + * not be able to access the protected fields. The entryXxx() methods on + * AbstractHashedMap exist to provide the necessary access. + */ + protected static class HashEntry implements Map.Entry, KeyValue { + /** The next entry in the hash chain */ + protected HashEntry next; + + /** The hash code of the key */ + protected int hashCode; + + /** The key */ + protected Object key; + + /** The value */ + protected Object value; + + protected HashEntry( + final HashEntry next, final int hashCode, final Object key, final V value) { + super(); + this.next = next; + this.hashCode = hashCode; + this.key = key; + this.value = value; + } + + @Override + @SuppressWarnings("unchecked") + public K getKey() { + if (key == NULL) { + return null; + } + return (K) key; + } + + @Override + @SuppressWarnings("unchecked") + public V getValue() { + return (V) value; + } + + @Override + @SuppressWarnings("unchecked") + public V setValue(final V value) { + final Object old = this.value; + this.value = value; + return (V) old; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Map.Entry == false) { + return false; + } + final Map.Entry other = (Map.Entry) obj; + return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) + && (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue())); + } + + @Override + public int hashCode() { + return (getKey() == null ? 0 : getKey().hashCode()) + ^ (getValue() == null ? 0 : getValue().hashCode()); + } + + @Override + public String toString() { + return new StringBuilder().append(getKey()).append('=').append(getValue()).toString(); + } + } + + /** Base Iterator */ + protected abstract static class HashIterator { + + /** The parent map */ + private final AbstractHashedMap parent; + + /** The current index into the array of buckets */ + private int hashIndex; + + /** The last returned entry */ + private HashEntry last; + + /** The next entry */ + private HashEntry next; + + /** The modification count expected */ + private int expectedModCount; + + protected HashIterator(final AbstractHashedMap parent) { + super(); + this.parent = parent; + final HashEntry[] data = parent.data; + int i = data.length; + HashEntry next = null; + while (i > 0 && next == null) { + next = data[--i]; + } + this.next = next; + this.hashIndex = i; + this.expectedModCount = parent.modCount; + } + + public boolean hasNext() { + return next != null; + } + + protected HashEntry nextEntry() { + if (parent.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + final HashEntry newCurrent = next; + if (newCurrent == null) { + throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY); + } + final HashEntry[] data = parent.data; + int i = hashIndex; + HashEntry n = newCurrent.next; + while (n == null && i > 0) { + n = data[--i]; + } + next = n; + hashIndex = i; + last = newCurrent; + return newCurrent; + } + + protected HashEntry currentEntry() { + return last; + } + + public void remove() { + if (last == null) { + throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID); + } + if (parent.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + parent.remove(last.getKey()); + last = null; + expectedModCount = parent.modCount; + } + + @Override + public String toString() { + if (last != null) { + return "Iterator[" + last.getKey() + "=" + last.getValue() + "]"; + } + return "Iterator[]"; + } + } + + // ----------------------------------------------------------------------- + /** + * Writes the map data to the stream. This method must be overridden if a subclass must be setup + * before put() is used. + * + *

Serialization is not one of the JDK's nicest topics. Normal serialization will initialise + * the superclass before the subclass. Sometimes however, this isn't what you want, as in this + * case the put() method on read can be affected by subclass state. + * + *

The solution adopted here is to serialize the state data of this class in this protected + * method. This method must be called by the writeObject() of the first serializable + * subclass. + * + *

Subclasses may override if they have a specific field that must be present on read before + * this implementation will work. Generally, the read determines what must be serialized here, if + * anything. + * + * @param out the output stream + * @throws IOException if an error occurs while writing tothe stream + */ + protected void doWriteObject(final ObjectOutputStream out) throws IOException { + out.writeFloat(loadFactor); + out.writeInt(data.length); + out.writeInt(size); + for (final MapIterator it = mapIterator(); it.hasNext(); ) { + out.writeObject(it.next()); + out.writeObject(it.getValue()); + } + } + + /** + * Reads the map data from the stream. This method must be overridden if a subclass must be setup + * before put() is used. + * + *

Serialization is not one of the JDK's nicest topics. Normal serialization will initialise + * the superclass before the subclass. Sometimes however, this isn't what you want, as in this + * case the put() method on read can be affected by subclass state. + * + *

The solution adopted here is to deserialize the state data of this class in this protected + * method. This method must be called by the readObject() of the first serializable + * subclass. + * + *

Subclasses may override if the subclass has a specific field that must be present before + * put() or calculateThreshold() will work correctly. + * + * @param in the input stream + * @throws IOException if an error occurs while reading from the stream + * @throws ClassNotFoundException if an object read from the stream can not be loaded + */ + @SuppressWarnings("unchecked") + protected void doReadObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + loadFactor = in.readFloat(); + final int capacity = in.readInt(); + final int size = in.readInt(); + init(); + threshold = calculateThreshold(capacity, loadFactor); + data = new HashEntry[capacity]; + for (int i = 0; i < size; i++) { + final K key = (K) in.readObject(); + final V value = (V) in.readObject(); + put(key, value); + } + } + + // ----------------------------------------------------------------------- + /** + * Clones the map without cloning the keys or values. + * + *

To implement clone(), a subclass must implement the Cloneable + * interface and make this method public. + * + * @return a shallow clone + * @throws InternalError if {@link AbstractMap#clone()} failed + */ + @Override + @SuppressWarnings("unchecked") + protected AbstractHashedMap clone() { + try { + final AbstractHashedMap cloned = (AbstractHashedMap) super.clone(); + cloned.data = new HashEntry[data.length]; + cloned.entrySet = null; + cloned.keySet = null; + cloned.values = null; + cloned.modCount = 0; + cloned.size = 0; + cloned.init(); + cloned.putAll(this); + return cloned; + } catch (final CloneNotSupportedException ex) { + throw new InternalError(); + } + } + + /** + * Compares this map with another. + * + * @param obj the object to compare to + * @return true if equal + */ + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Map == false) { + return false; + } + final Map map = (Map) obj; + if (map.size() != size()) { + return false; + } + final MapIterator it = mapIterator(); + try { + while (it.hasNext()) { + final Object key = it.next(); + final Object value = it.getValue(); + if (value == null) { + if (map.get(key) != null || map.containsKey(key) == false) { + return false; + } + } else { + if (value.equals(map.get(key)) == false) { + return false; + } + } + } + } catch (final ClassCastException ignored) { + return false; + } catch (final NullPointerException ignored) { + return false; + } + return true; + } + + /** + * Gets the standard Map hashCode. + * + * @return the hash code defined in the Map interface + */ + @Override + public int hashCode() { + int total = 0; + final Iterator> it = createEntrySetIterator(); + while (it.hasNext()) { + total += it.next().hashCode(); + } + return total; + } + + /** + * Gets the map as a String. + * + * @return a string version of the map + */ + @Override + public String toString() { + if (size() == 0) { + return "{}"; + } + final StringBuilder buf = new StringBuilder(32 * size()); + buf.append('{'); + + final MapIterator it = mapIterator(); + boolean hasNext = it.hasNext(); + while (hasNext) { + final K key = it.next(); + final V value = it.getValue(); + buf.append(key == this ? "(this Map)" : key) + .append('=') + .append(value == this ? "(this Map)" : value); + + hasNext = it.hasNext(); + if (hasNext) { + buf.append(',').append(' '); + } + } + + buf.append('}'); + return buf.toString(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java b/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java new file mode 100644 index 000000000..e27e21693 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java @@ -0,0 +1,610 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.map; + +import org.apache.commons.collections4.OrderedIterator; +import org.apache.commons.collections4.OrderedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.ResettableIterator; +import org.apache.commons.collections4.iterators.EmptyOrderedIterator; +import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator; + +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * An abstract implementation of a hash-based map that links entries to create an ordered map and + * which provides numerous points for subclasses to override. + * + *

This class implements all the features necessary for a subclass linked hash-based map. + * Key-value entries are stored in instances of the LinkEntry class which can be + * overridden and replaced. The iterators can similarly be replaced, without the need to replace the + * KeySet, EntrySet and Values view classes. + * + *

Overridable methods are provided to change the default hashing behaviour, and to change how + * entries are added to and removed from the map. Hopefully, all you need for unusual subclasses is + * here. + * + *

This implementation maintains order by original insertion, but subclasses may work + * differently. The OrderedMap interface is implemented to provide access to + * bidirectional iteration and extra convenience methods. + * + *

The orderedMapIterator() method provides direct access to a bidirectional + * iterator. The iterators from the other views can also be cast to OrderedIterator if + * required. + * + *

All the available iterators can be reset back to the start by casting to + * ResettableIterator and calling reset(). + * + *

The implementation is also designed to be subclassed, with lots of useful methods exposed. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 3.0 + */ +public abstract class AbstractLinkedMap extends AbstractHashedMap + implements OrderedMap { + + /** Header in the linked list */ + transient LinkEntry header; + + /** Constructor only used in deserialization, do not use otherwise. */ + protected AbstractLinkedMap() { + super(); + } + + /** + * Constructor which performs no validation on the passed in parameters. + * + * @param initialCapacity the initial capacity, must be a power of two + * @param loadFactor the load factor, must be > 0.0f and generally < 1.0f + * @param threshold the threshold, must be sensible + */ + protected AbstractLinkedMap( + final int initialCapacity, final float loadFactor, final int threshold) { + super(initialCapacity, loadFactor, threshold); + } + + /** + * Constructs a new, empty map with the specified initial capacity. + * + * @param initialCapacity the initial capacity + * @throws IllegalArgumentException if the initial capacity is negative + */ + protected AbstractLinkedMap(final int initialCapacity) { + super(initialCapacity); + } + + /** + * Constructs a new, empty map with the specified initial capacity and load factor. + * + * @param initialCapacity the initial capacity + * @param loadFactor the load factor + * @throws IllegalArgumentException if the initial capacity is negative + * @throws IllegalArgumentException if the load factor is less than zero + */ + protected AbstractLinkedMap(final int initialCapacity, final float loadFactor) { + super(initialCapacity, loadFactor); + } + + /** + * Constructor copying elements from another map. + * + * @param map the map to copy + * @throws NullPointerException if the map is null + */ + protected AbstractLinkedMap(final Map map) { + super(map); + } + + /** + * Initialise this subclass during construction. + * + *

NOTE: As from v3.2 this method calls {@link #createEntry(HashEntry, int, Object, Object)} to + * create the map entry object. + */ + @Override + protected void init() { + header = createEntry(null, -1, null, null); + header.before = header.after = header; + } + + // ----------------------------------------------------------------------- + /** + * Checks whether the map contains the specified value. + * + * @param value the value to search for + * @return true if the map contains the value + */ + @Override + public boolean containsValue(final Object value) { + // override uses faster iterator + if (value == null) { + for (LinkEntry entry = header.after; entry != header; entry = entry.after) { + if (entry.getValue() == null) { + return true; + } + } + } else { + for (LinkEntry entry = header.after; entry != header; entry = entry.after) { + if (isEqualValue(value, entry.getValue())) { + return true; + } + } + } + return false; + } + + /** + * Clears the map, resetting the size to zero and nullifying references to avoid garbage + * collection issues. + */ + @Override + public void clear() { + // override to reset the linked list + super.clear(); + header.before = header.after = header; + } + + // ----------------------------------------------------------------------- + /** + * Gets the first key in the map, which is the first inserted. + * + * @return the eldest key + */ + @Override + public K firstKey() { + if (size == 0) { + throw new NoSuchElementException("Map is empty"); + } + return header.after.getKey(); + } + + /** + * Gets the last key in the map, which is the most recently inserted. + * + * @return the most recently inserted key + */ + @Override + public K lastKey() { + if (size == 0) { + throw new NoSuchElementException("Map is empty"); + } + return header.before.getKey(); + } + + /** + * Gets the next key in sequence. + * + * @param key the key to get after + * @return the next key + */ + @Override + public K nextKey(final Object key) { + final LinkEntry entry = getEntry(key); + return entry == null || entry.after == header ? null : entry.after.getKey(); + } + + @Override + protected LinkEntry getEntry(final Object key) { + return (LinkEntry) super.getEntry(key); + } + + /** + * Gets the previous key in sequence. + * + * @param key the key to get before + * @return the previous key + */ + @Override + public K previousKey(final Object key) { + final LinkEntry entry = getEntry(key); + return entry == null || entry.before == header ? null : entry.before.getKey(); + } + + // ----------------------------------------------------------------------- + /** + * Gets the key at the specified index. + * + * @param index the index to retrieve + * @return the key at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + */ + protected LinkEntry getEntry(final int index) { + if (index < 0) { + throw new IndexOutOfBoundsException("Index " + index + " is less than zero"); + } + if (index >= size) { + throw new IndexOutOfBoundsException("Index " + index + " is invalid for size " + size); + } + LinkEntry entry; + if (index < size / 2) { + // Search forwards + entry = header.after; + for (int currentIndex = 0; currentIndex < index; currentIndex++) { + entry = entry.after; + } + } else { + // Search backwards + entry = header; + for (int currentIndex = size; currentIndex > index; currentIndex--) { + entry = entry.before; + } + } + return entry; + } + + /** + * Adds an entry into this map, maintaining insertion order. + * + *

This implementation adds the entry to the data storage table and to the end of the linked + * list. + * + * @param entry the entry to add + * @param hashIndex the index into the data array to store at + */ + @Override + protected void addEntry(final HashEntry entry, final int hashIndex) { + final LinkEntry link = (LinkEntry) entry; + link.after = header; + link.before = header.before; + header.before.after = link; + header.before = link; + data[hashIndex] = link; + } + + /** + * Creates an entry to store the data. + * + *

This implementation creates a new LinkEntry instance. + * + * @param next the next entry in sequence + * @param hashCode the hash code to use + * @param key the key to store + * @param value the value to store + * @return the newly created entry + */ + @Override + protected LinkEntry createEntry( + final HashEntry next, final int hashCode, final K key, final V value) { + return new LinkEntry<>(next, hashCode, convertKey(key), value); + } + + /** + * Removes an entry from the map and the linked list. + * + *

This implementation removes the entry from the linked list chain, then calls the superclass + * implementation. + * + * @param entry the entry to remove + * @param hashIndex the index into the data structure + * @param previous the previous entry in the chain + */ + @Override + protected void removeEntry( + final HashEntry entry, final int hashIndex, final HashEntry previous) { + final LinkEntry link = (LinkEntry) entry; + link.before.after = link.after; + link.after.before = link.before; + link.after = null; + link.before = null; + super.removeEntry(entry, hashIndex, previous); + } + + // ----------------------------------------------------------------------- + /** + * Gets the before field from a LinkEntry. Used in subclasses that have + * no visibility of the field. + * + * @param entry the entry to query, must not be null + * @return the before field of the entry + * @throws NullPointerException if the entry is null + * @since 3.1 + */ + protected LinkEntry entryBefore(final LinkEntry entry) { + return entry.before; + } + + /** + * Gets the after field from a LinkEntry. Used in subclasses that have + * no visibility of the field. + * + * @param entry the entry to query, must not be null + * @return the after field of the entry + * @throws NullPointerException if the entry is null + * @since 3.1 + */ + protected LinkEntry entryAfter(final LinkEntry entry) { + return entry.after; + } + + // ----------------------------------------------------------------------- + /** {@inheritDoc} */ + @Override + public OrderedMapIterator mapIterator() { + if (size == 0) { + return EmptyOrderedMapIterator.emptyOrderedMapIterator(); + } + return new LinkMapIterator<>(this); + } + + /** MapIterator implementation. */ + protected static class LinkMapIterator extends LinkIterator + implements OrderedMapIterator, ResettableIterator { + + protected LinkMapIterator(final AbstractLinkedMap parent) { + super(parent); + } + + @Override + public K next() { + return super.nextEntry().getKey(); + } + + @Override + public K previous() { + return super.previousEntry().getKey(); + } + + @Override + public K getKey() { + final LinkEntry current = currentEntry(); + if (current == null) { + throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID); + } + return current.getKey(); + } + + @Override + public V getValue() { + final LinkEntry current = currentEntry(); + if (current == null) { + throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID); + } + return current.getValue(); + } + + @Override + public V setValue(final V value) { + final LinkEntry current = currentEntry(); + if (current == null) { + throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID); + } + return current.setValue(value); + } + } + + // ----------------------------------------------------------------------- + /** + * Creates an entry set iterator. Subclasses can override this to return iterators with different + * properties. + * + * @return the entrySet iterator + */ + @Override + protected Iterator> createEntrySetIterator() { + if (size() == 0) { + return EmptyOrderedIterator.>emptyOrderedIterator(); + } + return new EntrySetIterator<>(this); + } + + /** EntrySet iterator. */ + protected static class EntrySetIterator extends LinkIterator + implements OrderedIterator>, ResettableIterator> { + + protected EntrySetIterator(final AbstractLinkedMap parent) { + super(parent); + } + + @Override + public Map.Entry next() { + return super.nextEntry(); + } + + @Override + public Map.Entry previous() { + return super.previousEntry(); + } + } + + // ----------------------------------------------------------------------- + /** + * Creates a key set iterator. Subclasses can override this to return iterators with different + * properties. + * + * @return the keySet iterator + */ + @Override + protected Iterator createKeySetIterator() { + if (size() == 0) { + return EmptyOrderedIterator.emptyOrderedIterator(); + } + return new KeySetIterator<>(this); + } + + /** KeySet iterator. */ + protected static class KeySetIterator extends LinkIterator + implements OrderedIterator, ResettableIterator { + + @SuppressWarnings("unchecked") + protected KeySetIterator(final AbstractLinkedMap parent) { + super((AbstractLinkedMap) parent); + } + + @Override + public K next() { + return super.nextEntry().getKey(); + } + + @Override + public K previous() { + return super.previousEntry().getKey(); + } + } + + // ----------------------------------------------------------------------- + /** + * Creates a values iterator. Subclasses can override this to return iterators with different + * properties. + * + * @return the values iterator + */ + @Override + protected Iterator createValuesIterator() { + if (size() == 0) { + return EmptyOrderedIterator.emptyOrderedIterator(); + } + return new ValuesIterator<>(this); + } + + /** Values iterator. */ + protected static class ValuesIterator extends LinkIterator + implements OrderedIterator, ResettableIterator { + + @SuppressWarnings("unchecked") + protected ValuesIterator(final AbstractLinkedMap parent) { + super((AbstractLinkedMap) parent); + } + + @Override + public V next() { + return super.nextEntry().getValue(); + } + + @Override + public V previous() { + return super.previousEntry().getValue(); + } + } + + // ----------------------------------------------------------------------- + /** + * LinkEntry that stores the data. + * + *

If you subclass AbstractLinkedMap but not LinkEntry then you will + * not be able to access the protected fields. The entryXxx() methods on + * AbstractLinkedMap exist to provide the necessary access. + */ + protected static class LinkEntry extends HashEntry { + /** The entry before this one in the order */ + protected LinkEntry before; + + /** The entry after this one in the order */ + protected LinkEntry after; + + /** + * Constructs a new entry. + * + * @param next the next entry in the hash bucket sequence + * @param hashCode the hash code + * @param key the key + * @param value the value + */ + protected LinkEntry( + final HashEntry next, final int hashCode, final Object key, final V value) { + super(next, hashCode, key, value); + } + } + + /** Base Iterator that iterates in link order. */ + protected abstract static class LinkIterator { + + /** The parent map */ + protected final AbstractLinkedMap parent; + + /** The current (last returned) entry */ + protected LinkEntry last; + + /** The next entry */ + protected LinkEntry next; + + /** The modification count expected */ + protected int expectedModCount; + + protected LinkIterator(final AbstractLinkedMap parent) { + super(); + this.parent = parent; + this.next = parent.header.after; + this.expectedModCount = parent.modCount; + } + + public boolean hasNext() { + return next != parent.header; + } + + public boolean hasPrevious() { + return next.before != parent.header; + } + + protected LinkEntry nextEntry() { + if (parent.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + if (next == parent.header) { + throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY); + } + last = next; + next = next.after; + return last; + } + + protected LinkEntry previousEntry() { + if (parent.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + final LinkEntry previous = next.before; + if (previous == parent.header) { + throw new NoSuchElementException(AbstractHashedMap.NO_PREVIOUS_ENTRY); + } + next = previous; + last = previous; + return last; + } + + protected LinkEntry currentEntry() { + return last; + } + + public void remove() { + if (last == null) { + throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID); + } + if (parent.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + parent.remove(last.getKey()); + last = null; + expectedModCount = parent.modCount; + } + + public void reset() { + last = null; + next = parent.header.after; + } + + @Override + public String toString() { + if (last != null) { + return "Iterator[" + last.getKey() + "=" + last.getValue() + "]"; + } + return "Iterator[]"; + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java b/java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java new file mode 100644 index 000000000..2b4371fbc --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java @@ -0,0 +1,572 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.map; + +import org.apache.commons.collections4.BoundedMap; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Map; + +/** + * A Map implementation with a fixed maximum size which removes the least recently used + * entry if an entry is added when full. + * + *

The least recently used algorithm works on the get and put operations only. Iteration of any + * kind, including setting the value by iteration, does not change the order. Queries such as + * containsKey and containsValue or access via views also do not change the order. + * + *

A somewhat subtle ramification of the least recently used algorithm is that calls to {@link + * #get(Object)} stand a very good chance of modifying the map's iteration order and thus + * invalidating any iterators currently in use. It is therefore suggested that iterations over an + * {@link LRUMap} instance access entry values only through a {@link + * org.apache.commons.collections4.MapIterator MapIterator} or {@link #entrySet()} iterator. + * + *

The map implements OrderedMap and entries may be queried using the bidirectional + * OrderedMapIterator. The order returned is least recently used to most recently used. + * Iterators from map views can also be cast to OrderedIterator if required. + * + *

All the available iterators can be reset back to the start by casting to + * ResettableIterator and calling reset(). + * + *

Note that LRUMap is not synchronized and is not thread-safe. If you wish to + * use this map from multiple threads concurrently, you must use appropriate synchronization. The + * simplest approach is to wrap this map using {@link java.util.Collections#synchronizedMap(Map)}. + * This class may throw NullPointerException's when accessed by concurrent threads. + * + * @param the type of the keys in this map + * @param the type of the values in this map + * @since 3.0 (previously in main package v1.0) + */ +public class LRUMap extends AbstractLinkedMap + implements BoundedMap, Serializable, Cloneable { + + /** Serialisation version */ + private static final long serialVersionUID = -612114643488955218L; + + /** Default maximum size */ + protected static final int DEFAULT_MAX_SIZE = 100; + + /** Maximum size */ + private transient int maxSize; + + /** Scan behaviour */ + private boolean scanUntilRemovable; + + /** Constructs a new empty map with a maximum size of 100. */ + public LRUMap() { + this(DEFAULT_MAX_SIZE, DEFAULT_LOAD_FACTOR, false); + } + + /** + * Constructs a new, empty map with the specified maximum size. + * + * @param maxSize the maximum size of the map + * @throws IllegalArgumentException if the maximum size is less than one + */ + public LRUMap(final int maxSize) { + this(maxSize, DEFAULT_LOAD_FACTOR); + } + + /** + * Constructs a new, empty map with the specified maximum size. + * + * @param maxSize the maximum size of the map + * @param initialSize the initial size of the map + * @throws IllegalArgumentException if the maximum size is less than one + * @throws IllegalArgumentException if the initial size is negative or larger than the maximum + * size + * @since 4.1 + */ + public LRUMap(final int maxSize, final int initialSize) { + this(maxSize, initialSize, DEFAULT_LOAD_FACTOR); + } + + /** + * Constructs a new, empty map with the specified maximum size. + * + * @param maxSize the maximum size of the map + * @param scanUntilRemovable scan until a removeable entry is found, default false + * @throws IllegalArgumentException if the maximum size is less than one + * @since 3.1 + */ + public LRUMap(final int maxSize, final boolean scanUntilRemovable) { + this(maxSize, DEFAULT_LOAD_FACTOR, scanUntilRemovable); + } + + /** + * Constructs a new, empty map with the specified max capacity and load factor. + * + * @param maxSize the maximum size of the map + * @param loadFactor the load factor + * @throws IllegalArgumentException if the maximum size is less than one + * @throws IllegalArgumentException if the load factor is less than zero + */ + public LRUMap(final int maxSize, final float loadFactor) { + this(maxSize, loadFactor, false); + } + + /** + * Constructs a new, empty map with the specified max / initial capacity and load factor. + * + * @param maxSize the maximum size of the map + * @param initialSize the initial size of the map + * @param loadFactor the load factor + * @throws IllegalArgumentException if the maximum size is less than one + * @throws IllegalArgumentException if the initial size is negative or larger than the maximum + * size + * @throws IllegalArgumentException if the load factor is less than zero + * @since 4.1 + */ + public LRUMap(final int maxSize, final int initialSize, final float loadFactor) { + this(maxSize, initialSize, loadFactor, false); + } + + /** + * Constructs a new, empty map with the specified max capacity and load factor. + * + * @param maxSize the maximum size of the map + * @param loadFactor the load factor + * @param scanUntilRemovable scan until a removeable entry is found, default false + * @throws IllegalArgumentException if the maximum size is less than one + * @throws IllegalArgumentException if the load factor is less than zero + * @since 3.1 + */ + public LRUMap(final int maxSize, final float loadFactor, final boolean scanUntilRemovable) { + this(maxSize, maxSize, loadFactor, scanUntilRemovable); + } + + /** + * Constructs a new, empty map with the specified max / initial capacity and load factor. + * + * @param maxSize the maximum size of the map + * @param initialSize the initial size of the map + * @param loadFactor the load factor + * @param scanUntilRemovable scan until a removeable entry is found, default false + * @throws IllegalArgumentException if the maximum size is less than one + * @throws IllegalArgumentException if the initial size is negative or larger than the maximum + * size + * @throws IllegalArgumentException if the load factor is less than zero + * @since 4.1 + */ + public LRUMap( + final int maxSize, + final int initialSize, + final float loadFactor, + final boolean scanUntilRemovable) { + + super(initialSize, loadFactor); + if (maxSize < 1) { + throw new IllegalArgumentException("LRUMap max size must be greater than 0"); + } + if (initialSize > maxSize) { + throw new IllegalArgumentException("LRUMap initial size must not be greather than max size"); + } + this.maxSize = maxSize; + this.scanUntilRemovable = scanUntilRemovable; + } + + /** + * Constructor copying elements from another map. + * + *

The maximum size is set from the map's size. + * + * @param map the map to copy + * @throws NullPointerException if the map is null + * @throws IllegalArgumentException if the map is empty + */ + public LRUMap(final Map map) { + this(map, false); + } + + /** + * Constructor copying elements from another map. + * + *

The maximum size is set from the map's size. + * + * @param map the map to copy + * @param scanUntilRemovable scan until a removeable entry is found, default false + * @throws NullPointerException if the map is null + * @throws IllegalArgumentException if the map is empty + * @since 3.1 + */ + public LRUMap(final Map map, final boolean scanUntilRemovable) { + this(map.size(), DEFAULT_LOAD_FACTOR, scanUntilRemovable); + putAll(map); + } + + // ----------------------------------------------------------------------- + /** + * Gets the value mapped to the key specified. + * + *

This operation changes the position of the key in the map to the most recently used position + * (last). + * + * @param key the key + * @return the mapped value, null if no match + */ + @Override + public V get(final Object key) { + return get(key, true); + } + + /** + * Gets the value mapped to the key specified. + * + *

If {@code updateToMRU} is {@code true}, the position of the key in the map is changed to the + * most recently used position (last), otherwise the iteration order is not changed by this + * operation. + * + * @param key the key + * @param updateToMRU whether the key shall be updated to the most recently used position + * @return the mapped value, null if no match + * @since 4.1 + */ + public V get(final Object key, final boolean updateToMRU) { + final LinkEntry entry = getEntry(key); + if (entry == null) { + return null; + } + if (updateToMRU) { + moveToMRU(entry); + } + return entry.getValue(); + } + + // ----------------------------------------------------------------------- + /** + * Moves an entry to the MRU position at the end of the list. + * + *

This implementation moves the updated entry to the end of the list. + * + * @param entry the entry to update + */ + protected void moveToMRU(final LinkEntry entry) { + if (entry.after != header) { + modCount++; + // remove + if (entry.before == null) { + throw new IllegalStateException( + "Entry.before is null." + + " This should not occur if your keys are immutable, and you have used synchronization properly."); + } + entry.before.after = entry.after; + entry.after.before = entry.before; + // add first + entry.after = header; + entry.before = header.before; + header.before.after = entry; + header.before = entry; + } else if (entry == header) { + throw new IllegalStateException( + "Can't move header to MRU" + + " This should not occur if your keys are immutable, and you have used synchronization properly."); + } + } + + /** + * Updates an existing key-value mapping. + * + *

This implementation moves the updated entry to the end of the list using {@link + * #moveToMRU(AbstractLinkedMap.LinkEntry)}. + * + * @param entry the entry to update + * @param newValue the new value to store + */ + @Override + protected void updateEntry(final HashEntry entry, final V newValue) { + moveToMRU((LinkEntry) entry); // handles modCount + entry.setValue(newValue); + } + + /** + * Adds a new key-value mapping into this map. + * + *

This implementation checks the LRU size and determines whether to discard an entry or not + * using {@link #removeLRU(AbstractLinkedMap.LinkEntry)}. + * + *

From Commons Collections 3.1 this method uses {@link #isFull()} rather than accessing + * size and maxSize directly. It also handles the scanUntilRemovable + * functionality. + * + * @param hashIndex the index into the data array to store at + * @param hashCode the hash code of the key to add + * @param key the key to add + * @param value the value to add + */ + @Override + protected void addMapping(final int hashIndex, final int hashCode, final K key, final V value) { + if (isFull()) { + LinkEntry reuse = header.after; + boolean removeLRUEntry = false; + if (scanUntilRemovable) { + while (reuse != header && reuse != null) { + if (removeLRU(reuse)) { + removeLRUEntry = true; + break; + } + reuse = reuse.after; + } + if (reuse == null) { + throw new IllegalStateException( + "Entry.after=null, header.after=" + + header.after + + " header.before=" + + header.before + + " key=" + + key + + " value=" + + value + + " size=" + + size + + " maxSize=" + + maxSize + + " This should not occur if your keys are immutable, and you have used synchronization properly."); + } + } else { + removeLRUEntry = removeLRU(reuse); + } + + if (removeLRUEntry) { + if (reuse == null) { + throw new IllegalStateException( + "reuse=null, header.after=" + + header.after + + " header.before=" + + header.before + + " key=" + + key + + " value=" + + value + + " size=" + + size + + " maxSize=" + + maxSize + + " This should not occur if your keys are immutable, and you have used synchronization properly."); + } + reuseMapping(reuse, hashIndex, hashCode, key, value); + } else { + super.addMapping(hashIndex, hashCode, key, value); + } + } else { + super.addMapping(hashIndex, hashCode, key, value); + } + } + + /** + * Reuses an entry by removing it and moving it to a new place in the map. + * + *

This method uses {@link #removeEntry}, {@link #reuseEntry} and {@link #addEntry}. + * + * @param entry the entry to reuse + * @param hashIndex the index into the data array to store at + * @param hashCode the hash code of the key to add + * @param key the key to add + * @param value the value to add + */ + protected void reuseMapping( + final LinkEntry entry, + final int hashIndex, + final int hashCode, + final K key, + final V value) { + // find the entry before the entry specified in the hash table + // remember that the parameters (except the first) refer to the new entry, + // not the old one + try { + final int removeIndex = hashIndex(entry.hashCode, data.length); + final HashEntry[] tmp = data; // may protect against some sync issues + HashEntry loop = tmp[removeIndex]; + HashEntry previous = null; + while (loop != entry && loop != null) { + previous = loop; + loop = loop.next; + } + if (loop == null) { + throw new IllegalStateException( + "Entry.next=null, data[removeIndex]=" + + data[removeIndex] + + " previous=" + + previous + + " key=" + + key + + " value=" + + value + + " size=" + + size + + " maxSize=" + + maxSize + + " This should not occur if your keys are immutable, and you have used synchronization properly."); + } + + // reuse the entry + modCount++; + removeEntry(entry, removeIndex, previous); + reuseEntry(entry, hashIndex, hashCode, key, value); + addEntry(entry, hashIndex); + } catch (final NullPointerException ex) { + throw new IllegalStateException( + "NPE, entry=" + + entry + + " entryIsHeader=" + + (entry == header) + + " key=" + + key + + " value=" + + value + + " size=" + + size + + " maxSize=" + + maxSize + + " This should not occur if your keys are immutable, and you have used synchronization properly."); + } + } + + /** + * Subclass method to control removal of the least recently used entry from the map. + * + *

This method exists for subclasses to override. A subclass may wish to provide cleanup of + * resources when an entry is removed. For example: + * + *

+   * protected boolean removeLRU(LinkEntry entry) {
+   *   releaseResources(entry.getValue());  // release resources held by entry
+   *   return true;  // actually delete entry
+   * }
+   * 
+ * + *

Alternatively, a subclass may choose to not remove the entry or selectively keep certain LRU + * entries. For example: + * + *

+   * protected boolean removeLRU(LinkEntry entry) {
+   *   if (entry.getKey().toString().startsWith("System.")) {
+   *     return false;  // entry not removed from LRUMap
+   *   } else {
+   *     return true;  // actually delete entry
+   *   }
+   * }
+   * 
+ * + * The effect of returning false is dependent on the scanUntilRemovable flag. If the flag is true, + * the next LRU entry will be passed to this method and so on until one returns false and is + * removed, or every entry in the map has been passed. If the scanUntilRemovable flag is false, + * the map will exceed the maximum size. + * + *

NOTE: Commons Collections 3.0 passed the wrong entry to this method. This is fixed in + * version 3.1 onwards. + * + * @param entry the entry to be removed + * @return {@code true} + */ + protected boolean removeLRU(final LinkEntry entry) { + return true; + } + + // ----------------------------------------------------------------------- + /** + * Returns true if this map is full and no new mappings can be added. + * + * @return true if the map is full + */ + @Override + public boolean isFull() { + return size >= maxSize; + } + + /** + * Gets the maximum size of the map (the bound). + * + * @return the maximum number of elements the map can hold + */ + @Override + public int maxSize() { + return maxSize; + } + + /** + * Whether this LRUMap will scan until a removable entry is found when the map is full. + * + * @return true if this map scans + * @since 3.1 + */ + public boolean isScanUntilRemovable() { + return scanUntilRemovable; + } + + // ----------------------------------------------------------------------- + /** + * Clones the map without cloning the keys or values. + * + * @return a shallow clone + */ + @Override + public LRUMap clone() { + return (LRUMap) super.clone(); + } + + /** + * Write the map out using a custom routine. + * + * @param out the output stream + * @throws IOException if an error occurs while writing to the stream + */ + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + doWriteObject(out); + } + + /** + * Read the map in using a custom routine. + * + * @param in the input stream + * @throws IOException if an error occurs while reading from the stream + * @throws ClassNotFoundException if an object read from the stream can not be loaded + */ + private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + doReadObject(in); + } + + /** + * Writes the data necessary for put() to work in deserialization. + * + * @param out the output stream + * @throws IOException if an error occurs while writing to the stream + */ + @Override + protected void doWriteObject(final ObjectOutputStream out) throws IOException { + out.writeInt(maxSize); + super.doWriteObject(out); + } + + /** + * Reads the data necessary for put() to work in the superclass. + * + * @param in the input stream + * @throws IOException if an error occurs while reading from the stream + * @throws ClassNotFoundException if an object read from the stream can not be loaded + */ + @Override + protected void doReadObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + maxSize = in.readInt(); + super.doReadObject(in); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/Charsets.java b/java/tsfile/src/main/java/org/apache/commons/io/Charsets.java new file mode 100644 index 000000000..f73e3bcf4 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/Charsets.java @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Collections; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * Charsets required of every implementation of the Java platform. + * + *

From the Java documentation Standard + * charsets: + * + *

Every implementation of the Java platform is required to support the following character + * encodings. Consult the release documentation for your implementation to see if any other + * encodings are supported. Consult the release documentation for your implementation to see if any + * other encodings are supported. + * + *

    + *
  • {@code US-ASCII}
    + * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character + * set. + *
  • {@code ISO-8859-1}
    + * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1. + *
  • {@code UTF-8}
    + * Eight-bit Unicode Transformation Format. + *
  • {@code UTF-16BE}
    + * Sixteen-bit Unicode Transformation Format, big-endian byte order. + *
  • {@code UTF-16LE}
    + * Sixteen-bit Unicode Transformation Format, little-endian byte order. + *
  • {@code UTF-16}
    + * Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial + * byte-order mark (either order accepted on input, big-endian used on output.) + *
+ * + * @see Standard + * charsets + * @since 2.3 + */ +public class Charsets { + + // + // This class should only contain Charset instances for required encodings. This guarantees that + // it will load + // correctly and without delay on all Java platforms. + // + + private static final SortedMap STANDARD_CHARSET_MAP; + + static { + final SortedMap standardCharsetMap = + new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + standardCharsetMap.put(StandardCharsets.ISO_8859_1.name(), StandardCharsets.ISO_8859_1); + standardCharsetMap.put(StandardCharsets.US_ASCII.name(), StandardCharsets.US_ASCII); + standardCharsetMap.put(StandardCharsets.UTF_16.name(), StandardCharsets.UTF_16); + standardCharsetMap.put(StandardCharsets.UTF_16BE.name(), StandardCharsets.UTF_16BE); + standardCharsetMap.put(StandardCharsets.UTF_16LE.name(), StandardCharsets.UTF_16LE); + standardCharsetMap.put(StandardCharsets.UTF_8.name(), StandardCharsets.UTF_8); + STANDARD_CHARSET_MAP = Collections.unmodifiableSortedMap(standardCharsetMap); + } + + /** + * CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1. + * + *

Every implementation of the Java platform is required to support this character encoding. + * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; + + /** + * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of the Unicode + * character set. + * + *

Every implementation of the Java platform is required to support this character encoding. + * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated public static final Charset US_ASCII = StandardCharsets.US_ASCII; + + /** + * Sixteen-bit Unicode Transformation Format, The byte order specified by a mandatory initial + * byte-order mark (either order accepted on input, big-endian used on output) + * + *

Every implementation of the Java platform is required to support this character encoding. + * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated public static final Charset UTF_16 = StandardCharsets.UTF_16; + + /** + * Sixteen-bit Unicode Transformation Format, big-endian byte order. + * + *

Every implementation of the Java platform is required to support this character encoding. + * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated public static final Charset UTF_16BE = StandardCharsets.UTF_16BE; + + /** + * Sixteen-bit Unicode Transformation Format, little-endian byte order. + * + *

Every implementation of the Java platform is required to support this character encoding. + * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated public static final Charset UTF_16LE = StandardCharsets.UTF_16LE; + + /** + * Eight-bit Unicode Transformation Format. + * + *

Every implementation of the Java platform is required to support this character encoding. + * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated public static final Charset UTF_8 = StandardCharsets.UTF_8; + + /** + * Constructs a sorted map from canonical charset names to charset objects required of every + * implementation of the Java platform. + * + *

From the Java documentation Standard + * charsets: + * + * @return An immutable, case-insensitive map from canonical charset names to charset objects. + * @see Charset#availableCharsets() + * @since 2.5 + */ + public static SortedMap requiredCharsets() { + return STANDARD_CHARSET_MAP; + } + + /** + * Returns the given Charset or the default Charset if the given Charset is null. + * + * @param charset A charset or null. + * @return the given Charset or the default Charset if the given Charset is null + */ + public static Charset toCharset(final Charset charset) { + return charset == null ? Charset.defaultCharset() : charset; + } + + /** + * Returns the given charset if non-null, otherwise return defaultCharset. + * + * @param charset The charset to test, may be null. + * @param defaultCharset The charset to return if charset is null, may be null. + * @return a Charset . + * @since 2.12.0 + */ + public static Charset toCharset(final Charset charset, final Charset defaultCharset) { + return charset == null ? defaultCharset : charset; + } + + /** + * Returns a Charset for the named charset. If the name is null, return the default Charset. + * + * @param charsetName The name of the requested charset, may be null. + * @return a Charset for the named charset. + * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception). + */ + public static Charset toCharset(final String charsetName) throws UnsupportedCharsetException { + return toCharset(charsetName, Charset.defaultCharset()); + } + + /** + * Returns a Charset for the named charset. If the name is null, return the given default Charset. + * + * @param charsetName The name of the requested charset, may be null. + * @param defaultCharset The name charset to return if charsetName is null, may be null. + * @return a Charset for the named charset. + * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception). + * @since 2.12.0 + */ + public static Charset toCharset(final String charsetName, final Charset defaultCharset) + throws UnsupportedCharsetException { + return charsetName == null ? defaultCharset : Charset.forName(charsetName); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java b/java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java new file mode 100644 index 000000000..6e6098be7 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import java.io.File; +import java.io.IOException; + +/** + * Indicates that a file already exists. + * + * @since 2.0 + */ +public class FileExistsException extends IOException { + + /** Defines the serial version UID. */ + private static final long serialVersionUID = 1L; + + /** Default Constructor. */ + public FileExistsException() {} + + /** + * Constructs an instance with the specified file. + * + * @param file The file that exists + */ + public FileExistsException(final File file) { + super("File " + file + " exists"); + } + + /** + * Constructs an instance with the specified message. + * + * @param message The error message + */ + public FileExistsException(final String message) { + super(message); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java b/java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java new file mode 100644 index 000000000..f3f1f9cb2 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java @@ -0,0 +1,884 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import org.apache.commons.io.file.Counters; +import org.apache.commons.io.file.PathUtils; +import org.apache.commons.io.file.StandardDeleteOption; +import org.apache.commons.io.filefilter.FileFileFilter; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.io.function.IOConsumer; +import org.apache.commons.io.function.Uncheck; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.file.CopyOption; +import java.nio.file.FileVisitOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class FileUtils { + + private static final String PROTOCOL_FILE = "file"; + + public static void deleteDirectory(final File directory) throws IOException { + Objects.requireNonNull(directory, "directory"); + if (!directory.exists()) { + return; + } + if (!isSymlink(directory)) { + cleanDirectory(directory); + } + delete(directory); + } + + public static File delete(final File file) throws IOException { + Objects.requireNonNull(file, PROTOCOL_FILE); + Files.delete(file.toPath()); + return file; + } + + public static boolean isSymlink(final File file) { + return file != null && Files.isSymbolicLink(file.toPath()); + } + + private static void requireDirectoryExists(final File directory, final String name) + throws FileNotFoundException { + Objects.requireNonNull(directory, name); + if (!directory.isDirectory()) { + if (directory.exists()) { + throw new IllegalArgumentException( + "Parameter '" + name + "' is not a directory: '" + directory + "'"); + } + throw new FileNotFoundException("Directory '" + directory + "' does not exist."); + } + } + + private static File[] listFiles(final File directory, final FileFilter fileFilter) + throws IOException { + requireDirectoryExists(directory, "directory"); + final File[] files = + fileFilter == null ? directory.listFiles() : directory.listFiles(fileFilter); + if (files == null) { + // null if the directory does not denote a directory, or if an I/O error occurs. + throw new IOException("Unknown I/O error listing contents of directory: " + directory); + } + return files; + } + + /** + * Creates all directories for a File object, including any necessary but non-existent parent + * directories. If the {@code directory} already exists or is null, nothing happens. + * + *

Calls {@link File#mkdirs()} and throws an {@link IOException} on failure. + * + * @param directory the receiver for {@code mkdirs()}. If the {@code directory} already exists or + * is null, nothing happens. + * @throws IOException if the directory was not created along with all its parent directories. + * @throws IOException if the given file object is not a directory. + * @throws SecurityException See {@link File#mkdirs()}. + * @see File#mkdirs() + */ + public static void forceMkdir(final File directory) throws IOException { + mkdirs(directory); + } + + /** + * Creates all directories for a File object, including any necessary but non-existent parent + * directories. If the parent directory already exists or is null, nothing happens. + * + *

Calls {@link File#mkdirs()} for the parent of @{code file}. + * + * @param file file with parents to create, must not be {@code null}. + * @throws NullPointerException if the file is {@code null}. + * @throws IOException if the directory was not created along with all its parent directories. + * @throws SecurityException See {@link File#mkdirs()}. + * @see File#mkdirs() + * @since 2.5 + */ + public static void forceMkdirParent(File file) throws IOException { + forceMkdir(getParentFile(Objects.requireNonNull(file, "file"))); + } + + public static void forceDelete(final File file) throws IOException { + Objects.requireNonNull(file, PROTOCOL_FILE); + + final Counters.PathCounters deleteCounters; + try { + deleteCounters = + PathUtils.delete( + file.toPath(), + PathUtils.EMPTY_LINK_OPTION_ARRAY, + StandardDeleteOption.OVERRIDE_READ_ONLY); + } catch (final IOException ex) { + throw new IOException("Cannot delete file: " + file, ex); + } + if (deleteCounters.getFileCounter().get() < 1 + && deleteCounters.getDirectoryCounter().get() < 1) { + // didn't find a file to delete. + throw new FileNotFoundException("File does not exist: " + file); + } + } + + public static void cleanDirectory(final File directory) throws IOException { + IOConsumer.forAll(FileUtils::forceDelete, listFiles(directory, null)); + } + + public static void moveFile( + final File srcFile, final File destFile, final CopyOption... copyOptions) throws IOException { + validateMoveParameters(srcFile, destFile); + checkFileExists(srcFile, "srcFile"); + requireAbsent(destFile, "destFile"); + final boolean rename = srcFile.renameTo(destFile); + if (!rename) { + // Don't interfere with file date on move, handled by StandardCopyOption.COPY_ATTRIBUTES + copyFile(srcFile, destFile, false, copyOptions); + if (!srcFile.delete()) { + deleteQuietly(destFile); + throw new IOException( + "Failed to delete original file '" + srcFile + "' after copy to '" + destFile + "'"); + } + } + } + + private static void checkFileExists(final File file, final String name) + throws FileNotFoundException { + Objects.requireNonNull(file, name); + if (!file.isFile()) { + if (file.exists()) { + throw new IllegalArgumentException("Parameter '" + name + "' is not a file: " + file); + } + if (!Files.isSymbolicLink(file.toPath())) { + throw new FileNotFoundException("Source '" + file + "' does not exist"); + } + } + } + + /** + * Requires that the given {@link File} is a file. + * + * @param file The {@link File} to check. + * @param name The parameter name to use in the exception message. + * @return the given file. + * @throws NullPointerException if the given {@link File} is {@code null}. + * @throws IllegalArgumentException if the given {@link File} does not exist or is not a file. + */ + private static File requireFile(final File file, final String name) { + Objects.requireNonNull(file, name); + if (!file.isFile()) { + throw new IllegalArgumentException("Parameter '" + name + "' is not a file: " + file); + } + return file; + } + + private static void requireAbsent(final File file, final String name) throws FileExistsException { + if (file.exists()) { + throw new FileExistsException( + String.format("File element in parameter '%s' already exists: '%s'", name, file)); + } + } + + public static void copyFile(final File srcFile, final File destFile) throws IOException { + copyFile(srcFile, destFile, StandardCopyOption.REPLACE_EXISTING); + } + + public static void copyFile( + final File srcFile, final File destFile, final CopyOption... copyOptions) throws IOException { + copyFile(srcFile, destFile, true, copyOptions); + } + + public static void copyFile( + final File srcFile, + final File destFile, + final boolean preserveFileDate, + final CopyOption... copyOptions) + throws IOException { + Objects.requireNonNull(destFile, "destination"); + checkFileExists(srcFile, "srcFile"); + requireCanonicalPathsNotEquals(srcFile, destFile); + createParentDirectories(destFile); + if (destFile.exists()) { + checkFileExists(destFile, "destFile"); + } + + final Path srcPath = srcFile.toPath(); + + Files.copy(srcPath, destFile.toPath(), copyOptions); + + // On Windows, the last modified time is copied by default. + if (preserveFileDate && !Files.isSymbolicLink(srcPath) && !setTimes(srcFile, destFile)) { + throw new IOException("Cannot set the file time."); + } + } + + private static void requireCanonicalPathsNotEquals(final File file1, final File file2) + throws IOException { + final String canonicalPath = file1.getCanonicalPath(); + if (canonicalPath.equals(file2.getCanonicalPath())) { + throw new IllegalArgumentException( + String.format( + "File canonical paths are equal: '%s' (file1='%s', file2='%s')", + canonicalPath, file1, file2)); + } + } + + public static File createParentDirectories(final File file) throws IOException { + return mkdirs(getParentFile(file)); + } + + private static File mkdirs(final File directory) throws IOException { + if (directory != null && !directory.mkdirs() && !directory.isDirectory()) { + throw new IOException("Cannot create directory '" + directory + "'."); + } + return directory; + } + + private static File getParentFile(final File file) { + return file == null ? null : file.getParentFile(); + } + + private static boolean setTimes(final File sourceFile, final File targetFile) { + Objects.requireNonNull(sourceFile, "sourceFile"); + Objects.requireNonNull(targetFile, "targetFile"); + try { + // Set creation, modified, last accessed to match source file + final BasicFileAttributes srcAttr = + Files.readAttributes(sourceFile.toPath(), BasicFileAttributes.class); + final BasicFileAttributeView destAttrView = + Files.getFileAttributeView(targetFile.toPath(), BasicFileAttributeView.class); + // null guards are not needed; BasicFileAttributes.setTimes(...) is null safe + destAttrView.setTimes( + srcAttr.lastModifiedTime(), srcAttr.lastAccessTime(), srcAttr.creationTime()); + return true; + } catch (final IOException ignored) { + // Fallback: Only set modified time to match source file + return targetFile.setLastModified(sourceFile.lastModified()); + } + } + + public static boolean deleteQuietly(final File file) { + if (file == null) { + return false; + } + try { + if (file.isDirectory()) { + cleanDirectory(file); + } + } catch (final Exception ignored) { + // ignore + } + + try { + return file.delete(); + } catch (final Exception ignored) { + return false; + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Writes a CharSequence to a file creating the file if it does not exist. + * + * @param file the file to write + * @param data the content to write to the file + * @param charset the charset to use, {@code null} means platform default + * @param append if {@code true}, then the data will be added to the end of the file rather than + * overwriting + * @throws IOException in case of an I/O error + * @since 2.3 + */ + public static void write( + final File file, final CharSequence data, final Charset charset, final boolean append) + throws IOException { + writeStringToFile(file, Objects.toString(data, null), charset, append); + } + + /** + * Writes a String to a file creating the file if it does not exist. + * + * @param file the file to write + * @param data the content to write to the file + * @param charset the charset to use, {@code null} means platform default + * @param append if {@code true}, then the String will be added to the end of the file rather than + * overwriting + * @throws IOException in case of an I/O error + * @since 2.3 + */ + public static void writeStringToFile( + final File file, final String data, final Charset charset, final boolean append) + throws IOException { + try (OutputStream out = newOutputStream(file, append)) { + IOUtils.write(data, out, charset); + } + } + + /** + * Creates a new OutputStream by opening or creating a file, returning an output stream that may + * be used to write bytes to the file. + * + * @param append Whether or not to append. + * @param file the File. + * @return a new OutputStream. + * @throws IOException if an I/O error occurs. + * @see PathUtils#newOutputStream(Path, boolean) + * @since 2.12.0 + */ + public static OutputStream newOutputStream(final File file, final boolean append) + throws IOException { + return PathUtils.newOutputStream(Objects.requireNonNull(file, "file").toPath(), append); + } + + /** + * Moves a file preserving attributes. + * + *

Shorthand for {@code moveFile(srcFile, destFile, StandardCopyOption.COPY_ATTRIBUTES)}. + * + *

When the destination file is on another file system, do a "copy and delete". + * + * @param srcFile the file to be moved. + * @param destFile the destination file. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws FileExistsException if the destination file exists. + * @throws FileNotFoundException if the source file does not exist. + * @throws IOException if source or destination is invalid. + * @throws IOException if an error occurs. + * @since 1.4 + */ + public static void moveFile(final File srcFile, final File destFile) throws IOException { + moveFile(srcFile, destFile, StandardCopyOption.COPY_ATTRIBUTES); + } + + /** + * Copies bytes from the URL {@code source} to a file {@code destination}. The directories up to + * {@code destination} will be created if they don't already exist. {@code destination} will be + * overwritten if it already exists. + * + *

Warning: this method does not set a connection or read timeout and thus might block forever. + * Use {@link #copyURLToFile(URL, File, int, int)} with reasonable timeouts to prevent this. + * + * @param source the {@link URL} to copy bytes from, must not be {@code null} + * @param destination the non-directory {@link File} to write bytes to (possibly overwriting), + * must not be {@code null} + * @throws IOException if {@code source} URL cannot be opened + * @throws IOException if {@code destination} is a directory + * @throws IOException if {@code destination} cannot be written + * @throws IOException if {@code destination} needs creating but can't be + * @throws IOException if an IO error occurs during copying + */ + public static void copyURLToFile(final URL source, final File destination) throws IOException { + final Path path = destination.toPath(); + PathUtils.createParentDirectories(path); + PathUtils.copy(source::openStream, path, StandardCopyOption.REPLACE_EXISTING); + } + + /** + * Moves a file to a directory. + * + *

If {@code createDestDir} is true, creates all destination parent directories, including any + * necessary but non-existent parent directories. + * + * @param srcFile the file to be moved. + * @param destDir the destination file. + * @param createDestDir If {@code true} create the destination directory, otherwise if {@code + * false} throw an IOException. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws FileExistsException if the destination file exists. + * @throws FileNotFoundException if the source file does not exist. + * @throws IOException if source or destination is invalid. + * @throws IOException if the directory was not created along with all its parent directories, if + * enabled. + * @throws IOException if an error occurs or setting the last-modified time didn't succeed. + * @throws SecurityException See {@link File#mkdirs()}. + * @since 1.4 + */ + public static void moveFileToDirectory( + final File srcFile, final File destDir, final boolean createDestDir) throws IOException { + validateMoveParameters(srcFile, destDir); + if (!destDir.exists() && createDestDir) { + mkdirs(destDir); + } + requireExistsChecked(destDir, "destDir"); + requireDirectory(destDir, "destDir"); + moveFile(srcFile, new File(destDir, srcFile.getName())); + } + + /** + * Validates the given arguments. + * + *

    + *
  • Throws {@link NullPointerException} if {@code source} is null + *
  • Throws {@link NullPointerException} if {@code destination} is null + *
  • Throws {@link FileNotFoundException} if {@code source} does not exist + *
+ * + * @param source the file or directory to be moved. + * @param destination the destination file or directory. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws FileNotFoundException if the source file does not exist. + */ + private static void validateMoveParameters(final File source, final File destination) + throws FileNotFoundException { + Objects.requireNonNull(source, "source"); + Objects.requireNonNull(destination, "destination"); + if (!source.exists()) { + throw new FileNotFoundException("Source '" + source + "' does not exist"); + } + } + + /** + * Requires that the given {@link File} exists and throws an {@link FileNotFoundException} if it + * doesn't. + * + * @param file The {@link File} to check. + * @param fileParamName The parameter name to use in the exception message in case of {@code null} + * input. + * @return the given file. + * @throws NullPointerException if the given {@link File} is {@code null}. + * @throws FileNotFoundException if the given {@link File} does not exist. + */ + private static File requireExistsChecked(final File file, final String fileParamName) + throws FileNotFoundException { + Objects.requireNonNull(file, fileParamName); + if (!file.exists()) { + throw new FileNotFoundException( + "File system element for parameter '" + + fileParamName + + "' does not exist: '" + + file + + "'"); + } + return file; + } + + /** + * Requires that the given {@link File} is a directory. + * + * @param directory The {@link File} to check. + * @param name The parameter name to use in the exception message in case of null input or if the + * file is not a directory. + * @return the given directory. + * @throws NullPointerException if the given {@link File} is {@code null}. + * @throws IllegalArgumentException if the given {@link File} does not exist or is not a + * directory. + */ + private static File requireDirectory(final File directory, final String name) { + Objects.requireNonNull(directory, name); + if (!directory.isDirectory()) { + throw new IllegalArgumentException( + "Parameter '" + name + "' is not a directory: '" + directory + "'"); + } + return directory; + } + + /** + * Finds files within a given directory (and optionally its subdirectories) which match an array + * of extensions. + * + * @param directory the directory to search in + * @param extensions an array of extensions, ex. {"java","xml"}. If this parameter is {@code + * null}, all files are returned. + * @param recursive if true all subdirectories are searched as well + * @return a collection of java.io.File with the matching files + */ + public static Collection listFiles( + final File directory, final String[] extensions, final boolean recursive) { + return Uncheck.apply(d -> toList(streamFiles(d, recursive, extensions)), directory); + } + + private static List toList(final Stream stream) { + return stream.collect(Collectors.toList()); + } + + /** + * Streams over the files in a given directory (and optionally its subdirectories) which match an + * array of extensions. + * + * @param directory the directory to search in + * @param recursive if true all subdirectories are searched as well + * @param extensions an array of extensions, ex. {"java","xml"}. If this parameter is {@code + * null}, all files are returned. + * @return an iterator of java.io.File with the matching files + * @since 2.9.0 + */ + public static Stream streamFiles( + final File directory, final boolean recursive, final String... extensions) + throws IOException { + // @formatter:off + final IOFileFilter filter = + extensions == null + ? FileFileFilter.INSTANCE + : FileFileFilter.INSTANCE.and(new SuffixFileFilter(toSuffixes(extensions))); + // @formatter:on + return PathUtils.walk( + directory.toPath(), filter, toMaxDepth(recursive), false, FileVisitOption.FOLLOW_LINKS) + .map(Path::toFile); + } + + /** + * Converts an array of file extensions to suffixes. + * + * @param extensions an array of extensions. Format: {"java", "xml"} + * @return an array of suffixes. Format: {".java", ".xml"} + * @throws NullPointerException if the parameter is null + */ + private static String[] toSuffixes(final String... extensions) { + return Stream.of(Objects.requireNonNull(extensions, "extensions")) + .map(e -> "." + e) + .toArray(String[]::new); + } + + /** + * Converts whether or not to recurse into a recursion max depth. + * + * @param recursive whether or not to recurse + * @return the recursion depth + */ + private static int toMaxDepth(final boolean recursive) { + return recursive ? Integer.MAX_VALUE : 1; + } + + /** + * Converts each of an array of {@link File} to a {@link URL}. + * + *

Returns an array of the same size as the input. + * + * @param files the files to convert, must not be {@code null} + * @return an array of URLs matching the input + * @throws IOException if a file cannot be converted + * @throws NullPointerException if the parameter is null + */ + public static URL[] toURLs(final File... files) throws IOException { + Objects.requireNonNull(files, "files"); + final URL[] urls = new URL[files.length]; + for (int i = 0; i < urls.length; i++) { + urls[i] = files[i].toURI().toURL(); + } + return urls; + } + + public static void moveDirectory(final File srcDir, final File destDir) throws IOException { + validateMoveParameters(srcDir, destDir); + requireDirectory(srcDir, "srcDir"); + requireAbsent(destDir, "destDir"); + if (!srcDir.renameTo(destDir)) { + if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath() + File.separator)) { + throw new IOException( + "Cannot move directory: " + srcDir + " to a subdirectory of itself: " + destDir); + } + copyDirectory(srcDir, destDir); + deleteDirectory(srcDir); + if (srcDir.exists()) { + throw new IOException( + "Failed to delete original directory '" + srcDir + "' after copy to '" + destDir + "'"); + } + } + } + + /** + * Copies a whole directory to a new location preserving the file dates. + * + *

This method copies the specified directory and all its child directories and files to the + * specified destination. The destination is the new location and name of the directory. + * + *

The destination directory is created if it does not exist. If the destination directory did + * exist, then this method merges the source with the destination, with the source taking + * precedence. + * + *

Note: Setting {@code preserveFileDate} to {@code true} tries to preserve + * the file's last modified date/times using {@link BasicFileAttributeView#setTimes(FileTime, + * FileTime, FileTime)}, however it is not guaranteed that the operation will succeed. If the + * modification operation fails it will fallback to {@link File#setLastModified(long)} and if that + * fails, the methods throws IOException. + * + * @param srcDir an existing directory to copy, must not be {@code null}. + * @param destDir the new directory, must not be {@code null}. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws IllegalArgumentException if the source or destination is invalid. + * @throws FileNotFoundException if the source does not exist. + * @throws IOException if an error occurs or setting the last-modified time didn't succeed. + * @since 1.1 + */ + public static void copyDirectory(final File srcDir, final File destDir) throws IOException { + copyDirectory(srcDir, destDir, true); + } + + /** + * Copies a whole directory to a new location. + * + *

This method copies the contents of the specified source directory to within the specified + * destination directory. + * + *

The destination directory is created if it does not exist. If the destination directory did + * exist, then this method merges the source with the destination, with the source taking + * precedence. + * + *

Note: Setting {@code preserveFileDate} to {@code true} tries to preserve + * the files' last modified date/times using {@link File#setLastModified(long)}, however it is not + * guaranteed that those operations will succeed. If the modification operation fails, the methods + * throws IOException. + * + * @param srcDir an existing directory to copy, must not be {@code null}. + * @param destDir the new directory, must not be {@code null}. + * @param preserveFileDate true if the file date of the copy should be the same as the original. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws IllegalArgumentException if the source or destination is invalid. + * @throws FileNotFoundException if the source does not exist. + * @throws IOException if an error occurs or setting the last-modified time didn't succeed. + * @since 1.1 + */ + public static void copyDirectory( + final File srcDir, final File destDir, final boolean preserveFileDate) throws IOException { + copyDirectory(srcDir, destDir, null, preserveFileDate); + } + + /** + * Copies a filtered directory to a new location. + * + *

This method copies the contents of the specified source directory to within the specified + * destination directory. + * + *

The destination directory is created if it does not exist. If the destination directory did + * exist, then this method merges the source with the destination, with the source taking + * precedence. + * + *

Note: Setting {@code preserveFileDate} to {@code true} tries to preserve + * the file's last modified date/times using {@link BasicFileAttributeView#setTimes(FileTime, + * FileTime, FileTime)}, however it is not guaranteed that the operation will succeed. If the + * modification operation fails it will fallback to {@link File#setLastModified(long)} and if that + * fails, the methods throws IOException. Example: Copy directories only + * + *

+   * // only copy the directory structure
+   * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
+   * 
+ * + * Example: Copy directories and txt files + * + *
+   * // Create a filter for ".txt" files
+   * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+   * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+   *
+   * // Create a filter for either directories or ".txt" files
+   * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+   *
+   * // Copy using the filter
+   * FileUtils.copyDirectory(srcDir, destDir, filter, false);
+   * 
+ * + * @param srcDir an existing directory to copy, must not be {@code null}. + * @param destDir the new directory, must not be {@code null}. + * @param filter the filter to apply, null means copy all directories and files. + * @param preserveFileDate true if the file date of the copy should be the same as the original. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws IllegalArgumentException if the source or destination is invalid. + * @throws FileNotFoundException if the source does not exist. + * @throws IOException if an error occurs or setting the last-modified time didn't succeed. + * @since 1.4 + */ + public static void copyDirectory( + final File srcDir, + final File destDir, + final FileFilter filter, + final boolean preserveFileDate) + throws IOException { + copyDirectory(srcDir, destDir, filter, preserveFileDate, StandardCopyOption.REPLACE_EXISTING); + } + + /** + * Copies a filtered directory to a new location. + * + *

This method copies the contents of the specified source directory to within the specified + * destination directory. + * + *

The destination directory is created if it does not exist. If the destination directory did + * exist, then this method merges the source with the destination, with the source taking + * precedence. + * + *

Note: Setting {@code preserveFileDate} to {@code true} tries to preserve + * the file's last modified date/times using {@link BasicFileAttributeView#setTimes(FileTime, + * FileTime, FileTime)}, however it is not guaranteed that the operation will succeed. If the + * modification operation fails it will fallback to {@link File#setLastModified(long)} and if that + * fails, the methods throws IOException. Example: Copy directories only + * + *

+   * // only copy the directory structure
+   * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
+   * 
+ * + * Example: Copy directories and txt files + * + *
+   * // Create a filter for ".txt" files
+   * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+   * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+   *
+   * // Create a filter for either directories or ".txt" files
+   * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+   *
+   * // Copy using the filter
+   * FileUtils.copyDirectory(srcDir, destDir, filter, false);
+   * 
+ * + * @param srcDir an existing directory to copy, must not be {@code null} + * @param destDir the new directory, must not be {@code null} + * @param fileFilter the filter to apply, null means copy all directories and files + * @param preserveFileDate true if the file date of the copy should be the same as the original + * @param copyOptions options specifying how the copy should be done, for example {@link + * StandardCopyOption}. + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws IllegalArgumentException if the source or destination is invalid. + * @throws FileNotFoundException if the source does not exist. + * @throws IOException if an error occurs or setting the last-modified time didn't succeed. + * @since 2.8.0 + */ + public static void copyDirectory( + final File srcDir, + final File destDir, + final FileFilter fileFilter, + final boolean preserveFileDate, + final CopyOption... copyOptions) + throws IOException { + requireFileCopy(srcDir, destDir); + requireDirectory(srcDir, "srcDir"); + requireCanonicalPathsNotEquals(srcDir, destDir); + + // Cater for destination being directory within the source directory (see IO-141) + List exclusionList = null; + final String srcDirCanonicalPath = srcDir.getCanonicalPath(); + final String destDirCanonicalPath = destDir.getCanonicalPath(); + if (destDirCanonicalPath.startsWith(srcDirCanonicalPath)) { + final File[] srcFiles = listFiles(srcDir, fileFilter); + if (srcFiles.length > 0) { + exclusionList = new ArrayList<>(srcFiles.length); + for (final File srcFile : srcFiles) { + exclusionList.add(new File(destDir, srcFile.getName()).getCanonicalPath()); + } + } + } + doCopyDirectory(srcDir, destDir, fileFilter, exclusionList, preserveFileDate, copyOptions); + } + + /** + * Requires parameter attributes for a file copy operation. + * + * @param source the source file + * @param destination the destination + * @throws NullPointerException if any of the given {@link File}s are {@code null}. + * @throws FileNotFoundException if the source does not exist. + */ + private static void requireFileCopy(final File source, final File destination) + throws FileNotFoundException { + requireExistsChecked(source, "source"); + Objects.requireNonNull(destination, "destination"); + } + + /** + * Internal copy directory method. Creates all destination parent directories, including any + * necessary but non-existent parent directories. + * + * @param srcDir the validated source directory, must not be {@code null}. + * @param destDir the validated destination directory, must not be {@code null}. + * @param fileFilter the filter to apply, null means copy all directories and files. + * @param exclusionList List of files and directories to exclude from the copy, may be null. + * @param preserveDirDate preserve the directories last modified dates. + * @param copyOptions options specifying how the copy should be done, see {@link + * StandardCopyOption}. + * @throws IOException if the directory was not created along with all its parent directories. + * @throws SecurityException See {@link File#mkdirs()}. + */ + private static void doCopyDirectory( + final File srcDir, + final File destDir, + final FileFilter fileFilter, + final List exclusionList, + final boolean preserveDirDate, + final CopyOption... copyOptions) + throws IOException { + // recurse dirs, copy files. + final File[] srcFiles = listFiles(srcDir, fileFilter); + requireDirectoryIfExists(destDir, "destDir"); + mkdirs(destDir); + requireCanWrite(destDir, "destDir"); + for (final File srcFile : srcFiles) { + final File dstFile = new File(destDir, srcFile.getName()); + if (exclusionList == null || !exclusionList.contains(srcFile.getCanonicalPath())) { + if (srcFile.isDirectory()) { + doCopyDirectory( + srcFile, dstFile, fileFilter, exclusionList, preserveDirDate, copyOptions); + } else { + copyFile(srcFile, dstFile, preserveDirDate, copyOptions); + } + } + } + // Do this last, as the above has probably affected directory metadata + if (preserveDirDate) { + setTimes(srcDir, destDir); + } + } + + /** + * Throws an {@link IllegalArgumentException} if the file is not writable. This provides a more + * precise exception message than a plain access denied. + * + * @param file The file to test. + * @param name The parameter name to use in the exception message. + * @throws NullPointerException if the given {@link File} is {@code null}. + * @throws IllegalArgumentException if the file is not writable. + */ + private static void requireCanWrite(final File file, final String name) { + Objects.requireNonNull(file, "file"); + if (!file.canWrite()) { + throw new IllegalArgumentException( + "File parameter '" + name + " is not writable: '" + file + "'"); + } + } + + /** + * Requires that the given {@link File} is a directory if it exists. + * + * @param directory The {@link File} to check. + * @param name The parameter name to use in the exception message in case of null input. + * @return the given directory. + * @throws NullPointerException if the given {@link File} is {@code null}. + * @throws IllegalArgumentException if the given {@link File} exists but is not a directory. + */ + private static File requireDirectoryIfExists(final File directory, final String name) { + Objects.requireNonNull(directory, name); + if (directory.exists()) { + requireDirectory(directory, name); + } + return directory; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java b/java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java new file mode 100644 index 000000000..e3c152fac --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import java.io.File; + +public class FilenameUtils { + /** + * Gets the base name, minus the full path and extension, from a full fileName. + * + *

This method will handle a file in either Unix or Windows format. The text after the last + * forward or backslash and before the last dot is returned. + * + *

+   * a/b/c.txt --> c
+   * a.txt     --> a
+   * a/b/c     --> c
+   * a/b/c/    --> ""
+   * 
+ * + *

The output will be the same irrespective of the machine that the code is running on. + * + * @param fileName the fileName to query, null returns null + * @return the name of the file without the path, or an empty string if none exists + * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000}) + */ + public static String getBaseName(final String fileName) { + return removeExtension(getName(fileName)); + } + + /** + * Removes the extension from a fileName. + * + *

This method returns the textual part of the fileName before the last dot. There must be no + * directory separator after the dot. + * + *

+   * foo.txt    --> foo
+   * a\b\c.jpg  --> a\b\c
+   * a\b\c      --> a\b\c
+   * a.b\c      --> a.b\c
+   * 
+ * + *

The output will be the same irrespective of the machine that the code is running on. + * + * @param fileName the fileName to query, null returns null + * @return the fileName minus the extension + * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000}) + */ + public static String removeExtension(final String fileName) { + if (fileName == null) { + return null; + } + requireNonNullChars(fileName); + + final int index = indexOfExtension(fileName); + if (index == NOT_FOUND) { + return fileName; + } + return fileName.substring(0, index); + } + + /** + * Gets the name minus the path from a full fileName. + * + *

This method will handle a file in either Unix or Windows format. The text after the last + * forward or backslash is returned. + * + *

+   * a/b/c.txt --> c.txt
+   * a.txt     --> a.txt
+   * a/b/c     --> c
+   * a/b/c/    --> ""
+   * 
+ * + *

The output will be the same irrespective of the machine that the code is running on. + * + * @param fileName the fileName to query, null returns null + * @return the name of the file without the path, or an empty string if none exists + * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000}) + */ + public static String getName(final String fileName) { + if (fileName == null) { + return null; + } + return requireNonNullChars(fileName).substring(indexOfLastSeparator(fileName) + 1); + } + + /** + * Checks the input for null characters ({@code U+0000}), a sign of unsanitized data being passed + * to file level functions. + * + *

This may be used for poison byte attacks. + * + * @param path the path to check + * @return The input + * @throws IllegalArgumentException if path contains the null character ({@code U+0000}) + */ + private static String requireNonNullChars(final String path) { + if (path.indexOf(0) >= 0) { + throw new IllegalArgumentException( + "Null character present in file/path name. There are no known legitimate use cases for such data, but several injection attacks may use it"); + } + return path; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + private static final int NOT_FOUND = -1; + private static final String EMPTY_STRING = ""; + + /** + * The extension separator character. + * + * @since 1.4 + */ + public static final char EXTENSION_SEPARATOR = '.'; + + /** The system separator character. */ + private static final char SYSTEM_NAME_SEPARATOR = File.separatorChar; + + /** The separator character that is the opposite of the system separator. */ + private static final char OTHER_SEPARATOR = flipSeparator(SYSTEM_NAME_SEPARATOR); + + /** The Unix separator character. */ + private static final char UNIX_NAME_SEPARATOR = '/'; + + /** The Windows separator character. */ + private static final char WINDOWS_NAME_SEPARATOR = '\\'; + + /** + * Gets the extension of a fileName. + * + *

This method returns the textual part of the fileName after the last dot. There must be no + * directory separator after the dot. + * + *

+   * foo.txt      --> "txt"
+   * a/b/c.jpg    --> "jpg"
+   * a/b.txt/c    --> ""
+   * a/b/c        --> ""
+   * 
+ * + *

The output will be the same irrespective of the machine that the code is running on, with + * the exception of a possible {@link IllegalArgumentException} on Windows (see below). + * + *

Note: This method used to have a hidden problem for names like "foo.exe:bar.txt". In + * this case, the name wouldn't be the name of a file, but the identifier of an alternate data + * stream (bar.txt) on the file foo.exe. The method used to return ".txt" here, which would be + * misleading. Commons IO 2.7, and later versions, are throwing an {@link + * IllegalArgumentException} for names like this. + * + * @param fileName the fileName to retrieve the extension of. + * @return the extension of the file or an empty string if none exists or {@code null} if the + * fileName is {@code null}. + * @throws IllegalArgumentException Windows only: The fileName parameter is, in fact, the + * identifier of an Alternate Data Stream, for example "foo.exe:bar.txt". + */ + public static String getExtension(final String fileName) throws IllegalArgumentException { + if (fileName == null) { + return null; + } + final int index = indexOfExtension(fileName); + if (index == NOT_FOUND) { + return EMPTY_STRING; + } + return fileName.substring(index + 1); + } + + /** + * Returns the index of the last extension separator character, which is a dot. + * + *

This method also checks that there is no directory separator after the last dot. To do this + * it uses {@link #indexOfLastSeparator(String)} which will handle a file in either Unix or + * Windows format. + * + *

The output will be the same irrespective of the machine that the code is running on, with + * the exception of a possible {@link IllegalArgumentException} on Windows (see below). + * Note: This method used to have a hidden problem for names like "foo.exe:bar.txt". In + * this case, the name wouldn't be the name of a file, but the identifier of an alternate data + * stream (bar.txt) on the file foo.exe. The method used to return ".txt" here, which would be + * misleading. Commons IO 2.7, and later versions, are throwing an {@link + * IllegalArgumentException} for names like this. + * + * @param fileName the fileName to find the last extension separator in, null returns -1 + * @return the index of the last extension separator character, or -1 if there is no such + * character + * @throws IllegalArgumentException Windows only: The fileName parameter is, in fact, the + * identifier of an Alternate Data Stream, for example "foo.exe:bar.txt". + */ + public static int indexOfExtension(final String fileName) throws IllegalArgumentException { + if (fileName == null) { + return NOT_FOUND; + } + if (isSystemWindows()) { + // Special handling for NTFS ADS: Don't accept colon in the fileName. + final int offset = fileName.indexOf(':', getAdsCriticalOffset(fileName)); + if (offset != -1) { + throw new IllegalArgumentException("NTFS ADS separator (':') in file name is forbidden."); + } + } + final int extensionPos = fileName.lastIndexOf(EXTENSION_SEPARATOR); + final int lastSeparator = indexOfLastSeparator(fileName); + return lastSeparator > extensionPos ? NOT_FOUND : extensionPos; + } + + /** + * Determines if Windows file system is in use. + * + * @return true if the system is Windows + */ + static boolean isSystemWindows() { + return SYSTEM_NAME_SEPARATOR == WINDOWS_NAME_SEPARATOR; + } + + /** + * Flips the Windows name separator to Linux and vice-versa. + * + * @param ch The Windows or Linux name separator. + * @return The Windows or Linux name separator. + */ + static char flipSeparator(final char ch) { + if (ch == UNIX_NAME_SEPARATOR) { + return WINDOWS_NAME_SEPARATOR; + } + if (ch == WINDOWS_NAME_SEPARATOR) { + return UNIX_NAME_SEPARATOR; + } + throw new IllegalArgumentException(String.valueOf(ch)); + } + + /** + * Special handling for NTFS ADS: Don't accept colon in the fileName. + * + * @param fileName a file name + * @return ADS offsets. + */ + private static int getAdsCriticalOffset(final String fileName) { + // Step 1: Remove leading path segments. + final int offset1 = fileName.lastIndexOf(SYSTEM_NAME_SEPARATOR); + final int offset2 = fileName.lastIndexOf(OTHER_SEPARATOR); + if (offset1 == -1) { + if (offset2 == -1) { + return 0; + } + return offset2 + 1; + } + if (offset2 == -1) { + return offset1 + 1; + } + return Math.max(offset1, offset2) + 1; + } + + /** + * Returns the index of the last directory separator character. + * + *

This method will handle a file in either Unix or Windows format. The position of the last + * forward or backslash is returned. + * + *

The output will be the same irrespective of the machine that the code is running on. + * + * @param fileName the fileName to find the last path separator in, null returns -1 + * @return the index of the last separator character, or -1 if there is no such character + */ + public static int indexOfLastSeparator(final String fileName) { + if (fileName == null) { + return NOT_FOUND; + } + final int lastUnixPos = fileName.lastIndexOf(UNIX_NAME_SEPARATOR); + final int lastWindowsPos = fileName.lastIndexOf(WINDOWS_NAME_SEPARATOR); + return Math.max(lastUnixPos, lastWindowsPos); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOCase.java b/java/tsfile/src/main/java/org/apache/commons/io/IOCase.java new file mode 100644 index 000000000..21e3e11e0 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/IOCase.java @@ -0,0 +1,247 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.util.Objects; +import java.util.stream.Stream; + +/** + * Enumeration of IO case sensitivity. + * + *

Different filing systems have different rules for case-sensitivity. Windows is + * case-insensitive, Unix is case-sensitive. + * + *

This class captures that difference, providing an enumeration to control how file name + * comparisons should be performed. It also provides methods that use the enumeration to perform + * comparisons. + * + *

Wherever possible, you should use the {@code check} methods in this class to compare file + * names. + * + * @since 1.3 + */ +public enum IOCase { + + /** The constant for case-sensitive regardless of operating system. */ + SENSITIVE("Sensitive", true), + + /** The constant for case-insensitive regardless of operating system. */ + INSENSITIVE("Insensitive", false); + + /** Serialization version. */ + private static final long serialVersionUID = -6343169151696340687L; + + /** + * Factory method to create an IOCase from a name. + * + * @param name the name to find + * @return the IOCase object + * @throws IllegalArgumentException if the name is invalid + */ + public static IOCase forName(final String name) { + return Stream.of(IOCase.values()) + .filter(ioCase -> ioCase.getName().equals(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Illegal IOCase name: " + name)); + } + + /** + * Tests for cases sensitivity in a null-safe manner. + * + * @param ioCase an IOCase. + * @return true if the input is non-null and {@link #isCaseSensitive()}. + * @since 2.10.0 + */ + public static boolean isCaseSensitive(final IOCase ioCase) { + return ioCase != null && ioCase.isCaseSensitive(); + } + + /** + * Returns the given value if not-null, the defaultValue if null. + * + * @param value the value to test. + * @param defaultValue the default value. + * @return the given value if not-null, the defaultValue if null. + * @since 2.12.0 + */ + public static IOCase value(final IOCase value, final IOCase defaultValue) { + return value != null ? value : defaultValue; + } + + /** The enumeration name. */ + private final String name; + + /** The sensitivity flag. */ + private final transient boolean sensitive; + + /** + * Constructs a new instance. + * + * @param name the name + * @param sensitive the sensitivity + */ + IOCase(final String name, final boolean sensitive) { + this.name = name; + this.sensitive = sensitive; + } + + /** + * Compares two strings using the case-sensitivity rule. + * + *

This method mimics {@link String#compareTo} but takes case-sensitivity into account. + * + * @param str1 the first string to compare, not null + * @param str2 the second string to compare, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public int checkCompareTo(final String str1, final String str2) { + Objects.requireNonNull(str1, "str1"); + Objects.requireNonNull(str2, "str2"); + return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2); + } + + /** + * Checks if one string ends with another using the case-sensitivity rule. + * + *

This method mimics {@link String#endsWith} but takes case-sensitivity into account. + * + * @param str the string to check + * @param end the end to compare against + * @return true if equal using the case rules, false if either input is null + */ + public boolean checkEndsWith(final String str, final String end) { + if (str == null || end == null) { + return false; + } + final int endLen = end.length(); + return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen); + } + + /** + * Compares two strings using the case-sensitivity rule. + * + *

This method mimics {@link String#equals} but takes case-sensitivity into account. + * + * @param str1 the first string to compare, not null + * @param str2 the second string to compare, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public boolean checkEquals(final String str1, final String str2) { + Objects.requireNonNull(str1, "str1"); + Objects.requireNonNull(str2, "str2"); + return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2); + } + + /** + * Checks if one string contains another starting at a specific index using the case-sensitivity + * rule. + * + *

This method mimics parts of {@link String#indexOf(String, int)} but takes case-sensitivity + * into account. + * + * @param str the string to check, not null + * @param strStartIndex the index to start at in str + * @param search the start to search for, not null + * @return the first index of the search String, -1 if no match or {@code null} string input + * @throws NullPointerException if either string is null + * @since 2.0 + */ + public int checkIndexOf(final String str, final int strStartIndex, final String search) { + final int endIndex = str.length() - search.length(); + if (endIndex >= strStartIndex) { + for (int i = strStartIndex; i <= endIndex; i++) { + if (checkRegionMatches(str, i, search)) { + return i; + } + } + } + return -1; + } + + /** + * Checks if one string contains another at a specific index using the case-sensitivity rule. + * + *

This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)} but + * takes case-sensitivity into account. + * + * @param str the string to check, not null + * @param strStartIndex the index to start at in str + * @param search the start to search for, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public boolean checkRegionMatches( + final String str, final int strStartIndex, final String search) { + return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length()); + } + + /** + * Checks if one string starts with another using the case-sensitivity rule. + * + *

This method mimics {@link String#startsWith(String)} but takes case-sensitivity into + * account. + * + * @param str the string to check + * @param start the start to compare against + * @return true if equal using the case rules, false if either input is null + */ + public boolean checkStartsWith(final String str, final String start) { + return str != null + && start != null + && str.regionMatches(!sensitive, 0, start, 0, start.length()); + } + + /** + * Gets the name of the constant. + * + * @return the name of the constant + */ + public String getName() { + return name; + } + + /** + * Does the object represent case-sensitive comparison. + * + * @return true if case-sensitive + */ + public boolean isCaseSensitive() { + return sensitive; + } + + /** + * Replaces the enumeration from the stream with a real one. This ensures that the correct flag is + * set for SYSTEM. + * + * @return the resolved object + */ + private Object readResolve() { + return forName(name); + } + + /** + * Gets a string describing the sensitivity. + * + * @return a string describing the sensitivity + */ + @Override + public String toString() { + return name; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java b/java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java new file mode 100644 index 000000000..bc20ec085 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * An IOException based on a list of Throwable causes. + * + *

The first exception in the list is used as this exception's cause and is accessible with the + * usual {@link #getCause()} while the complete list is accessible with {@link #getCauseList()}. + * + * @since 2.7 + */ +public class IOExceptionList extends IOException implements Iterable { + + private static final long serialVersionUID = 1L; + + /** + * Throws this exception if the list is not null or empty. + * + * @param causeList The list to test. + * @param message The detail message, see {@link #getMessage()}. + * @throws IOExceptionList if the list is not null or empty. + * @since 2.12.0 + */ + public static void checkEmpty(final List causeList, final Object message) + throws IOExceptionList { + if (!isEmpty(causeList)) { + throw new IOExceptionList(Objects.toString(message, null), causeList); + } + } + + private static boolean isEmpty(final List causeList) { + return size(causeList) == 0; + } + + private static int size(final List causeList) { + return causeList != null ? causeList.size() : 0; + } + + private static String toMessage(final List causeList) { + return String.format("%,d exception(s): %s", size(causeList), causeList); + } + + /** List of causes. */ + private final List causeList; + + /** + * Constructs a new exception caused by a list of exceptions. + * + * @param causeList a list of cause exceptions. + */ + public IOExceptionList(final List causeList) { + this(toMessage(causeList), causeList); + } + + /** + * Constructs a new exception caused by a list of exceptions. + * + * @param message The detail message, see {@link #getMessage()}. + * @param causeList a list of cause exceptions. + * @since 2.9.0 + */ + public IOExceptionList(final String message, final List causeList) { + super( + message != null ? message : toMessage(causeList), + isEmpty(causeList) ? null : causeList.get(0)); + this.causeList = causeList == null ? Collections.emptyList() : causeList; + } + + /** + * Gets the cause exception at the given index. + * + * @param type of exception to return. + * @param index index in the cause list. + * @return The list of causes. + */ + public T getCause(final int index) { + return (T) causeList.get(index); + } + + /** + * Gets the cause exception at the given index. + * + * @param type of exception to return. + * @param index index in the cause list. + * @param clazz type of exception to return. + * @return The list of causes. + */ + public T getCause(final int index, final Class clazz) { + return clazz.cast(getCause(index)); + } + + /** + * Gets the cause list. + * + * @param type of exception to return. + * @return The list of causes. + */ + public List getCauseList() { + return (List) new ArrayList<>(causeList); + } + + /** + * Works around Throwable and Generics, may fail at runtime depending on the argument value. + * + * @param type of exception to return. + * @param clazz the target type + * @return The list of causes. + */ + public List getCauseList(final Class clazz) { + return (List) new ArrayList<>(causeList); + } + + @Override + public Iterator iterator() { + return getCauseList().iterator(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java b/java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java new file mode 100644 index 000000000..906eec52d --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import java.io.IOException; + +/** + * A IOException associated with a source index. + * + * @since 2.7 + */ +public class IOIndexedException extends IOException { + + private static final long serialVersionUID = 1L; + + /** + * Converts input to a suitable String for exception message. + * + * @param index An index into a source collection. + * @param cause A cause. + * @return A message. + */ + protected static String toMessage(final int index, final Throwable cause) { + // Letting index be any int + final String unspecified = "Null"; + final String name = cause == null ? unspecified : cause.getClass().getSimpleName(); + final String msg = cause == null ? unspecified : cause.getMessage(); + return String.format("%s #%,d: %s", name, index, msg); + } + + /** Index. */ + private final int index; + + /** + * Constructs a new exception. + * + * @param index index of this exception. + * @param cause cause exceptions. + */ + public IOIndexedException(final int index, final Throwable cause) { + super(toMessage(index, cause), cause); + this.index = index; + } + + /** + * The index of this exception. + * + * @return index of this exception. + */ + public int getIndex() { + return index; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java b/java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java new file mode 100644 index 000000000..51c7d0bb5 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java @@ -0,0 +1,462 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.commons.io; + +import org.apache.commons.io.function.IOTriFunction; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.commons.io.output.StringBuilderWriter; +import org.apache.commons.io.output.ThresholdingOutputStream; +import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.nio.channels.Channels; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Objects; + +public class IOUtils { + + /** + * A singleton empty byte array. + * + * @since 2.9.0 + */ + public static final byte[] EMPTY_BYTE_ARRAY = {}; + + /** + * Represents the end-of-file (or stream). + * + * @since 2.5 (made public) + */ + public static final int EOF = -1; + + /** The default buffer size ({@value}) to use in copy methods. */ + public static final int DEFAULT_BUFFER_SIZE = 8192; + + public static int length(final Object[] array) { + return array == null ? 0 : array.length; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** Internal char array buffer, intended for both reading and writing. */ + private static final ThreadLocal SCRATCH_CHAR_BUFFER_RW = + ThreadLocal.withInitial(IOUtils::charArray); + + /** + * Returns a new char array of size {@link #DEFAULT_BUFFER_SIZE}. + * + * @return a new char array of size {@link #DEFAULT_BUFFER_SIZE}. + * @since 2.9.0 + */ + private static char[] charArray() { + return charArray(DEFAULT_BUFFER_SIZE); + } + + /** + * Returns a new char array of the given size. + * + *

TODO Consider guarding or warning against large allocations... + * + * @param size array size. + * @return a new char array of the given size. + * @since 2.9.0 + */ + private static char[] charArray(final int size) { + return new char[size]; + } + + /** + * Gets the contents of a {@link Reader} as a {@code byte[]} using the specified character + * encoding. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedReader}. + * + * @param reader the {@link Reader} to read + * @param charset the charset to use, null means platform default + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 2.3 + */ + public static byte[] toByteArray(final Reader reader, final Charset charset) throws IOException { + try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { + copy(reader, output, charset); + return output.toByteArray(); + } + } + + /** + * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the specified + * character encoding, and calling flush. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedReader}. + * + *

Due to the implementation of OutputStreamWriter, this method performs a flush. + * + *

This method uses {@link OutputStreamWriter}. + * + * @param reader the {@link Reader} to read + * @param output the {@link OutputStream} to write to + * @param outputCharset the charset to use for the OutputStream, null means platform default + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 2.3 + */ + public static void copy( + final Reader reader, final OutputStream output, final Charset outputCharset) + throws IOException { + final OutputStreamWriter writer = + new OutputStreamWriter(output, Charsets.toCharset(outputCharset)); + copy(reader, writer); + // XXX Unless anyone is planning on rewriting OutputStreamWriter, + // we have to flush here. + writer.flush(); + } + + /** + * Gets the contents of an {@link InputStream} as a {@code byte[]}. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param inputStream the {@link InputStream} to read. + * @return the requested byte array. + * @throws NullPointerException if the InputStream is {@code null}. + * @throws IOException if an I/O error occurs or reading more than {@link Integer#MAX_VALUE} + * occurs. + */ + public static byte[] toByteArray(final InputStream inputStream) throws IOException { + // We use a ThresholdingOutputStream to avoid reading AND writing more than Integer.MAX_VALUE. + try (UnsynchronizedByteArrayOutputStream ubaOutput = + UnsynchronizedByteArrayOutputStream.builder().get(); + ThresholdingOutputStream thresholdOutput = + new ThresholdingOutputStream( + Integer.MAX_VALUE, + os -> { + throw new IllegalArgumentException( + String.format( + "Cannot read more than %,d into a byte array", Integer.MAX_VALUE)); + }, + os -> ubaOutput)) { + copy(inputStream, thresholdOutput); + return ubaOutput.toByteArray(); + } + } + + /** + * Returns a new byte array of size {@link #DEFAULT_BUFFER_SIZE}. + * + * @return a new byte array of size {@link #DEFAULT_BUFFER_SIZE}. + * @since 2.9.0 + */ + public static byte[] byteArray() { + return byteArray(DEFAULT_BUFFER_SIZE); + } + + /** + * Returns a new byte array of the given size. + * + *

TODO Consider guarding or warning against large allocations... + * + * @param size array size. + * @return a new byte array of the given size. + * @throws NegativeArraySizeException if the size is negative. + * @since 2.9.0 + */ + public static byte[] byteArray(final int size) { + return new byte[size]; + } + + /** + * Copies bytes from an {@link InputStream} to an {@link OutputStream}. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + *

Large streams (over 2GB) will return a bytes copied value of {@code -1} after the copy has + * completed since the correct number of bytes cannot be returned as an int. For large streams use + * the {@link #copyLarge(InputStream, OutputStream)} method. + * + * @param inputStream the {@link InputStream} to read. + * @param outputStream the {@link OutputStream} to write. + * @return the number of bytes copied, or -1 if greater than {@link Integer#MAX_VALUE}. + * @throws NullPointerException if the InputStream is {@code null}. + * @throws NullPointerException if the OutputStream is {@code null}. + * @throws IOException if an I/O error occurs. + * @since 1.1 + */ + public static int copy(final InputStream inputStream, final OutputStream outputStream) + throws IOException { + final long count = copyLarge(inputStream, outputStream); + return count > Integer.MAX_VALUE ? EOF : (int) count; + } + + /** + * Copies bytes from an {@link InputStream} to an {@link OutputStream} using an internal buffer of + * the given size. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param inputStream the {@link InputStream} to read. + * @param outputStream the {@link OutputStream} to write to + * @param bufferSize the bufferSize used to copy from the input to the output + * @return the number of bytes copied. + * @throws NullPointerException if the InputStream is {@code null}. + * @throws NullPointerException if the OutputStream is {@code null}. + * @throws IOException if an I/O error occurs. + * @since 2.5 + */ + public static long copy( + final InputStream inputStream, final OutputStream outputStream, final int bufferSize) + throws IOException { + return copyLarge(inputStream, outputStream, IOUtils.byteArray(bufferSize)); + } + + /** + * Copies bytes from a large (over 2GB) {@link InputStream} to an {@link OutputStream}. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + *

The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. + * + * @param inputStream the {@link InputStream} to read. + * @param outputStream the {@link OutputStream} to write. + * @return the number of bytes copied. + * @throws NullPointerException if the InputStream is {@code null}. + * @throws NullPointerException if the OutputStream is {@code null}. + * @throws IOException if an I/O error occurs. + * @since 1.3 + */ + public static long copyLarge(final InputStream inputStream, final OutputStream outputStream) + throws IOException { + return copy(inputStream, outputStream, DEFAULT_BUFFER_SIZE); + } + + /** + * Copies bytes from a large (over 2GB) {@link InputStream} to an {@link OutputStream}. + * + *

This method uses the provided buffer, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param inputStream the {@link InputStream} to read. + * @param outputStream the {@link OutputStream} to write. + * @param buffer the buffer to use for the copy + * @return the number of bytes copied. + * @throws NullPointerException if the InputStream is {@code null}. + * @throws NullPointerException if the OutputStream is {@code null}. + * @throws IOException if an I/O error occurs. + * @since 2.2 + */ + @SuppressWarnings("resource") // streams are closed by the caller. + public static long copyLarge( + final InputStream inputStream, final OutputStream outputStream, final byte[] buffer) + throws IOException { + Objects.requireNonNull(inputStream, "inputStream"); + Objects.requireNonNull(outputStream, "outputStream"); + long count = 0; + int n; + while (EOF != (n = inputStream.read(buffer))) { + outputStream.write(buffer, 0, n); + count += n; + } + return count; + } + + /** + * Gets the contents of a {@link Reader} as a String. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedReader}. + * + * @param reader the {@link Reader} to read + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static String toString(final Reader reader) throws IOException { + try (StringBuilderWriter sw = new StringBuilderWriter()) { + copy(reader, sw); + return sw.toString(); + } + } + + /** + * Copies chars from a {@link Reader} to a {@link Writer}. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedReader}. + * + *

Large streams (over 2GB) will return a chars copied value of {@code -1} after the copy has + * completed since the correct number of chars cannot be returned as an int. For large streams use + * the {@link #copyLarge(Reader, Writer)} method. + * + * @param reader the {@link Reader} to read. + * @param writer the {@link Writer} to write. + * @return the number of characters copied, or -1 if > Integer.MAX_VALUE + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 1.1 + */ + public static int copy(final Reader reader, final Writer writer) throws IOException { + final long count = copyLarge(reader, writer); + if (count > Integer.MAX_VALUE) { + return EOF; + } + return (int) count; + } + + /** + * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedReader}. + * + *

The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. + * + * @param reader the {@link Reader} to source. + * @param writer the {@link Writer} to target. + * @return the number of characters copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 1.3 + */ + public static long copyLarge(final Reader reader, final Writer writer) throws IOException { + return copyLarge(reader, writer, getScratchCharArray()); + } + + /** + * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}. + * + *

This method uses the provided buffer, so there is no need to use a {@link BufferedReader}. + * + * @param reader the {@link Reader} to source. + * @param writer the {@link Writer} to target. + * @param buffer the buffer to be used for the copy + * @return the number of characters copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 2.2 + */ + public static long copyLarge(final Reader reader, final Writer writer, final char[] buffer) + throws IOException { + long count = 0; + int n; + while (EOF != (n = reader.read(buffer))) { + writer.write(buffer, 0, n); + count += n; + } + return count; + } + + /** + * Gets the char byte array buffer, intended for both reading and writing. + * + * @return the char byte array buffer, intended for both reading and writing. + */ + static char[] getScratchCharArray() { + return fill0(SCRATCH_CHAR_BUFFER_RW.get()); + } + + /** + * Fills the given array with 0s. + * + * @param arr The array to fill. + * @return The given array. + */ + private static char[] fill0(final char[] arr) { + Arrays.fill(arr, (char) 0); + return arr; + } + + /** + * Gets the contents of an input as a {@code byte[]}. + * + * @param input the input to read. + * @param size the size of the input to read, where 0 < {@code size} <= length of input. + * @return byte [] of length {@code size}. + * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code + * size}. + * @throws IllegalArgumentException if {@code size} is less than zero. + */ + static byte[] toByteArray( + final IOTriFunction input, final int size) + throws IOException { + + if (size < 0) { + throw new IllegalArgumentException("Size must be equal or greater than zero: " + size); + } + + if (size == 0) { + return EMPTY_BYTE_ARRAY; + } + + final byte[] data = byteArray(size); + int offset = 0; + int read; + + while (offset < size && (read = input.apply(data, offset, size - offset)) != EOF) { + offset += read; + } + + if (offset != size) { + throw new IOException("Unexpected read size, current: " + offset + ", expected: " + size); + } + + return data; + } + + /** + * Writes chars from a {@link String} to bytes on an {@link OutputStream} using the specified + * character encoding. + * + *

This method uses {@link String#getBytes(String)}. + * + * @param data the {@link String} to write, null ignored + * @param output the {@link OutputStream} to write to + * @param charset the charset to use, null means platform default + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since 2.3 + */ + @SuppressWarnings("resource") + public static void write(final String data, final OutputStream output, final Charset charset) + throws IOException { + if (data != null) { + // Use Charset#encode(String), since calling String#getBytes(Charset) might result in + // NegativeArraySizeException or OutOfMemoryError. + // The underlying OutputStream should not be closed, so the channel is not closed. + Channels.newChannel(output).write(Charsets.toCharset(charset).encode(data)); + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java b/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java new file mode 100644 index 000000000..991ccba36 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.RandomAccessFile; +import java.nio.file.Path; + +/** + * Access modes and factory methods for {@link RandomAccessFile}. + * + * @since 2.12.0 + */ +public enum RandomAccessFileMode { + + /** Mode {@code "r"} opens for reading only. */ + READ_ONLY("r"), + + /** Mode {@code "rw"} opens for reading and writing. */ + READ_WRITE("rw"), + + /** + * Mode {@code "rws"} opens for reading and writing, as with {@code "rw"}, and also require that + * every update to the file's content or metadata be written synchronously to the underlying + * storage device. + */ + READ_WRITE_SYNC_ALL("rws"), + + /** + * Mode {@code "rwd"} open for reading and writing, as with {@code "rw"}, and also require that + * every update to the file's content be written synchronously to the underlying storage device. + */ + READ_WRITE_SYNC_CONTENT("rwd"); + + private final String mode; + + RandomAccessFileMode(final String mode) { + this.mode = mode; + } + + /** + * Constructs a random access file stream to read from, and optionally to write to, the file + * specified by the {@link File} argument. + * + * @param file the file object + * @return a random access file stream + * @throws FileNotFoundException See {@link RandomAccessFile#RandomAccessFile(File, String)}. + */ + public RandomAccessFile create(final File file) throws FileNotFoundException { + return new RandomAccessFile(file, mode); + } + + /** + * Constructs a random access file stream to read from, and optionally to write to, the file + * specified by the {@link File} argument. + * + * @param file the file object + * @return a random access file stream + * @throws FileNotFoundException See {@link RandomAccessFile#RandomAccessFile(File, String)}. + */ + public RandomAccessFile create(final Path file) throws FileNotFoundException { + return create(file.toFile()); + } + + /** + * Constructs a random access file stream to read from, and optionally to write to, the file + * specified by the {@link File} argument. + * + * @param file the file object + * @return a random access file stream + * @throws FileNotFoundException See {@link RandomAccessFile#RandomAccessFile(File, String)}. + */ + public RandomAccessFile create(final String file) throws FileNotFoundException { + return new RandomAccessFile(file, mode); + } + + @Override + public String toString() { + return mode; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java b/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java new file mode 100644 index 000000000..3de254610 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Works on RandomAccessFile. + * + * @since 2.13.0 + */ +public class RandomAccessFiles { + + /** + * Reads a byte array starting at "position" for "length" bytes. + * + * @param input The source RandomAccessFile. + * @param position The offset position, measured in bytes from the beginning of the file, at which + * to set the file pointer. + * @param length How many bytes to read. + * @return a new byte array. + * @throws IOException If the first byte cannot be read for any reason other than end of file, or + * if the random access file has been closed, or if some other I/O error occurs. + */ + public static byte[] read(final RandomAccessFile input, final long position, final int length) + throws IOException { + input.seek(position); + return IOUtils.toByteArray(input::read, length); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java new file mode 100644 index 000000000..b7803f6c9 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java @@ -0,0 +1,530 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.build; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.RandomAccessFileMode; +import org.apache.commons.io.RandomAccessFiles; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.commons.io.output.WriterOutputStream; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.RandomAccessFile; +import java.io.Reader; +import java.io.Writer; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Objects; + +/** + * Abstracts the origin of data for builders like a {@link File}, {@link Path}, {@link Reader}, + * {@link Writer}, {@link InputStream}, {@link OutputStream}, and {@link URI}. + * + *

Some methods may throw {@link UnsupportedOperationException} if that method is not implemented + * in a concrete subclass, see {@link #getFile()} and {@link #getPath()}. + * + * @param the type of instances to build. + * @param the type of builder subclass. + * @since 2.12.0 + */ +public abstract class AbstractOrigin> + extends AbstractSupplier { + + /** A {@code byte[]} origin. */ + public static class ByteArrayOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public ByteArrayOrigin(final byte[] origin) { + super(origin); + } + + @Override + public byte[] getByteArray() { + // No conversion + return get(); + } + + @Override + public InputStream getInputStream(final OpenOption... options) throws IOException { + return new ByteArrayInputStream(origin); + } + + @Override + public Reader getReader(final Charset charset) throws IOException { + return new InputStreamReader(getInputStream(), charset); + } + + @Override + public long size() throws IOException { + return origin.length; + } + } + + /** A {@link CharSequence} origin. */ + public static class CharSequenceOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public CharSequenceOrigin(final CharSequence origin) { + super(origin); + } + + @Override + public byte[] getByteArray() { + // TODO Pass in a Charset? Consider if call sites actually need this. + return origin.toString().getBytes(Charset.defaultCharset()); + } + + @Override + public CharSequence getCharSequence(final Charset charset) { + // No conversion + return get(); + } + + @Override + public InputStream getInputStream(final OpenOption... options) throws IOException { + // TODO Pass in a Charset? Consider if call sites actually need this. + return new ByteArrayInputStream(origin.toString().getBytes(Charset.defaultCharset())); + // Needs [IO-795] CharSequenceInputStream.reset() only works once. + // return + // CharSequenceInputStream.builder().setCharSequence(getCharSequence(Charset.defaultCharset())).get(); + } + + @Override + public Reader getReader(final Charset charset) throws IOException { + return new InputStreamReader(getInputStream(), charset); + } + + @Override + public long size() throws IOException { + return origin.length(); + } + } + + /** + * A {@link File} origin. + * + *

Starting from this origin, you can get a byte array, a file, an input stream, an output + * stream, a path, a reader, and a writer. + */ + public static class FileOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public FileOrigin(final File origin) { + super(origin); + } + + @Override + public byte[] getByteArray(final long position, final int length) throws IOException { + try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) { + return RandomAccessFiles.read(raf, position, length); + } + } + + @Override + public File getFile() { + // No conversion + return get(); + } + + @Override + public Path getPath() { + return get().toPath(); + } + } + + /** + * An {@link InputStream} origin. + * + *

This origin cannot provide some of the other aspects. + */ + public static class InputStreamOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public InputStreamOrigin(final InputStream origin) { + super(origin); + } + + @Override + public byte[] getByteArray() throws IOException { + return IOUtils.toByteArray(origin); + } + + @Override + public InputStream getInputStream(final OpenOption... options) { + // No conversion + return get(); + } + + @Override + public Reader getReader(final Charset charset) throws IOException { + return new InputStreamReader(getInputStream(), charset); + } + } + + /** + * An {@link OutputStream} origin. + * + *

This origin cannot provide some of the other aspects. + */ + public static class OutputStreamOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public OutputStreamOrigin(final OutputStream origin) { + super(origin); + } + + @Override + public OutputStream getOutputStream(final OpenOption... options) { + // No conversion + return get(); + } + + @Override + public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException { + return new OutputStreamWriter(origin, charset); + } + } + + /** + * A {@link Path} origin. + * + *

Starting from this origin, you can get a byte array, a file, an input stream, an output + * stream, a path, a reader, and a writer. + */ + public static class PathOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public PathOrigin(final Path origin) { + super(origin); + } + + @Override + public byte[] getByteArray(final long position, final int length) throws IOException { + try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) { + return RandomAccessFiles.read(raf, position, length); + } + } + + @Override + public File getFile() { + return get().toFile(); + } + + @Override + public Path getPath() { + // No conversion + return get(); + } + } + + /** + * An {@link Reader} origin. + * + *

This origin cannot provide other aspects. + */ + public static class ReaderOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public ReaderOrigin(final Reader origin) { + super(origin); + } + + @Override + public byte[] getByteArray() throws IOException { + // TODO Pass in a Charset? Consider if call sites actually need this. + return IOUtils.toByteArray(origin, Charset.defaultCharset()); + } + + @Override + public CharSequence getCharSequence(final Charset charset) throws IOException { + return IOUtils.toString(origin); + } + + @Override + public InputStream getInputStream(final OpenOption... options) throws IOException { + // TODO Pass in a Charset? Consider if call sites actually need this. + return ReaderInputStream.builder() + .setReader(origin) + .setCharset(Charset.defaultCharset()) + .get(); + } + + @Override + public Reader getReader(final Charset charset) throws IOException { + // No conversion + return get(); + } + } + + /** A {@link URI} origin. */ + public static class URIOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public URIOrigin(final URI origin) { + super(origin); + } + + @Override + public File getFile() { + return getPath().toFile(); + } + + @Override + public Path getPath() { + return Paths.get(get()); + } + } + + /** + * An {@link Writer} origin. + * + *

This origin cannot provide other aspects. + */ + public static class WriterOrigin extends AbstractOrigin { + + /** + * Constructs a new instance for the given origin. + * + * @param origin The origin. + */ + public WriterOrigin(final Writer origin) { + super(origin); + } + + @Override + public OutputStream getOutputStream(final OpenOption... options) throws IOException { + // TODO Pass in a Charset? Consider if call sites actually need this. + return WriterOutputStream.builder() + .setWriter(origin) + .setCharset(Charset.defaultCharset()) + .get(); + } + + @Override + public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException { + // No conversion + return get(); + } + } + + /** The non-null origin. */ + final T origin; + + /** + * Constructs a new instance for a subclass. + * + * @param origin The origin. + */ + protected AbstractOrigin(final T origin) { + this.origin = Objects.requireNonNull(origin, "origin"); + } + + /** + * Gets the origin. + * + * @return the origin. + */ + @Override + public T get() { + return origin; + } + + /** + * Gets this origin as a byte array, if possible. + * + * @return this origin as a byte array, if possible. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + */ + public byte[] getByteArray() throws IOException { + return Files.readAllBytes(getPath()); + } + + /** + * Gets this origin as a byte array, if possible. + * + * @param position the initial index of the range to be copied, inclusive. + * @param length How many bytes to copy. + * @return this origin as a byte array, if possible. + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + * @throws ArithmeticException if the {@code position} overflows an int + * @throws IOException if an I/O error occurs. + * @since 2.13.0 + */ + public byte[] getByteArray(final long position, final int length) throws IOException { + final byte[] bytes = getByteArray(); + // Checks for int overflow. + final int start = Math.toIntExact(position); + if (start < 0 || length < 0 || start + length < 0 || start + length > bytes.length) { + throw new IllegalArgumentException( + "Couldn't read array (start: " + + start + + ", length: " + + length + + ", data length: " + + bytes.length + + ")."); + } + return Arrays.copyOfRange(bytes, start, start + length); + } + + /** + * Gets this origin as a byte array, if possible. + * + * @param charset The charset to use if conversion from bytes is needed. + * @return this origin as a byte array, if possible. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + */ + public CharSequence getCharSequence(final Charset charset) throws IOException { + return new String(getByteArray(), charset); + } + + /** + * Gets this origin as a Path, if possible. + * + * @return this origin as a Path, if possible. + * @throws UnsupportedOperationException if this method is not implemented in a concrete subclass. + */ + public File getFile() { + throw new UnsupportedOperationException( + String.format( + "%s#getFile() for %s origin %s", + getClass().getSimpleName(), origin.getClass().getSimpleName(), origin)); + } + + /** + * Gets this origin as an InputStream, if possible. + * + * @param options options specifying how the file is opened + * @return this origin as an InputStream, if possible. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + */ + public InputStream getInputStream(final OpenOption... options) throws IOException { + return Files.newInputStream(getPath(), options); + } + + /** + * Gets this origin as an OutputStream, if possible. + * + * @param options options specifying how the file is opened + * @return this origin as an OutputStream, if possible. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + */ + public OutputStream getOutputStream(final OpenOption... options) throws IOException { + return Files.newOutputStream(getPath(), options); + } + + /** + * Gets this origin as a Path, if possible. + * + * @return this origin as a Path, if possible. + * @throws UnsupportedOperationException if this method is not implemented in a concrete subclass. + */ + public Path getPath() { + throw new UnsupportedOperationException( + String.format( + "%s#getPath() for %s origin %s", + getClass().getSimpleName(), origin.getClass().getSimpleName(), origin)); + } + + /** + * Gets a new Reader on the origin, buffered by default. + * + * @param charset the charset to use for decoding + * @return a new Reader on the origin. + * @throws IOException if an I/O error occurs opening the file. + */ + public Reader getReader(final Charset charset) throws IOException { + return Files.newBufferedReader(getPath(), charset); + } + + /** + * Gets a new Writer on the origin, buffered by default. + * + * @param charset the charset to use for encoding + * @param options options specifying how the file is opened + * @return a new Writer on the origin. + * @throws IOException if an I/O error occurs opening or creating the file. + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + */ + public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException { + return Files.newBufferedWriter(getPath(), charset, options); + } + + /** + * Gets the size of the origin, if possible. + * + * @return the size of the origin in bytes or characters. + * @throws IOException if an I/O error occurs. + * @since 2.13.0 + */ + public long size() throws IOException { + return Files.size(getPath()); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + origin.toString() + "]"; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java new file mode 100644 index 000000000..ce7e18973 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java @@ -0,0 +1,315 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.build; + +import org.apache.commons.io.build.AbstractOrigin.ByteArrayOrigin; +import org.apache.commons.io.build.AbstractOrigin.CharSequenceOrigin; +import org.apache.commons.io.build.AbstractOrigin.FileOrigin; +import org.apache.commons.io.build.AbstractOrigin.InputStreamOrigin; +import org.apache.commons.io.build.AbstractOrigin.OutputStreamOrigin; +import org.apache.commons.io.build.AbstractOrigin.PathOrigin; +import org.apache.commons.io.build.AbstractOrigin.ReaderOrigin; +import org.apache.commons.io.build.AbstractOrigin.URIOrigin; +import org.apache.commons.io.build.AbstractOrigin.WriterOrigin; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Abstracts building an instance of {@code T}. + * + * @param the type of instances to build. + * @param the type of builder subclass. + * @since 2.12.0 + */ +public abstract class AbstractOriginSupplier> + extends AbstractSupplier { + + /** + * Constructs a new byte array origin for a byte array. + * + * @param origin the byte array. + * @return a new byte array origin. + */ + protected static ByteArrayOrigin newByteArrayOrigin(final byte[] origin) { + return new ByteArrayOrigin(origin); + } + + /** + * Constructs a new CharSequence origin for a CharSequence. + * + * @param origin the CharSequence. + * @return a new file origin. + * @since 2.13.0 + */ + protected static CharSequenceOrigin newCharSequenceOrigin(final CharSequence origin) { + return new CharSequenceOrigin(origin); + } + + /** + * Constructs a new file origin for a file. + * + * @param origin the file. + * @return a new file origin. + */ + protected static FileOrigin newFileOrigin(final File origin) { + return new FileOrigin(origin); + } + + /** + * Constructs a new file origin for a file path. + * + * @param origin the file path. + * @return a new file origin. + */ + protected static FileOrigin newFileOrigin(final String origin) { + return new FileOrigin(new File(origin)); + } + + /** + * Constructs a new input stream origin for a file. + * + * @param origin the input stream. + * @return a new input stream origin. + */ + protected static InputStreamOrigin newInputStreamOrigin(final InputStream origin) { + return new InputStreamOrigin(origin); + } + + /** + * Constructs a new output stream origin for a file. + * + * @param origin the output stream. + * @return a new output stream origin. + */ + protected static OutputStreamOrigin newOutputStreamOrigin(final OutputStream origin) { + return new OutputStreamOrigin(origin); + } + + /** + * Constructs a new path origin for a file. + * + * @param origin the path. + * @return a new path origin. + */ + protected static PathOrigin newPathOrigin(final Path origin) { + return new PathOrigin(origin); + } + + /** + * Constructs a new path name origin for a path name. + * + * @param origin the path name. + * @return a new path name origin. + */ + protected static PathOrigin newPathOrigin(final String origin) { + return new PathOrigin(Paths.get(origin)); + } + + /** + * Constructs a new reader origin for a reader. + * + * @param origin the reader. + * @return a new reader origin. + */ + protected static ReaderOrigin newReaderOrigin(final Reader origin) { + return new ReaderOrigin(origin); + } + + /** + * Constructs a new reader origin for a URI. + * + * @param origin the URI. + * @return a new URI origin. + */ + protected static URIOrigin newURIOrigin(final URI origin) { + return new URIOrigin(origin); + } + + /** + * Constructs a new writer origin for a file. + * + * @param origin the writer. + * @return a new writer . + */ + protected static WriterOrigin newWriterOrigin(final Writer origin) { + return new WriterOrigin(origin); + } + + /** The underlying origin. */ + private AbstractOrigin origin; + + /** + * Checks whether the origin is null. + * + * @return the origin. + * @throws IllegalStateException if the {@code origin} is {@code null}. + */ + protected AbstractOrigin checkOrigin() { + if (origin == null) { + throw new IllegalStateException("origin == null"); + } + return origin; + } + + /** + * Gets the origin. + * + * @return the origin. + */ + protected AbstractOrigin getOrigin() { + return origin; + } + + /** + * Tests whether the origin is null. + * + * @return whether the origin is null. + */ + protected boolean hasOrigin() { + return origin != null; + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setByteArray(final byte[] origin) { + return setOrigin(newByteArrayOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + * @since 2.13.0 + */ + public B setCharSequence(final CharSequence origin) { + return setOrigin(newCharSequenceOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setFile(final File origin) { + return setOrigin(newFileOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setFile(final String origin) { + return setOrigin(newFileOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setInputStream(final InputStream origin) { + return setOrigin(newInputStreamOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + protected B setOrigin(final AbstractOrigin origin) { + this.origin = origin; + return asThis(); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setOutputStream(final OutputStream origin) { + return setOrigin(newOutputStreamOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setPath(final Path origin) { + return setOrigin(newPathOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setPath(final String origin) { + return setOrigin(newPathOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setReader(final Reader origin) { + return setOrigin(newReaderOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setURI(final URI origin) { + return setOrigin(newURIOrigin(origin)); + } + + /** + * Sets a new origin. + * + * @param origin the new origin. + * @return this + */ + public B setWriter(final Writer origin) { + return setOrigin(newWriterOrigin(origin)); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java new file mode 100644 index 000000000..23e26b4cb --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java @@ -0,0 +1,329 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.build; + +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.file.PathUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.util.function.IntUnaryOperator; + +/** + * Abstracts building a typed instance of {@code T}. + * + * @param the type of instances to build. + * @param the type of builder subclass. + * @since 2.12.0 + */ +public abstract class AbstractStreamBuilder> + extends AbstractOriginSupplier { + + private static final int DEFAULT_MAX_VALUE = Integer.MAX_VALUE; + + private static final OpenOption[] DEFAULT_OPEN_OPTIONS = PathUtils.EMPTY_OPEN_OPTION_ARRAY; + + /** + * The buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value + * IOUtils#DEFAULT_BUFFER_SIZE}). + */ + private int bufferSize = IOUtils.DEFAULT_BUFFER_SIZE; + + /** + * The buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value + * IOUtils#DEFAULT_BUFFER_SIZE}). + */ + private int bufferSizeDefault = IOUtils.DEFAULT_BUFFER_SIZE; + + /** The maximum buffer size. */ + private int bufferSizeMax = DEFAULT_MAX_VALUE; + + /** The Charset, defaults to {@link Charset#defaultCharset()}. */ + private Charset charset = Charset.defaultCharset(); + + /** The Charset, defaults to {@link Charset#defaultCharset()}. */ + private Charset charsetDefault = Charset.defaultCharset(); + + private OpenOption[] openOptions = DEFAULT_OPEN_OPTIONS; + + /** + * The default checking behavior for a buffer size request. Throws a {@link + * IllegalArgumentException} by default. + */ + private final IntUnaryOperator defaultSizeChecker = + size -> size > bufferSizeMax ? throwIae(size, bufferSizeMax) : size; + + /** The checking behavior for a buffer size request. */ + private IntUnaryOperator bufferSizeChecker = defaultSizeChecker; + + /** + * Applies the buffer size request. + * + * @param size the size request. + * @return the size to use, usually the input, or can throw an unchecked exception, like {@link + * IllegalArgumentException}. + */ + private int checkBufferSize(final int size) { + return bufferSizeChecker.applyAsInt(size); + } + + /** + * Gets the buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value + * IOUtils#DEFAULT_BUFFER_SIZE}). + * + * @return the buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value + * IOUtils#DEFAULT_BUFFER_SIZE}). + */ + protected int getBufferSize() { + return bufferSize; + } + + /** + * Gets the buffer size default, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value + * IOUtils#DEFAULT_BUFFER_SIZE}). + * + * @return the buffer size default, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value + * IOUtils#DEFAULT_BUFFER_SIZE}). + */ + protected int getBufferSizeDefault() { + return bufferSizeDefault; + } + + /** + * Gets a CharSequence from the origin with a Charset. + * + * @return An input stream + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to a CharSequence. + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @see AbstractOrigin#getCharSequence(Charset) + * @since 2.13.0 + */ + protected CharSequence getCharSequence() throws IOException { + return checkOrigin().getCharSequence(getCharset()); + } + + /** + * Gets the Charset, defaults to {@link Charset#defaultCharset()}. + * + * @return the Charset, defaults to {@link Charset#defaultCharset()}. + */ + public Charset getCharset() { + return charset; + } + + /** + * Gets the Charset default, defaults to {@link Charset#defaultCharset()}. + * + * @return the Charset default, defaults to {@link Charset#defaultCharset()}. + */ + protected Charset getCharsetDefault() { + return charsetDefault; + } + + /** + * Gets an input stream from the origin with open options. + * + * @return An input stream + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to an InputStream. + * @see AbstractOrigin#getInputStream(OpenOption...) + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @since 2.13.0 + */ + protected InputStream getInputStream() throws IOException { + return checkOrigin().getInputStream(getOpenOptions()); + } + + protected OpenOption[] getOpenOptions() { + return openOptions; + } + + /** + * Gets an OutputStream from the origin with open options. + * + * @return An OutputStream + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to an OutputStream. + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @see AbstractOrigin#getOutputStream(OpenOption...) + * @since 2.13.0 + */ + protected OutputStream getOutputStream() throws IOException { + return checkOrigin().getOutputStream(getOpenOptions()); + } + + /** + * Gets a Path from the origin. + * + * @return A Path + * @throws UnsupportedOperationException if the origin cannot be converted to a Path. + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @see AbstractOrigin#getPath() + * @since 2.13.0 + */ + protected Path getPath() { + return checkOrigin().getPath(); + } + + /** + * Gets an writer from the origin with open options. + * + * @return An writer. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException if the origin cannot be converted to a Writer. + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @see AbstractOrigin#getOutputStream(OpenOption...) + * @since 2.13.0 + */ + protected Writer getWriter() throws IOException { + return checkOrigin().getWriter(getCharset(), getOpenOptions()); + } + + /** + * Sets the buffer size. Invalid input (bufferSize <= 0) resets the value to its default. + * + *

Subclasses may ignore this setting. + * + * @param bufferSize the buffer size. + * @return this. + */ + public B setBufferSize(final int bufferSize) { + this.bufferSize = checkBufferSize(bufferSize > 0 ? bufferSize : bufferSizeDefault); + return asThis(); + } + + /** + * Sets the buffer size. + * + *

Subclasses may ignore this setting. + * + * @param bufferSize the buffer size, null resets to the default. + * @return this. + */ + public B setBufferSize(final Integer bufferSize) { + setBufferSize(bufferSize != null ? bufferSize : bufferSizeDefault); + return asThis(); + } + + /** + * Sets the buffer size checker function. Throws a {@link IllegalArgumentException} by default. + * + * @param bufferSizeChecker the buffer size checker function. null resets to the default behavior. + * @return this + * @since 2.14.0 + */ + public B setBufferSizeChecker(final IntUnaryOperator bufferSizeChecker) { + this.bufferSizeChecker = bufferSizeChecker != null ? bufferSizeChecker : defaultSizeChecker; + return asThis(); + } + + /** + * Sets the buffer size for subclasses to initialize. + * + *

Subclasses may ignore this setting. + * + * @param bufferSizeDefault the buffer size, null resets to the default. + * @return this. + */ + protected B setBufferSizeDefault(final int bufferSizeDefault) { + this.bufferSizeDefault = bufferSizeDefault; + return asThis(); + } + + /** + * The maximum buffer size checked by the buffer size checker. Values less or equal to 0, resets + * to the int max value. By default, if this value is exceeded, this methods throws an {@link + * IllegalArgumentException}. + * + * @param bufferSizeMax maximum buffer size checked by the buffer size checker. + * @return this. + * @since 2.14.0 + */ + public B setBufferSizeMax(final int bufferSizeMax) { + this.bufferSizeMax = bufferSizeMax > 0 ? bufferSizeMax : DEFAULT_MAX_VALUE; + return asThis(); + } + + /** + * Sets the Charset. + * + *

Subclasses may ignore this setting. + * + * @param charset the Charset, null resets to the default. + * @return this. + */ + public B setCharset(final Charset charset) { + this.charset = Charsets.toCharset(charset, charsetDefault); + return asThis(); + } + + /** + * Sets the Charset. + * + *

Subclasses may ignore this setting. + * + * @param charset the Charset name, null resets to the default. + * @return this. + */ + public B setCharset(final String charset) { + return setCharset(Charsets.toCharset(charset, charsetDefault)); + } + + /** + * Sets the Charset default for subclasses to initialize. + * + *

Subclasses may ignore this setting. + * + * @param defaultCharset the Charset name, null resets to the default. + * @return this. + */ + protected B setCharsetDefault(final Charset defaultCharset) { + this.charsetDefault = defaultCharset; + return asThis(); + } + + /** + * Sets the OpenOption[]. + * + *

Normally used with InputStream, OutputStream, and Writer. + * + *

Subclasses may ignore this setting. + * + * @param openOptions the OpenOption[] name, null resets to the default. + * @return this. + * @since 2.13.0 + * @see #setInputStream(InputStream) + * @see #setOutputStream(OutputStream) + * @see #setWriter(Writer) + */ + public B setOpenOptions(final OpenOption... openOptions) { + this.openOptions = openOptions != null ? openOptions : DEFAULT_OPEN_OPTIONS; + return asThis(); + } + + private int throwIae(final int size, final int max) { + throw new IllegalArgumentException(String.format("Request %,d exceeds maximum %,d", size, max)); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java new file mode 100644 index 000000000..be2aeb148 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.build; + +import org.apache.commons.io.function.IOSupplier; + +/** + * Abstracts supplying an instance of {@code T}. Use to implement the builder pattern. + * + * @param the type of instances to build. + * @param the type of builder subclass. + * @since 2.12.0 + */ +public abstract class AbstractSupplier> + implements IOSupplier { + + /** + * Returns this instance typed as the proper subclass type. + * + * @return this instance typed as the proper subclass type. + */ + @SuppressWarnings("unchecked") + protected B asThis() { + return (B) this; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java b/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java new file mode 100644 index 000000000..5d7b465cb --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.charset; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; + +/** + * Works with {@link CharsetDecoder}. + * + * @since 2.12.0 + */ +public final class CharsetDecoders { + + /** + * Returns the given non-null CharsetDecoder or a new default CharsetDecoder. + * + * @param charsetDecoder The CharsetDecoder to test. + * @return the given non-null CharsetDecoder or a new default CharsetDecoder. + */ + public static CharsetDecoder toCharsetDecoder(final CharsetDecoder charsetDecoder) { + return charsetDecoder != null ? charsetDecoder : Charset.defaultCharset().newDecoder(); + } + + /** No instances. */ + private CharsetDecoders() { + // No instances. + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java b/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java new file mode 100644 index 000000000..8a37925bf --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.charset; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.util.function.Supplier; + +/** + * Works with {@link CharsetEncoder}. + * + * @since 2.12.0 + */ +public final class CharsetEncoders { + + /** + * Returns the given non-null CharsetEncoder or a new default CharsetEncoder. + * + * @param charsetEncoder The CharsetEncoder to test. + * @return the given non-null CharsetEncoder or a new default CharsetEncoder. + */ + public static CharsetEncoder toCharsetEncoder(final CharsetEncoder charsetEncoder) { + return toCharsetEncoder(charsetEncoder, () -> Charset.defaultCharset().newEncoder()); + } + + /** + * Returns the given non-null CharsetEncoder or a new default CharsetEncoder. + * + * @param charsetEncoder The CharsetEncoder to test. + * @param defaultSupplier The CharsetEncoder supplier to get when charsetEncoder is null. + * @return the given non-null CharsetEncoder or a new default CharsetEncoder. + * @since 2.13.0 + */ + public static CharsetEncoder toCharsetEncoder( + final CharsetEncoder charsetEncoder, final Supplier defaultSupplier) { + return charsetEncoder != null ? charsetEncoder : defaultSupplier.get(); + } + + /** No instances. */ + private CharsetEncoders() { + // No instances. + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java b/java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java new file mode 100644 index 000000000..d969eb11f --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java @@ -0,0 +1,419 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import java.math.BigInteger; +import java.util.Objects; + +/** + * Provides counters for files, directories, and sizes, as a visit proceeds. + * + * @since 2.7 + */ +public class Counters { + + /** Counts files, directories, and sizes, as a visit proceeds. */ + private static class AbstractPathCounters implements PathCounters { + + private final Counter byteCounter; + private final Counter directoryCounter; + private final Counter fileCounter; + + /** + * Constructs a new instance. + * + * @param byteCounter the byte counter. + * @param directoryCounter the directory counter. + * @param fileCounter the file counter. + */ + protected AbstractPathCounters( + final Counter byteCounter, final Counter directoryCounter, final Counter fileCounter) { + this.byteCounter = byteCounter; + this.directoryCounter = directoryCounter; + this.fileCounter = fileCounter; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof AbstractPathCounters)) { + return false; + } + final AbstractPathCounters other = (AbstractPathCounters) obj; + return Objects.equals(byteCounter, other.byteCounter) + && Objects.equals(directoryCounter, other.directoryCounter) + && Objects.equals(fileCounter, other.fileCounter); + } + + @Override + public Counter getByteCounter() { + return byteCounter; + } + + @Override + public Counter getDirectoryCounter() { + return directoryCounter; + } + + /** + * Gets the count of visited files. + * + * @return the byte count of visited files. + */ + @Override + public Counter getFileCounter() { + return this.fileCounter; + } + + @Override + public int hashCode() { + return Objects.hash(byteCounter, directoryCounter, fileCounter); + } + + @Override + public void reset() { + byteCounter.reset(); + directoryCounter.reset(); + fileCounter.reset(); + } + + @Override + public String toString() { + return String.format( + "%,d files, %,d directories, %,d bytes", + Long.valueOf(fileCounter.get()), + Long.valueOf(directoryCounter.get()), + Long.valueOf(byteCounter.get())); + } + } + + /** Counts using a {@link BigInteger} number. */ + private static final class BigIntegerCounter implements Counter { + + private BigInteger value = BigInteger.ZERO; + + @Override + public void add(final long val) { + value = value.add(BigInteger.valueOf(val)); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Counter)) { + return false; + } + final Counter other = (Counter) obj; + return Objects.equals(value, other.getBigInteger()); + } + + @Override + public long get() { + return value.longValueExact(); + } + + @Override + public BigInteger getBigInteger() { + return value; + } + + @Override + public Long getLong() { + return Long.valueOf(value.longValueExact()); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public void increment() { + value = value.add(BigInteger.ONE); + } + + @Override + public void reset() { + value = BigInteger.ZERO; + } + + @Override + public String toString() { + return value.toString(); + } + } + + /** Counts files, directories, and sizes, as a visit proceeds, using BigInteger numbers. */ + private static final class BigIntegerPathCounters extends AbstractPathCounters { + + /** Constructs a new initialized instance. */ + protected BigIntegerPathCounters() { + super(bigIntegerCounter(), bigIntegerCounter(), bigIntegerCounter()); + } + } + + /** Counts using a number. */ + public interface Counter { + + /** + * Adds the given number to this counter. + * + * @param val the value to add. + */ + void add(long val); + + /** + * Gets the counter as a long. + * + * @return the counter as a long. + */ + long get(); + + /** + * Gets the counter as a BigInteger. + * + * @return the counter as a BigInteger. + */ + BigInteger getBigInteger(); + + /** + * Gets the counter as a Long. + * + * @return the counter as a Long. + */ + Long getLong(); + + /** Adds one to this counter. */ + void increment(); + + /** Resets this count to 0. */ + default void reset() { + // binary compat, do nothing + } + } + + /** Counts using a {@code long} number. */ + private static final class LongCounter implements Counter { + + private long value; + + @Override + public void add(final long add) { + value += add; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Counter)) { + return false; + } + final Counter other = (Counter) obj; + return value == other.get(); + } + + @Override + public long get() { + return value; + } + + @Override + public BigInteger getBigInteger() { + return BigInteger.valueOf(value); + } + + @Override + public Long getLong() { + return Long.valueOf(value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public void increment() { + value++; + } + + @Override + public void reset() { + value = 0L; + } + + @Override + public String toString() { + return Long.toString(value); + } + } + + /** Counts files, directories, and sizes, as a visit proceeds, using long numbers. */ + private static final class LongPathCounters extends AbstractPathCounters { + + /** Constructs a new initialized instance. */ + protected LongPathCounters() { + super(longCounter(), longCounter(), longCounter()); + } + } + + /** Counts nothing. */ + private static final class NoopCounter implements Counter { + + static final NoopCounter INSTANCE = new NoopCounter(); + + @Override + public void add(final long add) { + // noop + } + + @Override + public long get() { + return 0; + } + + @Override + public BigInteger getBigInteger() { + return BigInteger.ZERO; + } + + @Override + public Long getLong() { + return 0L; + } + + @Override + public void increment() { + // noop + } + + /** + * Returns {@code "0"}, always. + * + * @return {@code "0"}, always. + * @since 2.12.0 + */ + @Override + public String toString() { + return "0"; + } + } + + /** Counts nothing. */ + private static final class NoopPathCounters extends AbstractPathCounters { + + static final NoopPathCounters INSTANCE = new NoopPathCounters(); + + /** Constructs a new initialized instance. */ + private NoopPathCounters() { + super(noopCounter(), noopCounter(), noopCounter()); + } + } + + /** Counts files, directories, and sizes, as a visit proceeds. */ + public interface PathCounters { + + /** + * Gets the byte counter. + * + * @return the byte counter. + */ + Counter getByteCounter(); + + /** + * Gets the directory counter. + * + * @return the directory counter. + */ + Counter getDirectoryCounter(); + + /** + * Gets the file counter. + * + * @return the file counter. + */ + Counter getFileCounter(); + + /** Resets the counts to 0. */ + default void reset() { + // binary compat, do nothing + } + } + + /** + * Returns a new BigInteger Counter. + * + * @return a new BigInteger Counter. + */ + public static Counter bigIntegerCounter() { + return new BigIntegerCounter(); + } + + /** + * Returns a new BigInteger PathCounters. + * + * @return a new BigInteger PathCounters. + */ + public static PathCounters bigIntegerPathCounters() { + return new BigIntegerPathCounters(); + } + + /** + * Returns a new long Counter. + * + * @return a new long Counter. + */ + public static Counter longCounter() { + return new LongCounter(); + } + + /** + * Returns a new BigInteger PathCounters. + * + * @return a new BigInteger PathCounters. + */ + public static PathCounters longPathCounters() { + return new LongPathCounters(); + } + + /** + * Returns the no-op Counter. + * + * @return the no-op Counter. + * @since 2.9.0 + */ + public static Counter noopCounter() { + return NoopCounter.INSTANCE; + } + + /** + * Returns the no-op PathCounters. + * + * @return the no-op PathCounters. + * @since 2.9.0 + */ + public static PathCounters noopPathCounters() { + return NoopPathCounters.INSTANCE; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java b/java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java new file mode 100644 index 000000000..d4ac0a111 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import org.apache.commons.io.file.Counters.PathCounters; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.SymbolicLinkFileFilter; +import org.apache.commons.io.filefilter.TrueFileFilter; +import org.apache.commons.io.function.IOBiFunction; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Objects; + +/** + * Counts files, directories, and sizes, as a visit proceeds. + * + * @since 2.7 + */ +public class CountingPathVisitor extends SimplePathVisitor { + + static final String[] EMPTY_STRING_ARRAY = {}; + + static IOFileFilter defaultDirFilter() { + return TrueFileFilter.INSTANCE; + } + + static IOFileFilter defaultFileFilter() { + return new SymbolicLinkFileFilter(FileVisitResult.TERMINATE, FileVisitResult.CONTINUE); + } + + /** + * Constructs a new instance configured with a {@link BigInteger} {@link PathCounters}. + * + * @return a new instance configured with a {@link BigInteger} {@link PathCounters}. + */ + public static CountingPathVisitor withBigIntegerCounters() { + return new CountingPathVisitor(Counters.bigIntegerPathCounters()); + } + + /** + * Constructs a new instance configured with a {@code long} {@link PathCounters}. + * + * @return a new instance configured with a {@code long} {@link PathCounters}. + */ + public static CountingPathVisitor withLongCounters() { + return new CountingPathVisitor(Counters.longPathCounters()); + } + + private final PathCounters pathCounters; + private final PathFilter fileFilter; + private final PathFilter dirFilter; + + /** + * Constructs a new instance. + * + * @param pathCounter How to count path visits. + */ + public CountingPathVisitor(final PathCounters pathCounter) { + this(pathCounter, defaultFileFilter(), defaultDirFilter()); + } + + /** + * Constructs a new instance. + * + * @param pathCounter How to count path visits. + * @param fileFilter Filters which files to count. + * @param dirFilter Filters which directories to count. + * @since 2.9.0 + */ + public CountingPathVisitor( + final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter) { + this.pathCounters = Objects.requireNonNull(pathCounter, "pathCounter"); + this.fileFilter = Objects.requireNonNull(fileFilter, "fileFilter"); + this.dirFilter = Objects.requireNonNull(dirFilter, "dirFilter"); + } + + /** + * Constructs a new instance. + * + * @param pathCounter How to count path visits. + * @param fileFilter Filters which files to count. + * @param dirFilter Filters which directories to count. + * @param visitFileFailed Called on {@link #visitFileFailed(Path, IOException)}. + * @since 2.12.0 + */ + public CountingPathVisitor( + final PathCounters pathCounter, + final PathFilter fileFilter, + final PathFilter dirFilter, + final IOBiFunction visitFileFailed) { + super(visitFileFailed); + this.pathCounters = Objects.requireNonNull(pathCounter, "pathCounter"); + this.fileFilter = Objects.requireNonNull(fileFilter, "fileFilter"); + this.dirFilter = Objects.requireNonNull(dirFilter, "dirFilter"); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof CountingPathVisitor)) { + return false; + } + final CountingPathVisitor other = (CountingPathVisitor) obj; + return Objects.equals(pathCounters, other.pathCounters); + } + + /** + * Gets the visitation counts. + * + * @return the visitation counts. + */ + public PathCounters getPathCounters() { + return pathCounters; + } + + @Override + public int hashCode() { + return Objects.hash(pathCounters); + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) + throws IOException { + updateDirCounter(dir, exc); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attributes) + throws IOException { + final FileVisitResult accept = dirFilter.accept(dir, attributes); + return accept != FileVisitResult.CONTINUE + ? FileVisitResult.SKIP_SUBTREE + : FileVisitResult.CONTINUE; + } + + @Override + public String toString() { + return pathCounters.toString(); + } + + /** + * Updates the counter for visiting the given directory. + * + * @param dir the visited directory. + * @param exc Encountered exception. + * @since 2.9.0 + */ + protected void updateDirCounter(final Path dir, final IOException exc) { + pathCounters.getDirectoryCounter().increment(); + } + + /** + * Updates the counters for visiting the given file. + * + * @param file the visited file. + * @param attributes the visited file attributes. + */ + protected void updateFileCounters(final Path file, final BasicFileAttributes attributes) { + pathCounters.getFileCounter().increment(); + pathCounters.getByteCounter().add(attributes.size()); + } + + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) + throws IOException { + // Note: A file can be a symbolic link to a directory. + if (Files.exists(file) && fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE) { + updateFileCounters(file, attributes); + } + return FileVisitResult.CONTINUE; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java b/java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java new file mode 100644 index 000000000..97e0ebcd1 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +/** + * An object that configures how to delete a file. + * + *

The {@link StandardDeleteOption} enumeration type defines our standard options. + * + * @see StandardDeleteOption + * @since 2.8.0 + */ +public interface DeleteOption { + // empty +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java b/java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java new file mode 100644 index 000000000..d671d68c4 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import org.apache.commons.io.file.Counters.PathCounters; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Arrays; +import java.util.Objects; + +/** + * Deletes files and directories as a visit proceeds. + * + * @since 2.7 + */ +public class DeletingPathVisitor extends CountingPathVisitor { + + /** + * Constructs a new instance configured with a BigInteger {@link PathCounters}. + * + * @return a new instance configured with a BigInteger {@link PathCounters}. + */ + public static DeletingPathVisitor withBigIntegerCounters() { + return new DeletingPathVisitor(Counters.bigIntegerPathCounters()); + } + + /** + * Constructs a new instance configured with a long {@link PathCounters}. + * + * @return a new instance configured with a long {@link PathCounters}. + */ + public static DeletingPathVisitor withLongCounters() { + return new DeletingPathVisitor(Counters.longPathCounters()); + } + + private final String[] skip; + private final boolean overrideReadOnly; + private final LinkOption[] linkOptions; + + /** + * Constructs a new visitor that deletes files except for the files and directories explicitly + * given. + * + * @param pathCounter How to count visits. + * @param deleteOption How deletion is handled. + * @param skip The files to skip deleting. + * @since 2.8.0 + */ + public DeletingPathVisitor( + final Counters.PathCounters pathCounter, + final DeleteOption[] deleteOption, + final String... skip) { + this(pathCounter, PathUtils.noFollowLinkOptionArray(), deleteOption, skip); + } + + /** + * Constructs a new visitor that deletes files except for the files and directories explicitly + * given. + * + * @param pathCounter How to count visits. + * @param linkOptions How symbolic links are handled. + * @param deleteOption How deletion is handled. + * @param skip The files to skip deleting. + * @since 2.9.0 + */ + public DeletingPathVisitor( + final Counters.PathCounters pathCounter, + final LinkOption[] linkOptions, + final DeleteOption[] deleteOption, + final String... skip) { + super(pathCounter); + final String[] temp = skip != null ? skip.clone() : EMPTY_STRING_ARRAY; + Arrays.sort(temp); + this.skip = temp; + this.overrideReadOnly = StandardDeleteOption.overrideReadOnly(deleteOption); + // TODO Files.deleteIfExists() never follows links, so use LinkOption.NOFOLLOW_LINKS in other + // calls to Files. + this.linkOptions = + linkOptions == null ? PathUtils.noFollowLinkOptionArray() : linkOptions.clone(); + } + + /** + * Constructs a new visitor that deletes files except for the files and directories explicitly + * given. + * + * @param pathCounter How to count visits. + * @param skip The files to skip deleting. + */ + public DeletingPathVisitor(final Counters.PathCounters pathCounter, final String... skip) { + this(pathCounter, PathUtils.EMPTY_DELETE_OPTION_ARRAY, skip); + } + + /** + * Returns true to process the given path, false if not. + * + * @param path the path to test. + * @return true to process the given path, false if not. + */ + private boolean accept(final Path path) { + return Arrays.binarySearch(skip, PathUtils.getFileNameString(path)) < 0; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final DeletingPathVisitor other = (DeletingPathVisitor) obj; + return overrideReadOnly == other.overrideReadOnly && Arrays.equals(skip, other.skip); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Arrays.hashCode(skip); + result = prime * result + Objects.hash(overrideReadOnly); + return result; + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) + throws IOException { + if (PathUtils.isEmptyDirectory(dir)) { + Files.deleteIfExists(dir); + } + return super.postVisitDirectory(dir, exc); + } + + @Override + public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) + throws IOException { + super.preVisitDirectory(dir, attrs); + return accept(dir) ? FileVisitResult.CONTINUE : FileVisitResult.SKIP_SUBTREE; + } + + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) + throws IOException { + if (accept(file)) { + // delete files and valid links, respecting linkOptions + if (Files.exists(file, linkOptions)) { + if (overrideReadOnly) { + PathUtils.setReadOnly(file, false, linkOptions); + } + Files.deleteIfExists(file); + } + // invalid links will survive previous delete, different approach needed: + if (Files.isSymbolicLink(file)) { + try { + // deleteIfExists does not work for this case + Files.delete(file); + } catch (final NoSuchFileException ignored) { + // ignore + } + } + } + updateFileCounters(file, attrs); + return FileVisitResult.CONTINUE; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java new file mode 100644 index 000000000..b30c67fda --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * A filter for {@link Path}s. + * + * @since 2.9.0 + */ +@FunctionalInterface +public interface PathFilter { + + /** + * Tests whether or not to include the specified Path in a result. + * + * @param path The Path to test. + * @param attributes the file's basic attributes (TODO may be null). + * @return a FileVisitResult + */ + FileVisitResult accept(Path path, BasicFileAttributes attributes); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java b/java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java new file mode 100644 index 000000000..4a1696e03 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -0,0 +1,539 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.commons.io.file; + +import org.apache.commons.io.function.IOFunction; +import org.apache.commons.io.function.IOSupplier; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.AccessDeniedException; +import java.nio.file.CopyOption; +import java.nio.file.DirectoryStream; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.NoSuchFileException; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.DosFileAttributeView; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; + +public class PathUtils { + public static final LinkOption[] NOFOLLOW_LINK_OPTION_ARRAY = {LinkOption.NOFOLLOW_LINKS}; + + /** Empty {@link OpenOption} array. */ + public static final OpenOption[] EMPTY_OPEN_OPTION_ARRAY = {}; + + public static final LinkOption[] EMPTY_LINK_OPTION_ARRAY = {}; + public static final DeleteOption[] EMPTY_DELETE_OPTION_ARRAY = {}; + + public static Counters.PathCounters delete( + final Path path, final LinkOption[] linkOptions, final DeleteOption... deleteOptions) + throws IOException { + // File deletion through Files deletes links, not targets, so use LinkOption.NOFOLLOW_LINKS. + return Files.isDirectory(path, linkOptions) + ? deleteDirectory(path, linkOptions, deleteOptions) + : deleteFile(path, linkOptions, deleteOptions); + } + + public static Counters.PathCounters deleteFile( + final Path file, final DeleteOption... deleteOptions) throws IOException { + // Files.deleteIfExists() never follows links, so use LinkOption.NOFOLLOW_LINKS in other calls + // to Files. + return deleteFile(file, noFollowLinkOptionArray(), deleteOptions); + } + + public static LinkOption[] noFollowLinkOptionArray() { + return NOFOLLOW_LINK_OPTION_ARRAY.clone(); + } + + public static Counters.PathCounters deleteFile( + final Path file, final LinkOption[] linkOptions, final DeleteOption... deleteOptions) + throws NoSuchFileException, IOException { + // + // TODO Needs clean up + // + if (Files.isDirectory(file, linkOptions)) { + throw new NoSuchFileException(file.toString()); + } + final Counters.PathCounters pathCounts = Counters.longPathCounters(); + boolean exists = exists(file, linkOptions); + long size = exists && !Files.isSymbolicLink(file) ? Files.size(file) : 0; + try { + if (Files.deleteIfExists(file)) { + pathCounts.getFileCounter().increment(); + pathCounts.getByteCounter().add(size); + return pathCounts; + } + } catch (final AccessDeniedException ignored) { + // Ignore and try again below. + } + final Path parent = getParent(file); + PosixFileAttributes posixFileAttributes = null; + try { + if (overrideReadOnly(deleteOptions)) { + posixFileAttributes = readPosixFileAttributes(parent, linkOptions); + setReadOnly(file, false, linkOptions); + } + // Read size _after_ having read/execute access on POSIX. + exists = exists(file, linkOptions); + size = exists && !Files.isSymbolicLink(file) ? Files.size(file) : 0; + if (Files.deleteIfExists(file)) { + pathCounts.getFileCounter().increment(); + pathCounts.getByteCounter().add(size); + } + } finally { + if (posixFileAttributes != null) { + Files.setPosixFilePermissions(parent, posixFileAttributes.permissions()); + } + } + return pathCounts; + } + + public static Path setReadOnly( + final Path path, final boolean readOnly, final LinkOption... linkOptions) throws IOException { + try { + // Windows is simplest + if (setDosReadOnly(path, readOnly, linkOptions)) { + return path; + } + } catch (final IOException ignored) { + // Retry with POSIX below. + } + final Path parent = getParent(path); + if (!isPosix( + parent, linkOptions)) { // Test parent because we may not the permissions to test the file. + throw new IOException( + String.format( + "DOS or POSIX file operations not available for '%s', linkOptions %s", + path, Arrays.toString(linkOptions))); + } + // POSIX + if (readOnly) { + // RO + // File, then parent dir (if any). + setPosixReadOnlyFile(path, readOnly, linkOptions); + setPosixDeletePermissions(parent, false, linkOptions); + } else { + // RE + // Parent dir (if any), then file. + setPosixDeletePermissions(parent, true, linkOptions); + } + return path; + } + + private static boolean setPosixDeletePermissions( + final Path parent, final boolean enableDeleteChildren, final LinkOption... linkOptions) + throws IOException { + // To delete a file in POSIX, you need write and execute permissions on its parent directory. + // @formatter:off + return setPosixPermissions( + parent, + enableDeleteChildren, + Arrays.asList( + PosixFilePermission.OWNER_WRITE, + // PosixFilePermission.GROUP_WRITE, + // PosixFilePermission.OTHERS_WRITE, + PosixFilePermission.OWNER_EXECUTE + // PosixFilePermission.GROUP_EXECUTE, + // PosixFilePermission.OTHERS_EXECUTE + ), + linkOptions); + // @formatter:on + } + + private static boolean setPosixPermissions( + final Path path, + final boolean addPermissions, + final List updatePermissions, + final LinkOption... linkOptions) + throws IOException { + if (path != null) { + final Set permissions = Files.getPosixFilePermissions(path, linkOptions); + final Set newPermissions = new HashSet<>(permissions); + if (addPermissions) { + newPermissions.addAll(updatePermissions); + } else { + newPermissions.removeAll(updatePermissions); + } + if (!newPermissions.equals(permissions)) { + Files.setPosixFilePermissions(path, newPermissions); + } + return true; + } + return false; + } + + private static void setPosixReadOnlyFile( + final Path path, final boolean readOnly, final LinkOption... linkOptions) throws IOException { + // Not Windows 10 + final Set permissions = Files.getPosixFilePermissions(path, linkOptions); + // @formatter:off + final List readPermissions = + Arrays.asList( + PosixFilePermission.OWNER_READ + // PosixFilePermission.GROUP_READ, + // PosixFilePermission.OTHERS_READ + ); + final List writePermissions = + Arrays.asList( + PosixFilePermission.OWNER_WRITE + // PosixFilePermission.GROUP_WRITE, + // PosixFilePermission.OTHERS_WRITE + ); + // @formatter:on + if (readOnly) { + // RO: We can read, we cannot write. + permissions.addAll(readPermissions); + permissions.removeAll(writePermissions); + } else { + // Not RO: We can read, we can write. + permissions.addAll(readPermissions); + permissions.addAll(writePermissions); + } + Files.setPosixFilePermissions(path, permissions); + } + + public static boolean isPosix(final Path test, final LinkOption... options) { + return exists(test, options) && readPosixFileAttributes(test, options) != null; + } + + private static boolean exists(final Path path, final LinkOption... options) { + return path != null && (options != null ? Files.exists(path, options) : Files.exists(path)); + } + + public static PosixFileAttributes readPosixFileAttributes( + final Path path, final LinkOption... options) { + return readAttributes(path, PosixFileAttributes.class, options); + } + + private static boolean setDosReadOnly( + final Path path, final boolean readOnly, final LinkOption... linkOptions) throws IOException { + final DosFileAttributeView dosFileAttributeView = getDosFileAttributeView(path, linkOptions); + if (dosFileAttributeView != null) { + dosFileAttributeView.setReadOnly(readOnly); + return true; + } + return false; + } + + public static A readAttributes( + final Path path, final Class type, final LinkOption... options) { + try { + return path == null ? null : Files.readAttributes(path, type, options); + } catch (final UnsupportedOperationException | IOException e) { + // For example, on Windows. + return null; + } + } + + public static DosFileAttributeView getDosFileAttributeView( + final Path path, final LinkOption... options) { + return Files.getFileAttributeView(path, DosFileAttributeView.class, options); + } + + public static Counters.PathCounters deleteDirectory( + final Path directory, final LinkOption[] linkOptions, final DeleteOption... deleteOptions) + throws IOException { + return visitFileTree( + new DeletingPathVisitor(Counters.longPathCounters(), linkOptions, deleteOptions), + directory) + .getPathCounters(); + } + + public static > T visitFileTree( + final T visitor, final Path directory) throws IOException { + Files.walkFileTree(directory, visitor); + return visitor; + } + + private static Path getParent(final Path path) { + return path == null ? null : path.getParent(); + } + + private static boolean overrideReadOnly(final DeleteOption... deleteOptions) { + if (deleteOptions == null) { + return false; + } + return Stream.of(deleteOptions).anyMatch(e -> e == StandardDeleteOption.OVERRIDE_READ_ONLY); + } + + public static String getFileNameString(final Path path) { + return getFileName(path, Path::toString); + } + + public static R getFileName(final Path path, final Function function) { + final Path fileName = path != null ? path.getFileName() : null; + return fileName != null ? function.apply(fileName) : null; + } + + public static boolean isEmptyDirectory(final Path directory) throws IOException { + try (DirectoryStream directoryStream = Files.newDirectoryStream(directory)) { + return !directoryStream.iterator().hasNext(); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * A LinkOption used to follow link in this class, the inverse of {@link + * LinkOption#NOFOLLOW_LINKS}. + * + * @since 2.12.0 + */ + static final LinkOption NULL_LINK_OPTION = null; + + private static final OpenOption[] OPEN_OPTIONS_TRUNCATE = { + StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING + }; + + private static final OpenOption[] OPEN_OPTIONS_APPEND = { + StandardOpenOption.CREATE, StandardOpenOption.APPEND + }; + + /** + * Deletes a directory including subdirectories. + * + * @param directory directory to delete. + * @return The visitor used to delete the given directory. + * @throws IOException if an I/O error is thrown by a visitor method. + */ + public static Counters.PathCounters deleteDirectory(final Path directory) throws IOException { + return deleteDirectory(directory, EMPTY_DELETE_OPTION_ARRAY); + } + + /** + * Deletes a directory including subdirectories. + * + * @param directory directory to delete. + * @param deleteOptions How to handle deletion. + * @return The visitor used to delete the given directory. + * @throws IOException if an I/O error is thrown by a visitor method. + * @since 2.8.0 + */ + public static Counters.PathCounters deleteDirectory( + final Path directory, final DeleteOption... deleteOptions) throws IOException { + final LinkOption[] linkOptions = PathUtils.noFollowLinkOptionArray(); + // POSIX ops will noop on non-POSIX. + return withPosixFileAttributes( + getParent(directory), + linkOptions, + overrideReadOnly(deleteOptions), + pfa -> + visitFileTree( + new DeletingPathVisitor( + Counters.longPathCounters(), linkOptions, deleteOptions), + directory) + .getPathCounters()); + } + + private static R withPosixFileAttributes( + final Path path, + final LinkOption[] linkOptions, + final boolean overrideReadOnly, + final IOFunction function) + throws IOException { + final PosixFileAttributes posixFileAttributes = + overrideReadOnly ? readPosixFileAttributes(path, linkOptions) : null; + try { + return function.apply(posixFileAttributes); + } finally { + if (posixFileAttributes != null && path != null && Files.exists(path, linkOptions)) { + Files.setPosixFilePermissions(path, posixFileAttributes.permissions()); + } + } + } + + /** + * Creates a new OutputStream by opening or creating a file, returning an output stream that may + * be used to write bytes to the file. + * + * @param path the Path. + * @param append Whether or not to append. + * @return a new OutputStream. + * @throws IOException if an I/O error occurs. + * @see Files#newOutputStream(Path, OpenOption...) + * @since 2.12.0 + */ + public static OutputStream newOutputStream(final Path path, final boolean append) + throws IOException { + return newOutputStream( + path, EMPTY_LINK_OPTION_ARRAY, append ? OPEN_OPTIONS_APPEND : OPEN_OPTIONS_TRUNCATE); + } + + static OutputStream newOutputStream( + final Path path, final LinkOption[] linkOptions, final OpenOption... openOptions) + throws IOException { + if (!exists(path, linkOptions)) { + createParentDirectories( + path, linkOptions != null && linkOptions.length > 0 ? linkOptions[0] : NULL_LINK_OPTION); + } + final List list = + new ArrayList<>(Arrays.asList(openOptions != null ? openOptions : EMPTY_OPEN_OPTION_ARRAY)); + list.addAll(Arrays.asList(linkOptions != null ? linkOptions : EMPTY_LINK_OPTION_ARRAY)); + return Files.newOutputStream(path, list.toArray(EMPTY_OPEN_OPTION_ARRAY)); + } + + /** + * Creates the parent directories for the given {@code path}. + * + *

If the parent directory already exists, then return it. + * + *

+ * + * @param path The path to a file (or directory). + * @param attrs An optional list of file attributes to set atomically when creating the + * directories. + * @return The Path for the {@code path}'s parent directory or null if the given path has no + * parent. + * @throws IOException if an I/O error occurs. + * @since 2.9.0 + */ + public static Path createParentDirectories(final Path path, final FileAttribute... attrs) + throws IOException { + return createParentDirectories(path, LinkOption.NOFOLLOW_LINKS, attrs); + } + + /** + * Creates the parent directories for the given {@code path}. + * + *

If the parent directory already exists, then return it. + * + *

+ * + * @param path The path to a file (or directory). + * @param linkOption A {@link LinkOption} or null. + * @param attrs An optional list of file attributes to set atomically when creating the + * directories. + * @return The Path for the {@code path}'s parent directory or null if the given path has no + * parent. + * @throws IOException if an I/O error occurs. + * @since 2.12.0 + */ + public static Path createParentDirectories( + final Path path, final LinkOption linkOption, final FileAttribute... attrs) + throws IOException { + Path parent = getParent(path); + parent = linkOption == LinkOption.NOFOLLOW_LINKS ? parent : readIfSymbolicLink(parent); + if (parent == null) { + return null; + } + final boolean exists = + linkOption == null ? Files.exists(parent) : Files.exists(parent, linkOption); + return exists ? parent : Files.createDirectories(parent, attrs); + } + + private static Path readIfSymbolicLink(final Path path) throws IOException { + return path != null ? Files.isSymbolicLink(path) ? Files.readSymbolicLink(path) : path : null; + } + + /** + * Copies the InputStream from the supplier with {@link Files#copy(InputStream, Path, + * CopyOption...)}. + * + * @param in Supplies the InputStream. + * @param target See {@link Files#copy(InputStream, Path, CopyOption...)}. + * @param copyOptions See {@link Files#copy(InputStream, Path, CopyOption...)}. + * @return See {@link Files#copy(InputStream, Path, CopyOption...)} + * @throws IOException See {@link Files#copy(InputStream, Path, CopyOption...)} + * @since 2.12.0 + */ + public static long copy( + final IOSupplier in, final Path target, final CopyOption... copyOptions) + throws IOException { + try (InputStream inputStream = in.get()) { + return Files.copy(inputStream, target, copyOptions); + } + } + + /** + * Returns a stream of filtered paths. + * + * @param start the start path + * @param pathFilter the path filter + * @param maxDepth the maximum depth of directories to walk. + * @param readAttributes whether to call the filters with file attributes (false passes null). + * @param options the options to configure the walk. + * @return a filtered stream of paths. + * @throws IOException if an I/O error is thrown when accessing the starting file. + * @since 2.9.0 + */ + public static Stream walk( + final Path start, + final PathFilter pathFilter, + final int maxDepth, + final boolean readAttributes, + final FileVisitOption... options) + throws IOException { + return Files.walk(start, maxDepth, options) + .filter( + path -> + pathFilter.accept( + path, readAttributes ? readBasicFileAttributesUnchecked(path) : null) + == FileVisitResult.CONTINUE); + } + + /** + * Reads the BasicFileAttributes from the given path. Returns null instead of throwing {@link + * UnsupportedOperationException}. + * + * @param path the path to read. + * @return the path attributes. + * @throws UncheckedIOException if an I/O error occurs + * @since 2.9.0 + * @deprecated Use {@link #readBasicFileAttributes(Path, LinkOption...)}. + */ + @Deprecated + public static BasicFileAttributes readBasicFileAttributesUnchecked(final Path path) { + return readBasicFileAttributes(path, EMPTY_LINK_OPTION_ARRAY); + } + + /** + * Reads the BasicFileAttributes from the given path. Returns null instead of throwing {@link + * UnsupportedOperationException}. + * + * @param path the path to read. + * @param options options indicating how to handle symbolic links. + * @return the path attributes. + * @since 2.12.0 + */ + public static BasicFileAttributes readBasicFileAttributes( + final Path path, final LinkOption... options) { + return readAttributes(path, BasicFileAttributes.class, options); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java b/java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java new file mode 100644 index 000000000..c58237df5 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import java.nio.file.FileVisitor; +import java.nio.file.Path; + +/** + * A {@link FileVisitor} typed to a {@link Path}. + * + * @since 2.9.0 + */ +public interface PathVisitor extends FileVisitor { + // empty +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java b/java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java new file mode 100644 index 000000000..ffc0ed604 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import org.apache.commons.io.function.IOBiFunction; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.util.Objects; + +/** + * A {@link SimpleFileVisitor} typed to a {@link Path}. + * + * @since 2.7 + */ +public abstract class SimplePathVisitor extends SimpleFileVisitor implements PathVisitor { + + private final IOBiFunction visitFileFailedFunction; + + /** Constructs a new instance. */ + protected SimplePathVisitor() { + this.visitFileFailedFunction = super::visitFileFailed; + } + + /** + * Constructs a new instance. + * + * @param visitFileFailed Called on {@link #visitFileFailed(Path, IOException)}. + */ + protected SimplePathVisitor( + final IOBiFunction visitFileFailed) { + this.visitFileFailedFunction = Objects.requireNonNull(visitFileFailed, "visitFileFailed"); + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException exc) + throws IOException { + return visitFileFailedFunction.apply(file, exc); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java b/java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java new file mode 100644 index 000000000..aa6403f95 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.file; + +import org.apache.commons.io.IOUtils; + +import java.util.stream.Stream; + +/** + * Defines the standard delete options. + * + * @since 2.8.0 + */ +public enum StandardDeleteOption implements DeleteOption { + + /** + * Overrides the read-only attribute to allow deletion, on POSIX, this means Write and Execute on + * the parent. + */ + OVERRIDE_READ_ONLY; + + /** + * Returns true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}. + * + *

For now, assume the array is not sorted. + * + * @param options the array to test + * @return true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}. + */ + public static boolean overrideReadOnly(final DeleteOption[] options) { + if (IOUtils.length(options) == 0) { + return false; + } + return Stream.of(options).anyMatch(e -> OVERRIDE_READ_ONLY == e); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java new file mode 100644 index 000000000..179a4ac71 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.filefilter; + +import org.apache.commons.io.file.PathFilter; +import org.apache.commons.io.file.PathVisitor; +import org.apache.commons.io.function.IOSupplier; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; +import java.util.Objects; + +/** + * Abstracts the implementation of the {@link FileFilter} (IO), {@link FilenameFilter} (IO), {@link + * PathFilter} (NIO) interfaces via our own {@link IOFileFilter} interface. + * + *

Note that a subclass MUST override one of the {@code accept} methods, otherwise that subclass + * will infinitely loop. + * + * @since 1.0 + */ +public abstract class AbstractFileFilter implements IOFileFilter, PathVisitor { + + static FileVisitResult toDefaultFileVisitResult(final boolean accept) { + return accept ? FileVisitResult.CONTINUE : FileVisitResult.TERMINATE; + } + + /** What to do when this filter accepts. */ + private final FileVisitResult onAccept; + + /** What to do when this filter rejects. */ + private final FileVisitResult onReject; + + /** Constructs a new instance. */ + public AbstractFileFilter() { + this(FileVisitResult.CONTINUE, FileVisitResult.TERMINATE); + } + + /** + * Constructs a new instance. + * + * @param onAccept What to do on acceptance. + * @param onReject What to do on rejection. + * @since 2.12.0. + */ + protected AbstractFileFilter(final FileVisitResult onAccept, final FileVisitResult onReject) { + this.onAccept = onAccept; + this.onReject = onReject; + } + + /** + * Checks to see if the File should be accepted by this filter. + * + * @param file the File to check + * @return true if this file matches the test + */ + @Override + public boolean accept(final File file) { + Objects.requireNonNull(file, "file"); + return accept(file.getParentFile(), file.getName()); + } + + /** + * Checks to see if the File should be accepted by this filter. + * + * @param dir the directory File to check + * @param name the file name within the directory to check + * @return true if this file matches the test + */ + @Override + public boolean accept(final File dir, final String name) { + Objects.requireNonNull(name, "name"); + return accept(new File(dir, name)); + } + + void append(final List list, final StringBuilder buffer) { + for (int i = 0; i < list.size(); i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(list.get(i)); + } + } + + void append(final Object[] array, final StringBuilder buffer) { + for (int i = 0; i < array.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(array[i]); + } + } + + FileVisitResult get(final IOSupplier supplier) { + try { + return supplier.get(); + } catch (final IOException e) { + return handle(e); + } + } + + /** + * Handles exceptions caught while accepting. + * + * @param t the caught Throwable. + * @return the given Throwable. + * @since 2.9.0 + */ + protected FileVisitResult handle(final Throwable t) { + return FileVisitResult.TERMINATE; + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) + throws IOException { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attributes) + throws IOException { + return accept(dir, attributes); + } + + /** + * Converts a boolean into a FileVisitResult. + * + * @param accept accepted or rejected. + * @return a FileVisitResult. + */ + FileVisitResult toFileVisitResult(final boolean accept) { + return accept ? onAccept : onReject; + } + + /** + * Provides a String representation of this file filter. + * + * @return a String representation + */ + @Override + public String toString() { + return getClass().getSimpleName(); + } + + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) + throws IOException { + return accept(file, attributes); + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException exc) + throws IOException { + return FileVisitResult.CONTINUE; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java new file mode 100644 index 000000000..0657aaf49 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.FileFilter; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * A {@link FileFilter} providing conditional AND logic across a list of file filters. This filter + * returns {@code true} if all filters in the list return {@code true}. Otherwise, it returns {@code + * false}. Checking of the file filter list stops when the first filter returns {@code false}. + * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.0 + * @see FileFilterUtils#and(IOFileFilter...) + */ +public class AndFileFilter extends AbstractFileFilter + implements ConditionalFileFilter, Serializable { + + private static final long serialVersionUID = 7215974688563965257L; + + /** The list of file filters. */ + private final List fileFilters; + + /** + * Constructs a new empty instance. + * + * @since 1.1 + */ + public AndFileFilter() { + this(0); + } + + /** + * Constructs a new instance with the given initial list. + * + * @param initialList the initial list. + */ + private AndFileFilter(final ArrayList initialList) { + this.fileFilters = Objects.requireNonNull(initialList, "initialList"); + } + + /** + * Constructs a new instance with the given initial capacity. + * + * @param initialCapacity the initial capacity. + */ + private AndFileFilter(final int initialCapacity) { + this(new ArrayList<>(initialCapacity)); + } + + /** + * Constructs a new instance for the give filters. + * + * @param fileFilters filters to OR. + * @since 2.9.0 + */ + public AndFileFilter(final IOFileFilter... fileFilters) { + this(Objects.requireNonNull(fileFilters, "fileFilters").length); + addFileFilter(fileFilters); + } + + /** + * Constructs a new file filter that ANDs the result of other filters. + * + * @param filter1 the first filter, must second be null + * @param filter2 the first filter, must not be null + * @throws IllegalArgumentException if either filter is null + */ + public AndFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { + this(2); + addFileFilter(filter1); + addFileFilter(filter2); + } + + /** + * Constructs a new instance of {@link AndFileFilter} with the specified list of filters. + * + * @param fileFilters a List of IOFileFilter instances, copied. + * @since 1.1 + */ + public AndFileFilter(final List fileFilters) { + this(new ArrayList<>(Objects.requireNonNull(fileFilters, "fileFilters"))); + } + + /** {@inheritDoc} */ + @Override + public boolean accept(final File file) { + return !isEmpty() && fileFilters.stream().allMatch(fileFilter -> fileFilter.accept(file)); + } + + /** {@inheritDoc} */ + @Override + public boolean accept(final File file, final String name) { + return !isEmpty() && fileFilters.stream().allMatch(fileFilter -> fileFilter.accept(file, name)); + } + + /** + * {@inheritDoc} + * + * @since 2.9.0 + */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return isEmpty() + ? FileVisitResult.TERMINATE + : toDefaultFileVisitResult( + fileFilters.stream() + .allMatch( + fileFilter -> fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE)); + } + + /** {@inheritDoc} */ + @Override + public void addFileFilter(final IOFileFilter fileFilter) { + fileFilters.add(Objects.requireNonNull(fileFilter, "fileFilter")); + } + + /** + * Adds the given file filters. + * + * @param fileFilters the filters to add. + * @since 2.9.0 + */ + public void addFileFilter(final IOFileFilter... fileFilters) { + Stream.of(Objects.requireNonNull(fileFilters, "fileFilters")).forEach(this::addFileFilter); + } + + /** {@inheritDoc} */ + @Override + public List getFileFilters() { + return Collections.unmodifiableList(fileFilters); + } + + private boolean isEmpty() { + return fileFilters.isEmpty(); + } + + /** {@inheritDoc} */ + @Override + public boolean removeFileFilter(final IOFileFilter ioFileFilter) { + return fileFilters.remove(ioFileFilter); + } + + /** {@inheritDoc} */ + @Override + public void setFileFilters(final List fileFilters) { + this.fileFilters.clear(); + this.fileFilters.addAll(fileFilters); + } + + /** + * Builds a String representation of this file filter. + * + * @return a String representation + */ + @Override + public String toString() { + final StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + append(fileFilters, buffer); + buffer.append(")"); + return buffer.toString(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java new file mode 100644 index 000000000..52143d384 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.util.List; + +/** + * Defines operations for conditional file filters. + * + * @since 1.1 + */ +public interface ConditionalFileFilter { + + /** + * Adds the specified file filter to the list of file filters at the end of the list. + * + * @param ioFileFilter the filter to be added + * @since 1.1 + */ + void addFileFilter(IOFileFilter ioFileFilter); + + /** + * Gets this conditional file filter's list of file filters. + * + * @return the file filter list + * @since 1.1 + */ + List getFileFilters(); + + /** + * Removes the specified file filter. + * + * @param ioFileFilter filter to be removed + * @return {@code true} if the filter was found in the list, {@code false} otherwise + * @since 1.1 + */ + boolean removeFileFilter(IOFileFilter ioFileFilter); + + /** + * Sets the list of file filters, replacing any previously configured file filters on this filter. + * + * @param fileFilters the list of filters + * @since 1.1 + */ + void setFileFilters(List fileFilters); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java new file mode 100644 index 000000000..c61203015 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * A file filter that always returns false. + * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.0 + * @see FileFilterUtils#falseFileFilter() + */ +public class FalseFileFilter implements IOFileFilter, Serializable { + + private static final String TO_STRING = Boolean.FALSE.toString(); + + /** + * Singleton instance of false filter. + * + * @since 1.3 + */ + public static final IOFileFilter FALSE = new FalseFileFilter(); + + /** + * Singleton instance of false filter. Please use the identical FalseFileFilter.FALSE constant. + * The new name is more JDK 1.5 friendly as it doesn't clash with other values when using static + * imports. + */ + public static final IOFileFilter INSTANCE = FALSE; + + private static final long serialVersionUID = 6210271677940926200L; + + /** Restrictive constructor. */ + protected FalseFileFilter() {} + + /** + * Returns false. + * + * @param file the file to check (ignored) + * @return false + */ + @Override + public boolean accept(final File file) { + return false; + } + + /** + * Returns false. + * + * @param dir the directory to check (ignored) + * @param name the file name (ignored) + * @return false + */ + @Override + public boolean accept(final File dir, final String name) { + return false; + } + + /** + * Returns false. + * + * @param file the file to check (ignored) + * @return false + * @since 2.9.0 + */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return FileVisitResult.TERMINATE; + } + + @Override + public IOFileFilter and(final IOFileFilter fileFilter) { + // FALSE AND expression <=> FALSE + return INSTANCE; + } + + @Override + public IOFileFilter negate() { + return TrueFileFilter.INSTANCE; + } + + @Override + public IOFileFilter or(final IOFileFilter fileFilter) { + // FALSE OR expression <=> expression + return fileFilter; + } + + @Override + public String toString() { + return TO_STRING; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java new file mode 100644 index 000000000..549623175 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * This filter accepts {@link File}s that are files (not directories). + * + *

For example, here is how to print out a list of the real files within the current directory: + * + *

Using Classic IO

+ * + *
+ * File dir = FileUtils.current();
+ * String[] files = dir.list(FileFileFilter.INSTANCE);
+ * for (String file : files) {
+ *     System.out.println(file);
+ * }
+ * 
+ * + *

Using NIO

+ * + *
+ * final Path dir = PathUtils.current();
+ * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(FileFileFilter.INSTANCE);
+ * //
+ * // Walk one dir
+ * Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getFileList());
+ * //
+ * visitor.getPathCounters().reset();
+ * //
+ * // Walk dir tree
+ * Files.walkFileTree(dir, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getDirList());
+ * System.out.println(visitor.getFileList());
+ * 
+ * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.3 + * @see FileFilterUtils#fileFileFilter() + */ +public class FileFileFilter extends AbstractFileFilter implements Serializable { + + /** + * Singleton instance of file filter. + * + * @since 2.9.0 + */ + public static final IOFileFilter INSTANCE = new FileFileFilter(); + + /** + * Singleton instance of file filter. + * + * @deprecated Use {@link #INSTANCE}. + */ + @Deprecated public static final IOFileFilter FILE = INSTANCE; + + private static final long serialVersionUID = 5345244090827540862L; + + /** Restrictive constructor. */ + protected FileFileFilter() {} + + /** + * Checks to see if the file is a file. + * + * @param file the File to check + * @return true if the file is a file + */ + @Override + public boolean accept(final File file) { + return file.isFile(); + } + + /** + * Checks to see if the file is a file. + * + * @param file the File to check + * @return true if the file is a file + * @since 2.9.0 + */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return toFileVisitResult(Files.isRegularFile(file)); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java new file mode 100644 index 000000000..ed5fde7be --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.filefilter; + +import org.apache.commons.io.file.PathFilter; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * An interface which brings the {@link FileFilter}, {@link FilenameFilter}, {@link PathFilter}, and + * {@link PathMatcher} interfaces together. + * + * @since 1.0 + */ +public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter, PathMatcher { + + /** An empty String array. */ + String[] EMPTY_STRING_ARRAY = {}; + + /** + * Tests if a File should be accepted by this filter. + * + *

Defined in {@link FileFilter}. + * + * @param file the File to check. + * @return true if this file matches the test. + */ + @Override + boolean accept(File file); + + /** + * Tests if a File should be accepted by this filter. + * + *

Defined in {@link FilenameFilter}. + * + * @param dir the directory File to check. + * @param name the file name within the directory to check. + * @return true if this file matches the test. + */ + @Override + boolean accept(File dir, String name); + + /** + * Checks to see if a Path should be accepted by this filter. + * + * @param path the Path to check. + * @return true if this path matches the test. + * @since 2.9.0 + */ + @Override + default FileVisitResult accept(final Path path, final BasicFileAttributes attributes) { + return AbstractFileFilter.toDefaultFileVisitResult(path != null && accept(path.toFile())); + } + + /** + * Constructs a new "and" filter with this filter. + * + * @param fileFilter the filter to "and". + * @return a new filter. + * @since 2.9.0 + */ + default IOFileFilter and(final IOFileFilter fileFilter) { + return new AndFileFilter(this, fileFilter); + } + + /** + * Tests if a Path should be accepted by this filter. + * + * @param path the Path to check. + * @return true if this path matches the test. + * @since 2.14.0 + */ + @Override + default boolean matches(final Path path) { + return accept(path, null) != FileVisitResult.TERMINATE; + } + + /** + * Constructs a new "not" filter with this filter. + * + * @return a new filter. + * @since 2.9.0 + */ + default IOFileFilter negate() { + return new NotFileFilter(this); + } + + /** + * Constructs a new "or" filter with this filter. + * + * @param fileFilter the filter to "or". + * @return a new filter. + * @since 2.9.0 + */ + default IOFileFilter or(final IOFileFilter fileFilter) { + return new OrFileFilter(this, fileFilter); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java new file mode 100644 index 000000000..3943c2871 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Objects; + +/** + * This filter produces a logical NOT of the filters specified. + * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.0 + * @see FileFilterUtils#notFileFilter(IOFileFilter) + */ +public class NotFileFilter extends AbstractFileFilter implements Serializable { + + private static final long serialVersionUID = 6131563330944994230L; + + /** The filter */ + private final IOFileFilter filter; + + /** + * Constructs a new file filter that NOTs the result of another filter. + * + * @param filter the filter, must not be null + * @throws NullPointerException if the filter is null + */ + public NotFileFilter(final IOFileFilter filter) { + Objects.requireNonNull(filter, "filter"); + this.filter = filter; + } + + /** + * Returns the logical NOT of the underlying filter's return value for the same File. + * + * @param file the File to check + * @return true if the filter returns false + */ + @Override + public boolean accept(final File file) { + return !filter.accept(file); + } + + /** + * Returns the logical NOT of the underlying filter's return value for the same arguments. + * + * @param file the File directory + * @param name the file name + * @return true if the filter returns false + */ + @Override + public boolean accept(final File file, final String name) { + return !filter.accept(file, name); + } + + /** + * Returns the logical NOT of the underlying filter's return value for the same File. + * + * @param file the File to check + * @return true if the filter returns false + * @since 2.9.0 + */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return not(filter.accept(file, attributes)); + } + + private FileVisitResult not(final FileVisitResult accept) { + return accept == FileVisitResult.CONTINUE + ? FileVisitResult.TERMINATE + : FileVisitResult.CONTINUE; + } + + /** + * Provide a String representation of this file filter. + * + * @return a String representation + */ + @Override + public String toString() { + return "NOT (" + filter.toString() + ")"; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java new file mode 100644 index 000000000..5de7792e0 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.FileFilter; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * A {@link FileFilter} providing conditional OR logic across a list of file filters. This filter + * returns {@code true} if any filters in the list return {@code true}. Otherwise, it returns {@code + * false}. Checking of the file filter list stops when the first filter returns {@code true}. + * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.0 + * @see FileFilterUtils#or(IOFileFilter...) + */ +public class OrFileFilter extends AbstractFileFilter + implements ConditionalFileFilter, Serializable { + + private static final long serialVersionUID = 5767770777065432721L; + + /** The list of file filters. */ + private final List fileFilters; + + /** + * Constructs a new instance of {@link OrFileFilter}. + * + * @since 1.1 + */ + public OrFileFilter() { + this(0); + } + + /** + * Constructs a new instance with the given initial list. + * + * @param initialList the initial list. + */ + private OrFileFilter(final ArrayList initialList) { + this.fileFilters = Objects.requireNonNull(initialList, "initialList"); + } + + /** + * Constructs a new instance with the given initial capacity. + * + * @param initialCapacity the initial capacity. + */ + private OrFileFilter(final int initialCapacity) { + this(new ArrayList<>(initialCapacity)); + } + + /** + * Constructs a new instance for the give filters. + * + * @param fileFilters filters to OR. + * @since 2.9.0 + */ + public OrFileFilter(final IOFileFilter... fileFilters) { + this(Objects.requireNonNull(fileFilters, "fileFilters").length); + addFileFilter(fileFilters); + } + + /** + * Constructs a new file filter that ORs the result of other filters. + * + * @param filter1 the first filter, must not be null + * @param filter2 the second filter, must not be null + * @throws IllegalArgumentException if either filter is null + */ + public OrFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { + this(2); + addFileFilter(filter1); + addFileFilter(filter2); + } + + /** + * Constructs a new instance of {@link OrFileFilter} with the specified filters. + * + * @param fileFilters the file filters for this filter, copied. + * @since 1.1 + */ + public OrFileFilter(final List fileFilters) { + this(new ArrayList<>(Objects.requireNonNull(fileFilters, "fileFilters"))); + } + + /** {@inheritDoc} */ + @Override + public boolean accept(final File file) { + return fileFilters.stream().anyMatch(fileFilter -> fileFilter.accept(file)); + } + + /** {@inheritDoc} */ + @Override + public boolean accept(final File file, final String name) { + return fileFilters.stream().anyMatch(fileFilter -> fileFilter.accept(file, name)); + } + + /** {@inheritDoc} */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return toDefaultFileVisitResult( + fileFilters.stream() + .anyMatch( + fileFilter -> fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE)); + } + + /** {@inheritDoc} */ + @Override + public void addFileFilter(final IOFileFilter fileFilter) { + this.fileFilters.add(Objects.requireNonNull(fileFilter, "fileFilter")); + } + + /** + * Adds the given file filters. + * + * @param fileFilters the filters to add. + * @since 2.9.0 + */ + public void addFileFilter(final IOFileFilter... fileFilters) { + Stream.of(Objects.requireNonNull(fileFilters, "fileFilters")).forEach(this::addFileFilter); + } + + /** {@inheritDoc} */ + @Override + public List getFileFilters() { + return Collections.unmodifiableList(this.fileFilters); + } + + /** {@inheritDoc} */ + @Override + public boolean removeFileFilter(final IOFileFilter fileFilter) { + return this.fileFilters.remove(fileFilter); + } + + /** {@inheritDoc} */ + @Override + public void setFileFilters(final List fileFilters) { + this.fileFilters.clear(); + this.fileFilters.addAll(Objects.requireNonNull(fileFilters, "fileFilters")); + } + + /** + * Provide a String representation of this file filter. + * + * @return a String representation + */ + @Override + public String toString() { + final StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + append(fileFilters, buffer); + buffer.append(")"); + return buffer.toString(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java new file mode 100644 index 000000000..8fa74d74e --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import org.apache.commons.io.IOCase; + +import java.io.File; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * Filters files based on the suffix (what the file name ends with). This is used in retrieving all + * the files of a particular type. + * + *

For example, to retrieve and print all {@code *.java} files in the current directory: + * + *

Using Classic IO

+ * + *
+ * File dir = FileUtils.current();
+ * String[] files = dir.list(new SuffixFileFilter(".java"));
+ * for (String file : files) {
+ *     System.out.println(file);
+ * }
+ * 
+ * + *

Using NIO

+ * + *
+ * final Path dir = PathUtils.current();
+ * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new SuffixFileFilter(".java"));
+ * //
+ * // Walk one dir
+ * Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getFileList());
+ * //
+ * visitor.getPathCounters().reset();
+ * //
+ * // Walk dir tree
+ * Files.walkFileTree(dir, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getDirList());
+ * System.out.println(visitor.getFileList());
+ * 
+ * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.0 + * @see FileFilterUtils#suffixFileFilter(String) + * @see FileFilterUtils#suffixFileFilter(String, IOCase) + */ +public class SuffixFileFilter extends AbstractFileFilter implements Serializable { + + private static final long serialVersionUID = -3389157631240246157L; + + /** The file name suffixes to search for */ + private final String[] suffixes; + + /** Whether the comparison is case-sensitive. */ + private final IOCase ioCase; + + /** + * Constructs a new Suffix file filter for a list of suffixes. + * + * @param suffixes the suffixes to allow, must not be null + * @throws IllegalArgumentException if the suffix list is null + * @throws ClassCastException if the list does not contain Strings + */ + public SuffixFileFilter(final List suffixes) { + this(suffixes, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for a list of suffixes specifying case-sensitivity. + * + * @param suffixes the suffixes to allow, must not be null + * @param ioCase how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the suffix list is null + * @throws ClassCastException if the list does not contain Strings + * @since 1.4 + */ + public SuffixFileFilter(final List suffixes, final IOCase ioCase) { + Objects.requireNonNull(suffixes, "suffixes"); + this.suffixes = suffixes.toArray(EMPTY_STRING_ARRAY); + this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for a single extension. + * + * @param suffix the suffix to allow, must not be null + * @throws IllegalArgumentException if the suffix is null + */ + public SuffixFileFilter(final String suffix) { + this(suffix, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for an array of suffixes. + * + *

The array is not cloned, so could be changed after constructing the instance. This would be + * inadvisable however. + * + * @param suffixes the suffixes to allow, must not be null + * @throws NullPointerException if the suffix array is null + */ + public SuffixFileFilter(final String... suffixes) { + this(suffixes, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for a single extension specifying case-sensitivity. + * + * @param suffix the suffix to allow, must not be null + * @param ioCase how to handle case sensitivity, null means case-sensitive + * @throws NullPointerException if the suffix is null + * @since 1.4 + */ + public SuffixFileFilter(final String suffix, final IOCase ioCase) { + Objects.requireNonNull(suffix, "suffix"); + this.suffixes = new String[] {suffix}; + this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for an array of suffixes specifying case-sensitivity. + * + * @param suffixes the suffixes to allow, must not be null + * @param ioCase how to handle case sensitivity, null means case-sensitive + * @throws NullPointerException if the suffix array is null + * @since 1.4 + */ + public SuffixFileFilter(final String[] suffixes, final IOCase ioCase) { + Objects.requireNonNull(suffixes, "suffixes"); + this.suffixes = suffixes.clone(); + this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); + } + + /** + * Checks to see if the file name ends with the suffix. + * + * @param file the File to check + * @return true if the file name ends with one of our suffixes + */ + @Override + public boolean accept(final File file) { + return accept(file.getName()); + } + + /** + * Checks to see if the file name ends with the suffix. + * + * @param file the File directory + * @param name the file name + * @return true if the file name ends with one of our suffixes + */ + @Override + public boolean accept(final File file, final String name) { + return accept(name); + } + + /** + * Checks to see if the file name ends with the suffix. + * + * @param file the File to check + * @return true if the file name ends with one of our suffixes + * @since 2.9.0 + */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return toFileVisitResult(accept(Objects.toString(file.getFileName(), null))); + } + + private boolean accept(final String name) { + return Stream.of(suffixes).anyMatch(suffix -> ioCase.checkEndsWith(name, suffix)); + } + + /** + * Provide a String representation of this file filter. + * + * @return a String representation + */ + @Override + public String toString() { + final StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + append(suffixes, buffer); + buffer.append(")"); + return buffer.toString(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java new file mode 100644 index 000000000..46c33a8c1 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * This filter accepts {@link File}s that are symbolic links. + * + *

For example, here is how to print out a list of the real files within the current directory: + * + *

Using Classic IO

+ * + *
+ * File dir = FileUtils.current();
+ * String[] files = dir.list(SymbolicLinkFileFilter.INSTANCE);
+ * for (String file : files) {
+ *     System.out.println(file);
+ * }
+ * 
+ * + *

Using NIO

+ * + *
+ * final Path dir = PathUtils.current();
+ * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(SymbolicLinkFileFilter.INSTANCE);
+ * //
+ * // Walk one dir
+ * Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getFileList());
+ * //
+ * visitor.getPathCounters().reset();
+ * //
+ * // Walk dir tree
+ * Files.walkFileTree(dir, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getDirList());
+ * System.out.println(visitor.getFileList());
+ * 
+ * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 2.11.0 + * @see FileFilterUtils#fileFileFilter() + */ +public class SymbolicLinkFileFilter extends AbstractFileFilter implements Serializable { + /* + * Note to developers: The unit test needs to create symbolic links to files. However, on + * Windows, this can't be done without admin privileges. This class is designed to allow a + * unit test to works around this by doing two things: 1) This separates the class logic from + * the call to identify a symbolic link, and 2) It allows the unit test to override that + * symbolic link call on Windows only. + * This means we can write unit tests that will run on all machines. On Windows, the unit test + * can't create a symbolic link without admin privileges, so the unit tests won't + * completely test all the necessary behavior on Windows, but they will still test the class + * logic. Be careful not to break this, but be aware of it when writing unit tests. You can + * still maintain this class and its unit tests on Windows. The one method that won't get + * tested on Windows is not likely to change, and will be tested properly when it gets run + * on Apache servers. + */ + + /** Singleton instance of file filter. */ + public static final SymbolicLinkFileFilter INSTANCE = new SymbolicLinkFileFilter(); + + private static final long serialVersionUID = 1L; + + /** Restrictive constructor. */ + protected SymbolicLinkFileFilter() {} + + /** + * Constructs a new instance. + * + * @param onAccept What to do on acceptance. + * @param onReject What to do on rejection. + * @since 2.12.0. + */ + public SymbolicLinkFileFilter(final FileVisitResult onAccept, final FileVisitResult onReject) { + super(onAccept, onReject); + } + + /** + * Checks to see if the file is a symbolic link. + * + * @param file the File to check + * @return true if the file exists and is a symbolic link to either another file or a directory, + * false otherwise. + */ + @Override + public boolean accept(final File file) { + return isSymbolicLink(file.toPath()); + } + + /** + * Checks to see if the file is a symbolic link. + * + * @param path the File Path to check + * @return {@code onAccept} from {@link #SymbolicLinkFileFilter(FileVisitResult, FileVisitResult)} + * if the file exists and is a symbolic link to either another file or a directory; returns + * {@code onReject} otherwise. + */ + @Override + public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) { + return toFileVisitResult(isSymbolicLink(path)); + } + + /** + * Delegates to {@link Files#isSymbolicLink(Path)} for testing. + * + *

Using package access for unit tests. To facilitate unit testing, all calls to test if the + * file is a symbolic should go through this method. (See the unit test for why.) + * + * @param filePath The filePath to test + * @return true if the file exists and is a symbolic link to either a file or directory, false + * otherwise. + */ + boolean isSymbolicLink(final Path filePath) { + return Files.isSymbolicLink(filePath); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java new file mode 100644 index 000000000..54a8752b6 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * A file filter that always returns true. + * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 1.0 + * @see FileFilterUtils#trueFileFilter() + */ +public class TrueFileFilter implements IOFileFilter, Serializable { + + private static final String TO_STRING = Boolean.TRUE.toString(); + + private static final long serialVersionUID = 8782512160909720199L; + + /** + * Singleton instance of true filter. + * + * @since 1.3 + */ + public static final IOFileFilter TRUE = new TrueFileFilter(); + + /** + * Singleton instance of true filter. Please use the identical TrueFileFilter.TRUE constant. The + * new name is more JDK 1.5 friendly as it doesn't clash with other values when using static + * imports. + */ + public static final IOFileFilter INSTANCE = TRUE; + + /** Restrictive constructor. */ + protected TrueFileFilter() {} + + /** + * Returns true. + * + * @param file the file to check (ignored) + * @return true + */ + @Override + public boolean accept(final File file) { + return true; + } + + /** + * Returns true. + * + * @param dir the directory to check (ignored) + * @param name the file name (ignored) + * @return true + */ + @Override + public boolean accept(final File dir, final String name) { + return true; + } + + /** + * Returns true. + * + * @param file the file to check (ignored) + * @return true + * @since 2.9.0 + */ + @Override + public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { + return FileVisitResult.CONTINUE; + } + + @Override + public IOFileFilter and(final IOFileFilter fileFilter) { + // TRUE AND expression <=> expression + return fileFilter; + } + + @Override + public IOFileFilter negate() { + return FalseFileFilter.INSTANCE; + } + + @Override + public IOFileFilter or(final IOFileFilter fileFilter) { + // TRUE OR expression <=> true + return INSTANCE; + } + + @Override + public String toString() { + return TO_STRING; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java b/java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java new file mode 100644 index 000000000..78f8fa2f9 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +/** Defines package-private constants. */ +final class Constants { + + /** No-op singleton. */ + @SuppressWarnings("rawtypes") + static final IOBiConsumer IO_BI_CONSUMER = + (t, u) -> { + /* No-op */ + }; + + /** No-op singleton. */ + static final IORunnable IO_RUNNABLE = + () -> { + /* No-op */ + }; + + /** No-op singleton. */ + @SuppressWarnings("rawtypes") + static final IOBiFunction IO_BI_FUNCTION = (t, u) -> null; + + /** No-op singleton. */ + @SuppressWarnings("rawtypes") + static final IOFunction IO_FUNCTION_ID = t -> t; + + /** Always false. */ + static final IOPredicate IO_PREDICATE_FALSE = t -> false; + + /** Always true. */ + static final IOPredicate IO_PREDICATE_TRUE = t -> true; + + /** No-op singleton. */ + @SuppressWarnings("rawtypes") + static final IOTriConsumer IO_TRI_CONSUMER = + (t, u, v) -> { + /* No-op */ + }; + + private Constants() { + // We don't want instances + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java b/java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java new file mode 100644 index 000000000..d19433edb --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.function; + +import java.io.IOException; + +/** + * Erases {@link IOException} for the compiler but still throws that exception at runtime. + * + * @since 2.16.0 + */ +public final class Erase { + + /** + * Delegates to the given {@link IOBiConsumer} but erases its {@link IOException} for the + * compiler, while still throwing the exception at runtime. + * + * @param See delegate. + * @param See delegate. + * @param consumer See delegate. + * @param t See delegate. + * @param u See delegate. + * @see IOBiConsumer + */ + static void accept(final IOBiConsumer consumer, final T t, final U u) { + try { + consumer.accept(t, u); + } catch (final IOException ex) { + rethrow(ex); // throws IOException + } + } + + /** + * Delegates to the given {@link IOConsumer} but erases its {@link IOException} for the compiler, + * while still throwing the exception at runtime. + * + * @param See delegate. + * @param consumer See delegate. + * @param t See delegate. + * @see IOConsumer + */ + static void accept(final IOConsumer consumer, final T t) { + try { + consumer.accept(t); + } catch (final IOException ex) { + rethrow(ex); // throws IOException + } + } + + /** + * Delegates to the given {@link IOBiFunction} but erases its {@link IOException} for the + * compiler, while still throwing the exception at runtime. + * + * @param See delegate. + * @param See delegate. + * @param See delegate. + * @param mapper See delegate. + * @param t See delegate. + * @param u See delegate. + * @return See delegate. + * @see IOBiFunction + */ + static R apply( + final IOBiFunction mapper, final T t, final U u) { + try { + return mapper.apply(t, u); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOFunction} but erases its {@link IOException} for the compiler, + * while still throwing the exception at runtime. + * + * @param See delegate. + * @param See delegate. + * @param mapper See delegate. + * @param t See delegate. + * @return See delegate. + * @see IOFunction + */ + static R apply(final IOFunction mapper, final T t) { + try { + return mapper.apply(t); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOComparator} but erases its {@link IOException} for the + * compiler, while still throwing the exception at runtime. + * + * @param See delegate. + * @param comparator See delegate. + * @param t See delegate. + * @param u See delegate. + * @return See delegate. + * @see IOComparator + */ + static int compare(final IOComparator comparator, final T t, final T u) { + try { + return comparator.compare(t, u); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOSupplier} but erases its {@link IOException} for the compiler, + * while still throwing the exception at runtime. + * + * @param See delegate. + * @param supplier See delegate. + * @return See delegate. + * @see IOSupplier + */ + static T get(final IOSupplier supplier) { + try { + return supplier.get(); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Throws the given throwable. + * + * @param The throwable cast type. + * @param throwable The throwable to rethrow. + * @return nothing because we throw. + * @throws T Always thrown. + */ + @SuppressWarnings("unchecked") + public static RuntimeException rethrow(final Throwable throwable) throws T { + throw (T) throwable; + } + + /** + * Delegates to the given {@link IORunnable} but erases its {@link IOException} for the compiler, + * while still throwing the exception at runtime. + * + * @param runnable See delegate. + * @see IORunnable + */ + static void run(final IORunnable runnable) { + try { + runnable.run(); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOPredicate} but erases its {@link IOException} for the compiler, + * while still throwing the exception at runtime. + * + * @param See delegate. + * @param predicate See delegate. + * @param t See delegate. + * @return See delegate. + * @see IOPredicate + */ + static boolean test(final IOPredicate predicate, final T t) { + try { + return predicate.test(t); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** No instances. */ + private Erase() { + // No instances. + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java new file mode 100644 index 000000000..6732b6d83 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.Closeable; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.stream.BaseStream; +import java.util.stream.Stream; + +/** + * Like {@link BaseStream} but throws {@link IOException}. + * + * @param the type of the stream elements. + * @param the type of the IO stream extending {@code IOBaseStream}. + * @param the type of the stream extending {@code BaseStream}. + * @since 2.12.0 + */ +public interface IOBaseStream, B extends BaseStream> + extends Closeable { + + /** + * Constructs a {@link BaseStream} for this instance that throws {@link UncheckedIOException} + * instead of {@link IOException}. + * + * @return an {@link UncheckedIOException} {@link BaseStream}. + */ + @SuppressWarnings("unchecked") + default BaseStream asBaseStream() { + return new UncheckedIOBaseStream<>((S) this); + } + + /** + * Like {@link BaseStream#close()}. + * + * @see BaseStream#close() + */ + @Override + default void close() { + unwrap().close(); + } + + /** + * Like {@link BaseStream#isParallel()}. + * + * @return See {@link BaseStream#isParallel() delegate}. + * @see BaseStream#isParallel() + */ + @SuppressWarnings("resource") // for unwrap() + default boolean isParallel() { + return unwrap().isParallel(); + } + + /** + * Like {@link BaseStream#iterator()}. + * + * @return See {@link BaseStream#iterator() delegate}. + * @see BaseStream#iterator() + */ + @SuppressWarnings("resource") // for unwrap() + default IOIterator iterator() { + return IOIteratorAdapter.adapt(unwrap().iterator()); + } + + /** + * Like {@link BaseStream#onClose(Runnable)}. + * + * @param closeHandler See {@link BaseStream#onClose(Runnable) delegate}. + * @return See {@link BaseStream#onClose(Runnable) delegate}. + * @throws IOException if an I/O error occurs. + * @see BaseStream#onClose(Runnable) + */ + @SuppressWarnings({"unused", "resource"}) // throws IOException, unwrap() + default S onClose(final IORunnable closeHandler) throws IOException { + return wrap(unwrap().onClose(() -> Erase.run(closeHandler))); + } + + /** + * Like {@link BaseStream#parallel()}. + * + * @return See {@link BaseStream#parallel() delegate}. + * @see BaseStream#parallel() + */ + @SuppressWarnings({"resource", "unchecked"}) // for unwrap(), this + default S parallel() { + return isParallel() ? (S) this : wrap(unwrap().parallel()); + } + + /** + * Like {@link BaseStream#sequential()}. + * + * @return See {@link BaseStream#sequential() delegate}. + * @see BaseStream#sequential() + */ + @SuppressWarnings({"resource", "unchecked"}) // for unwrap(), this + default S sequential() { + return isParallel() ? wrap(unwrap().sequential()) : (S) this; + } + + /** + * Like {@link BaseStream#spliterator()}. + * + * @return See {@link BaseStream#spliterator() delegate}. + * @see BaseStream#spliterator() + */ + @SuppressWarnings("resource") // for unwrap() + default IOSpliterator spliterator() { + return IOSpliteratorAdapter.adapt(unwrap().spliterator()); + } + + /** + * Like {@link BaseStream#unordered()}. + * + * @return See {@link BaseStream#unordered() delegate}. + * @see java.util.stream.BaseStream#unordered() + */ + @SuppressWarnings("resource") // for unwrap() + default S unordered() { + return wrap(unwrap().unordered()); + } + + /** + * Unwraps this instance and returns the underlying {@link Stream}. + * + *

Implementations may not have anything to unwrap and that behavior is undefined for now. + * + * @return the underlying stream. + */ + B unwrap(); + + /** + * Wraps a {@link Stream}. + * + * @param delegate The delegate. + * @return An IO stream. + */ + S wrap(B delegate); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java new file mode 100644 index 000000000..7b5369217 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.util.Objects; +import java.util.stream.BaseStream; + +/** + * Abstracts an {@link IOBaseStream} implementation. + * + *

Keep package-private for now. + * + * @param the type of the stream elements. + * @param the type of the stream extending {@code IOBaseStream}. + */ +abstract class IOBaseStreamAdapter, B extends BaseStream> + implements IOBaseStream { + + /** The underlying base stream. */ + private final B delegate; + + /** + * Constructs an instance. + * + * @param delegate the delegate. + */ + IOBaseStreamAdapter(final B delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate"); + } + + @Override + public B unwrap() { + return delegate; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java new file mode 100644 index 000000000..737bef50d --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.function.BiConsumer; + +/** + * Like {@link BiConsumer} but throws {@link IOException}. + * + * @param the type of the first argument to the operation + * @param the type of the second argument to the operation + * @see BiConsumer + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOBiConsumer { + + /** + * Returns the no-op singleton. + * + * @param the type of the first argument to the operation + * @param the type of the second argument to the operation + * @return The no-op singleton. + */ + @SuppressWarnings("unchecked") + static IOBiConsumer noop() { + return Constants.IO_BI_CONSUMER; + } + + /** + * Performs this operation on the given arguments. + * + * @param t the first input argument + * @param u the second input argument + * @throws IOException if an I/O error occurs. + */ + void accept(T t, U u) throws IOException; + + /** + * Creates a composed {@link IOBiConsumer} that performs, in sequence, this operation followed by + * the {@code after} operation. If performing either operation throws an exception, it is relayed + * to the caller of the composed operation. If performing this operation throws an exception, the + * {@code after} operation will not be performed. + * + * @param after the operation to perform after this operation + * @return a composed {@link IOBiConsumer} that performs in sequence this operation followed by + * the {@code after} operation + * @throws NullPointerException if {@code after} is null + */ + default IOBiConsumer andThen(final IOBiConsumer after) { + Objects.requireNonNull(after); + return (t, u) -> { + accept(t, u); + after.accept(t, u); + }; + } + + /** + * Creates a {@link BiConsumer} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException BiConsumer. + * @throws UncheckedIOException Wraps an {@link IOException}. + * @since 2.12.0 + */ + default BiConsumer asBiConsumer() { + return (t, u) -> Uncheck.accept(this, t, u); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java new file mode 100644 index 000000000..a4e2da838 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Like {@link BiFunction} but throws {@link IOException}. + * + *

This is a functional interface whose functional method is + * {@link #apply(Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function + * @param the type of the result of the function + * @see Function + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOBiFunction { + + /** + * Creates a composed function that first applies this function to its input, and then applies the + * {@code after} function to the result. If evaluation of either function throws an exception, it + * is relayed to the caller of the composed function. + * + * @param the type of output of the {@code after} function, and of the composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * function + * @throws NullPointerException if after is null + */ + default IOBiFunction andThen(final IOFunction after) { + Objects.requireNonNull(after); + return (final T t, final U u) -> after.apply(apply(t, u)); + } + + /** + * Applies this function to the given arguments. + * + * @param t the first function argument + * @param u the second function argument + * @return the function result + * @throws IOException if an I/O error occurs. + */ + R apply(T t, U u) throws IOException; + + /** + * Creates a {@link BiFunction} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException BiFunction. + */ + default BiFunction asBiFunction() { + return (t, u) -> Uncheck.apply(this, t, u); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java new file mode 100644 index 000000000..fb8a57fef --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.function.BinaryOperator; + +/** + * Like {@link BinaryOperator} but throws {@link IOException}. + * + * @param the type of the operands and result of the operator. + * @see IOBiFunction + * @see BinaryOperator + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOBinaryOperator extends IOBiFunction { + + /** + * Creates a {@link IOBinaryOperator} which returns the greater of two elements according to the + * specified {@code Comparator}. + * + * @param the type of the input arguments of the comparator + * @param comparator a {@code Comparator} for comparing the two values + * @return a {@code BinaryOperator} which returns the greater of its operands, according to the + * supplied {@code Comparator} + * @throws NullPointerException if the argument is null + */ + static IOBinaryOperator maxBy(final IOComparator comparator) { + Objects.requireNonNull(comparator); + return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; + } + + /** + * Creates a {@link IOBinaryOperator} which returns the lesser of two elements according to the + * specified {@code Comparator}. + * + * @param the type of the input arguments of the comparator + * @param comparator a {@code Comparator} for comparing the two values + * @return a {@code BinaryOperator} which returns the lesser of its operands, according to the + * supplied {@code Comparator} + * @throws NullPointerException if the argument is null + */ + static IOBinaryOperator minBy(final IOComparator comparator) { + Objects.requireNonNull(comparator); + return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; + } + + /** + * Creates a {@link BinaryOperator} for this instance that throws {@link UncheckedIOException} + * instead of {@link IOException}. + * + * @return an unchecked BiFunction. + */ + default BinaryOperator asBinaryOperator() { + return (t, u) -> Uncheck.apply(this, t, u); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java new file mode 100644 index 000000000..de14d1d4d --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Comparator; + +/** + * Like {@link Comparator} but throws {@link IOException}. + * + * @param the type of objects that may be compared by this comparator + * @see Comparator + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOComparator { + + /** + * Creates a {@link Comparator} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException BiFunction. + */ + default Comparator asComparator() { + return (t, u) -> Uncheck.compare(this, t, u); + } + + /** + * Like {@link Comparator#compare(Object, Object)} but throws {@link IOException}. + * + * @param o1 the first object to be compared. + * @param o2 the second object to be compared. + * @return a negative integer, zero, or a positive integer as the first argument is less than, + * equal to, or greater than the second. + * @throws NullPointerException if an argument is null and this comparator does not permit null + * arguments + * @throws ClassCastException if the arguments' types prevent them from being compared by this + * comparator. + * @throws IOException if an I/O error occurs. + */ + int compare(T o1, T o2) throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java new file mode 100644 index 000000000..5e1537082 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import org.apache.commons.io.IOExceptionList; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.stream.Stream; + +/** + * Like {@link Consumer} but throws {@link IOException}. + * + * @param the type of the input to the operations. + * @since 2.7 + */ +@FunctionalInterface +public interface IOConsumer { + + /** Consider private. */ + IOConsumer NOOP_IO_CONSUMER = + t -> { + /* noop */ + }; + + /** + * Performs an action for each element of the array, gathering any exceptions. + * + * @param action The action to apply to each input element. + * @param array The input to stream. + * @param The element type. + * @throws IOExceptionList if any I/O errors occur. + * @since 2.12.0 + */ + static void forAll(final IOConsumer action, final T... array) throws IOExceptionList { + IOStreams.forAll(IOStreams.of(array), action); + } + + /** + * Performs an action for each element of the collection, stopping at the first exception. + * + * @param The element type. + * @param iterable The input to stream. + * @param action The action to apply to each input element. + * @throws IOException if an I/O error occurs. + * @since 2.12.0 + */ + static void forEach(final Iterable iterable, final IOConsumer action) + throws IOException { + IOStreams.forEach(IOStreams.of(iterable), action); + } + + /** + * Performs an action for each element of the stream, stopping at the first exception. + * + * @param The element type. + * @param stream The input to stream. + * @param action The action to apply to each input element. + * @throws IOException if an I/O error occurs. + * @since 2.12.0 + */ + static void forEach(final Stream stream, final IOConsumer action) throws IOException { + IOStreams.forEach(stream, action); + } + + /** + * Performs an action for each element of this array, stopping at the first exception. + * + * @param The element type. + * @param array The input to stream. + * @param action The action to apply to each input element. + * @throws IOException if an I/O error occurs. + * @since 2.12.0 + */ + static void forEach(final T[] array, final IOConsumer action) throws IOException { + IOStreams.forEach(IOStreams.of(array), action); + } + + /** + * Returns the constant no-op consumer. + * + * @param Type consumer type. + * @return a constant no-op consumer. + * @since 2.9.0 + */ + @SuppressWarnings("unchecked") + static IOConsumer noop() { + return (IOConsumer) NOOP_IO_CONSUMER; + } + + /** + * Performs this operation on the given argument. + * + * @param t the input argument + * @throws IOException if an I/O error occurs. + */ + void accept(T t) throws IOException; + + /** + * Returns a composed {@link IOConsumer} that performs, in sequence, this operation followed by + * the {@code after} operation. If performing either operation throws an exception, it is relayed + * to the caller of the composed operation. If performing this operation throws an exception, the + * {@code after} operation will not be performed. + * + * @param after the operation to perform after this operation + * @return a composed {@link Consumer} that performs in sequence this operation followed by the + * {@code after} operation + * @throws NullPointerException if {@code after} is null + */ + default IOConsumer andThen(final IOConsumer after) { + Objects.requireNonNull(after, "after"); + return (final T t) -> { + accept(t); + after.accept(t); + }; + } + + /** + * Creates a {@link Consumer} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException Consumer. + * @since 2.12.0 + */ + default Consumer asConsumer() { + return t -> Uncheck.accept(this, t); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java new file mode 100644 index 000000000..d821ae4c6 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Like {@link Function} but throws {@link IOException}. + * + * @param the type of the input to the operations. + * @param the return type of the operations. + * @since 2.7 + */ +@FunctionalInterface +public interface IOFunction { + + /** + * Returns a {@link IOFunction} that always returns its input argument. + * + * @param the type of the input and output objects to the function + * @return a function that always returns its input argument + */ + @SuppressWarnings("unchecked") + static IOFunction identity() { + return Constants.IO_FUNCTION_ID; + } + + /** + * Returns a composed {@link IOFunction} that first applies this function to its input, and then + * applies the {@code after} consumer to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param after the consumer to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * consumer + * @throws NullPointerException if after is null + * @see #compose(IOFunction) + */ + default IOConsumer andThen(final Consumer after) { + Objects.requireNonNull(after, "after"); + return (final T t) -> after.accept(apply(t)); + } + + /** + * Returns a composed {@link IOFunction} that first applies this function to its input, and then + * applies the {@code after} function to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param the type of output of the {@code after} function, and of the composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * function + * @throws NullPointerException if after is null + * @see #compose(IOFunction) + */ + default IOFunction andThen(final Function after) { + Objects.requireNonNull(after, "after"); + return (final T t) -> after.apply(apply(t)); + } + + /** + * Returns a composed {@link IOFunction} that first applies this function to its input, and then + * applies the {@code after} consumer to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param after the consumer to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * consumer + * @throws NullPointerException if after is null + * @see #compose(IOFunction) + */ + default IOConsumer andThen(final IOConsumer after) { + Objects.requireNonNull(after, "after"); + return (final T t) -> after.accept(apply(t)); + } + + /** + * Returns a composed {@link IOFunction} that first applies this function to its input, and then + * applies the {@code after} function to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param the type of output of the {@code after} function, and of the composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * function + * @throws NullPointerException if after is null + * @see #compose(IOFunction) + */ + default IOFunction andThen(final IOFunction after) { + Objects.requireNonNull(after, "after"); + return (final T t) -> after.apply(apply(t)); + } + + /** + * Applies this function to the given argument. + * + * @param t the function argument + * @return the function result + * @throws IOException if an I/O error occurs. + */ + R apply(final T t) throws IOException; + + /** + * Creates a {@link Function} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException Function. + * @since 2.12.0 + */ + default Function asFunction() { + return t -> Uncheck.apply(this, t); + } + + /** + * Returns a composed {@link IOFunction} that first applies the {@code before} function to its + * input, and then applies this function to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param the type of input to the {@code before} function, and to the composed function + * @param before the function to apply before this function is applied + * @return a composed function that first applies the {@code before} function and then applies + * this function + * @throws NullPointerException if before is null + * @see #andThen(IOFunction) + */ + default IOFunction compose(final Function before) { + Objects.requireNonNull(before, "before"); + return (final V v) -> apply(before.apply(v)); + } + + /** + * Returns a composed {@link IOFunction} that first applies the {@code before} function to its + * input, and then applies this function to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param the type of input to the {@code before} function, and to the composed function + * @param before the function to apply before this function is applied + * @return a composed function that first applies the {@code before} function and then applies + * this function + * @throws NullPointerException if before is null + * @see #andThen(IOFunction) + */ + default IOFunction compose(final IOFunction before) { + Objects.requireNonNull(before, "before"); + return (final V v) -> apply(before.apply(v)); + } + + /** + * Returns a composed {@link IOFunction} that first applies the {@code before} function to its + * input, and then applies this function to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param before the supplier which feeds the application of this function + * @return a composed function that first applies the {@code before} function and then applies + * this function + * @throws NullPointerException if before is null + * @see #andThen(IOFunction) + */ + default IOSupplier compose(final IOSupplier before) { + Objects.requireNonNull(before, "before"); + return () -> apply(before.get()); + } + + /** + * Returns a composed {@link IOFunction} that first applies the {@code before} function to its + * input, and then applies this function to the result. If evaluation of either function throws an + * exception, it is relayed to the caller of the composed function. + * + * @param before the supplier which feeds the application of this function + * @return a composed function that first applies the {@code before} function and then applies + * this function + * @throws NullPointerException if before is null + * @see #andThen(IOFunction) + */ + default IOSupplier compose(final Supplier before) { + Objects.requireNonNull(before, "before"); + return () -> apply(before.get()); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java new file mode 100644 index 000000000..ee028feb1 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.function.IntSupplier; +import java.util.function.Supplier; + +/** + * Like {@link IntSupplier} but throws {@link IOException}. + * + * @since 2.14.0 + */ +@FunctionalInterface +public interface IOIntSupplier { + + /** + * Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException Supplier. + */ + default IntSupplier asIntSupplier() { + return () -> Uncheck.getAsInt(this); + } + + /** + * Gets a result. + * + * @return a result + * @throws IOException if an I/O error occurs. + */ + int getAsInt() throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java new file mode 100644 index 000000000..0f14a66fa --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * Like {@link Iterator} but throws {@link IOException}. + * + * @param the type of elements returned by this iterator. + * @since 2.12.0 + */ +public interface IOIterator { + + /** + * Adapts the given Iterable as an IOIterator. + * + * @param the type of the stream elements. + * @param iterable The iterable to adapt + * @return A new IOIterator + * @since 2.17.0 + */ + static IOIterator adapt(final Iterable iterable) { + return IOIteratorAdapter.adapt(iterable.iterator()); + } + + /** + * Adapts the given Iterator as an IOIterator. + * + * @param the type of the stream elements. + * @param iterator The iterator to adapt + * @return A new IOIterator + */ + static IOIterator adapt(final Iterator iterator) { + return IOIteratorAdapter.adapt(iterator); + } + + /** + * Creates an {@link Iterator} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an {@link UncheckedIOException} {@link Iterator}. + */ + default Iterator asIterator() { + return new UncheckedIOIterator<>(this); + } + + /** + * Like {@link Iterator#forEachRemaining(Consumer)}. + * + * @param action See delegate. + * @throws IOException if an I/O error occurs. + */ + default void forEachRemaining(final IOConsumer action) throws IOException { + Objects.requireNonNull(action); + while (hasNext()) { + action.accept(next()); + } + } + + /** + * Like {@link Iterator#hasNext()}. + * + * @return See delegate. + * @throws IOException if an I/O error occurs. + */ + boolean hasNext() throws IOException; + + /** + * Like {@link Iterator#next()}. + * + * @return See delegate. + * @throws IOException if an I/O error occurs. + * @throws NoSuchElementException if the iteration has no more elements + */ + E next() throws IOException; + + /** + * Like {@link Iterator#remove()}. + * + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") + default void remove() throws IOException { + unwrap().remove(); + } + + /** + * Unwraps this instance and returns the underlying {@link Iterator}. + * + *

Implementations may not have anything to unwrap and that behavior is undefined for now. + * + * @return the underlying Iterator. + */ + Iterator unwrap(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java new file mode 100644 index 000000000..2cad5ca68 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Objects; + +/** + * Adapts an {@link Iterator} as an {@link IOIterator}. + * + * @param the type of the stream elements. + */ +final class IOIteratorAdapter implements IOIterator { + + static IOIteratorAdapter adapt(final Iterator delegate) { + return new IOIteratorAdapter<>(delegate); + } + + private final Iterator delegate; + + IOIteratorAdapter(final Iterator delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate"); + } + + @Override + public boolean hasNext() throws IOException { + return delegate.hasNext(); + } + + @Override + public E next() throws IOException { + return delegate.next(); + } + + @Override + public Iterator unwrap() { + return delegate; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java new file mode 100644 index 000000000..cfef2a440 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.util.function.LongSupplier; + +/** + * Like {@link LongSupplier} but throws {@link IOException}. + * + * @since 2.14.0 + */ +@FunctionalInterface +public interface IOLongSupplier { + /** + * Gets a result. + * + * @return a result + * @throws IOException if an I/O error occurs. + */ + long getAsLong() throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java new file mode 100644 index 000000000..4bab3def4 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * Like {@link Predicate} but throws {@link IOException}. + * + * @param the type of the input to the predicate + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOPredicate { + + /** + * Always false. + * + * @param the type of the input to the predicate + * @return a constant predicate that tests always false. + */ + @SuppressWarnings("unchecked") + static IOPredicate alwaysFalse() { + return (IOPredicate) Constants.IO_PREDICATE_FALSE; + } + + /** + * Always true. + * + * @param the type of the input to the predicate + * @return a constant predicate that tests always true. + */ + @SuppressWarnings("unchecked") + static IOPredicate alwaysTrue() { + return (IOPredicate) Constants.IO_PREDICATE_TRUE; + } + + /** + * Creates a predicate that tests if two arguments are equal using {@link Objects#equals(Object, + * Object)}. + * + * @param the type of arguments to the predicate + * @param target the object to compare for equality, may be {@code null} + * @return a predicate that tests if two arguments are equal using {@link Objects#equals(Object, + * Object)} + */ + static IOPredicate isEqual(final Object target) { + return null == target ? Objects::isNull : object -> target.equals(object); + } + + /** + * Creates a composed predicate that represents a short-circuiting logical AND of this predicate + * and another. When evaluating the composed predicate, if this predicate is {@code false}, then + * the {@code other} predicate is not evaluated. + * + *

Any exceptions thrown during evaluation of either predicate are relayed to the caller; if + * evaluation of this predicate throws an exception, the {@code other} predicate will not be + * evaluated. + * + * @param other a predicate that will be logically-ANDed with this predicate + * @return a composed predicate that represents the short-circuiting logical AND of this predicate + * and the {@code other} predicate + * @throws NullPointerException if other is null + */ + default IOPredicate and(final IOPredicate other) { + Objects.requireNonNull(other); + return t -> test(t) && other.test(t); + } + + /** + * Creates a {@link Predicate} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException Predicate. + */ + default Predicate asPredicate() { + return t -> Uncheck.test(this, t); + } + + /** + * Creates a predicate that represents the logical negation of this predicate. + * + * @return a predicate that represents the logical negation of this predicate + */ + default IOPredicate negate() { + return t -> !test(t); + } + + /** + * Creates a composed predicate that represents a short-circuiting logical OR of this predicate + * and another. When evaluating the composed predicate, if this predicate is {@code true}, then + * the {@code other} predicate is not evaluated. + * + *

Any exceptions thrown during evaluation of either predicate are relayed to the caller; if + * evaluation of this predicate throws an exception, the {@code other} predicate will not be + * evaluated. + * + * @param other a predicate that will be logically-ORed with this predicate + * @return a composed predicate that represents the short-circuiting logical OR of this predicate + * and the {@code other} predicate + * @throws NullPointerException if other is null + */ + default IOPredicate or(final IOPredicate other) { + Objects.requireNonNull(other); + return t -> test(t) || other.test(t); + } + + /** + * Evaluates this predicate on the given argument. + * + * @param t the input argument + * @return {@code true} if the input argument matches the predicate, otherwise {@code false} + * @throws IOException if an I/O error occurs. + */ + boolean test(T t) throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java new file mode 100644 index 000000000..a09d438e3 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.function; + +import java.io.IOException; +import java.util.function.Function; + +/** + * Represents a function that accepts four arguments and produces a result. This is the four-arity + * specialization of {@link IOFunction}. + * + *

This is a functional interface whose functional method is + * {@link #apply(Object, Object, Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function + * @param the type of the third argument to the function + * @param the type of the fourth argument to the function + * @param the type of the result of the function + * @see Function + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOQuadFunction { + + /** + * Applies this function to the given arguments. + * + * @param t the first function argument + * @param u the second function argument + * @param v the third function argument + * @param w the fourth function argument + * @return the function result + * @throws IOException if an I/O error occurs. + */ + R apply(T t, U u, V v, W w) throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java new file mode 100644 index 000000000..f991e1463 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; + +/** + * Like {@link Runnable} but throws {@link IOException}. + * + * @since 2.12.0 + */ +@FunctionalInterface +public interface IORunnable { + + /** + * Like {@link Runnable#run()} but throws {@link IOException}. + * + * @throws IOException if an I/O error occurs. + */ + void run() throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java new file mode 100644 index 000000000..c066fdf5c --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; +import java.util.Spliterator; +import java.util.function.Consumer; + +/** + * Like {@link Spliterator} but throws {@link IOException}. + * + * @param the type of elements returned by this IOSpliterator. + * @since 2.12.0 + */ +public interface IOSpliterator { + + /** + * Adapts the given Spliterator as an IOSpliterator. + * + * @param the type of the stream elements. + * @param iterator The iterator to adapt + * @return A new IOSpliterator + */ + static IOSpliterator adapt(final Spliterator iterator) { + return IOSpliteratorAdapter.adapt(iterator); + } + + /** + * Constructs a {@link Spliterator} for this instance that throws {@link UncheckedIOException} + * instead of {@link IOException}. + * + * @return an {@link UncheckedIOException} {@link Spliterator}. + */ + default Spliterator asSpliterator() { + return new UncheckedIOSpliterator<>(this); + } + + /** + * Like {@link Spliterator#characteristics()}. + * + * @return a representation of characteristics + */ + default int characteristics() { + return unwrap().characteristics(); + } + + /** + * Like {@link Spliterator#estimateSize()}. + * + * @return the estimated size, or {@code Long.MAX_VALUE} if infinite, unknown, or too expensive to + * compute. + */ + default long estimateSize() { + return unwrap().estimateSize(); + } + + /** + * Like {@link Spliterator#forEachRemaining(Consumer)}. + * + * @param action The action + * @throws NullPointerException if the specified action is null + */ + default void forEachRemaining(final IOConsumer action) { + while (tryAdvance(action)) { // NOPMD + } + } + + /** + * Like {@link Spliterator#getComparator()}. + * + * @return a Comparator, or {@code null} if the elements are sorted in the natural order. + * @throws IllegalStateException if the spliterator does not report a characteristic of {@code + * SORTED}. + */ + @SuppressWarnings("unchecked") + default IOComparator getComparator() { + return (IOComparator) unwrap().getComparator(); + } + + /** + * Like {@link Spliterator#getExactSizeIfKnown()}. + * + * @return the exact size, if known, else {@code -1}. + */ + default long getExactSizeIfKnown() { + return unwrap().getExactSizeIfKnown(); + } + + /** + * Like {@link Spliterator#hasCharacteristics(int)}. + * + * @param characteristics the characteristics to check for + * @return {@code true} if all the specified characteristics are present, else {@code false} + */ + default boolean hasCharacteristics(final int characteristics) { + return unwrap().hasCharacteristics(characteristics); + } + + /** + * Like {@link Spliterator#tryAdvance(Consumer)}. + * + * @param action The action + * @return {@code false} if no remaining elements existed upon entry to this method, else {@code + * true}. + * @throws NullPointerException if the specified action is null + */ + default boolean tryAdvance(final IOConsumer action) { + return unwrap().tryAdvance(Objects.requireNonNull(action, "action").asConsumer()); + } + + /** + * Like {@link Spliterator#trySplit()}. + * + * @return a {@code Spliterator} covering some portion of the elements, or {@code null} if this + * spliterator cannot be split + */ + default IOSpliterator trySplit() { + return adapt(unwrap().trySplit()); + } + + /** + * Unwraps this instance and returns the underlying {@link Spliterator}. + * + *

Implementations may not have anything to unwrap and that behavior is undefined for now. + * + * @return the underlying Spliterator. + */ + Spliterator unwrap(); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java new file mode 100644 index 000000000..9874206d9 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.util.Objects; +import java.util.Spliterator; + +/** + * Adapts an {@link Spliterator} as an {@link IOSpliterator}. + * + * @param the type of the stream elements. + */ +final class IOSpliteratorAdapter implements IOSpliterator { + + static IOSpliteratorAdapter adapt(final Spliterator delegate) { + return new IOSpliteratorAdapter<>(delegate); + } + + private final Spliterator delegate; + + IOSpliteratorAdapter(final Spliterator delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate"); + } + + @Override + public Spliterator unwrap() { + return delegate; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java new file mode 100644 index 000000000..2318b1d85 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java @@ -0,0 +1,633 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import org.apache.commons.io.IOExceptionList; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; +import java.util.function.IntFunction; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; +import java.util.function.UnaryOperator; +import java.util.stream.Collector; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * Like {@link Stream} but throws {@link IOException}. + * + * @param the type of the stream elements. + * @since 2.12.0 + */ +public interface IOStream extends IOBaseStream, Stream> { + + /** + * Constructs a new IOStream for the given Stream. + * + * @param the type of the stream elements. + * @param stream The stream to delegate. + * @return a new IOStream. + */ + static IOStream adapt(final Stream stream) { + return IOStreamAdapter.adapt(stream); + } + + /** + * This class' version of {@link Stream#empty()}. + * + * @param the type of the stream elements + * @return an empty sequential {@code IOStreamImpl}. + * @see Stream#empty() + */ + static IOStream empty() { + return IOStreamAdapter.adapt(Stream.empty()); + } + + /** + * Like {@link Stream#iterate(Object, UnaryOperator)} but for IO. + * + * @param the type of stream elements. + * @param seed the initial element. + * @param f a function to be applied to the previous element to produce a new element. + * @return a new sequential {@code IOStream}. + */ + static IOStream iterate(final T seed, final IOUnaryOperator f) { + Objects.requireNonNull(f); + final Iterator iterator = + new Iterator() { + @SuppressWarnings("unchecked") + T t = (T) IOStreams.NONE; + + @Override + public boolean hasNext() { + return true; + } + + @Override + public T next() throws NoSuchElementException { + try { + return t = t == IOStreams.NONE ? seed : f.apply(t); + } catch (final IOException e) { + final NoSuchElementException nsee = new NoSuchElementException(); + nsee.initCause(e); + throw nsee; + } + } + }; + return adapt( + StreamSupport.stream( + Spliterators.spliteratorUnknownSize( + iterator, Spliterator.ORDERED | Spliterator.IMMUTABLE), + false)); + } + + /** + * Null-safe version of {@link StreamSupport#stream(java.util.Spliterator, boolean)}. + * + *

Copied from Apache Commons Lang. + * + * @param the type of stream elements. + * @param values the elements of the new stream, may be {@code null}. + * @return the new stream on {@code values} or {@link Stream#empty()}. + */ + static IOStream of(final Iterable values) { + return values == null ? empty() : adapt(StreamSupport.stream(values.spliterator(), false)); + } + + /** + * Null-safe version of {@link Stream#of(Object[])} for an IO stream. + * + * @param the type of stream elements. + * @param values the elements of the new stream, may be {@code null}. + * @return the new stream on {@code values} or {@link Stream#empty()}. + */ + @SafeVarargs // Creating a stream from an array is safe + static IOStream of(final T... values) { + return values == null || values.length == 0 ? empty() : adapt(Arrays.stream(values)); + } + + /** + * Returns a sequential {@code IOStreamImpl} containing a single element. + * + * @param t the single element + * @param the type of stream elements + * @return a singleton sequential stream + */ + static IOStream of(final T t) { + return adapt(Stream.of(t)); + } + + /** + * Like {@link Stream#allMatch(java.util.function.Predicate)} but throws {@link IOException}. + * + * @param predicate {@link Stream#allMatch(java.util.function.Predicate)}. + * @return Like {@link Stream#allMatch(java.util.function.Predicate)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default boolean allMatch(final IOPredicate predicate) throws IOException { + return unwrap().allMatch(t -> Erase.test(predicate, t)); + } + + /** + * Like {@link Stream#anyMatch(java.util.function.Predicate)} but throws {@link IOException}. + * + * @param predicate {@link Stream#anyMatch(java.util.function.Predicate)}. + * @return Like {@link Stream#anyMatch(java.util.function.Predicate)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default boolean anyMatch(final IOPredicate predicate) throws IOException { + return unwrap().anyMatch(t -> Erase.test(predicate, t)); + } + + /** + * TODO Package-private for now, needs IOCollector? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#collect(Collector)}. + * + *

Package private for now. + * + * @param Like {@link Stream#collect(Collector)}. + * @param Like {@link Stream#collect(Collector)}. + * @param collector Like {@link Stream#collect(Collector)}. + * @return Like {@link Stream#collect(Collector)}. + */ + default R collect(final Collector collector) { + return unwrap().collect(collector); + } + + /** + * Like {@link Stream#collect(java.util.function.Supplier, java.util.function.BiConsumer, + * java.util.function.BiConsumer)}. + * + * @param Like {@link Stream#collect(java.util.function.Supplier, + * java.util.function.BiConsumer, java.util.function.BiConsumer)}. + * @param supplier Like {@link Stream#collect(java.util.function.Supplier, + * java.util.function.BiConsumer, java.util.function.BiConsumer)}. + * @param accumulator Like {@link Stream#collect(java.util.function.Supplier, + * java.util.function.BiConsumer, java.util.function.BiConsumer)}. + * @param combiner Like {@link Stream#collect(java.util.function.Supplier, + * java.util.function.BiConsumer, java.util.function.BiConsumer)}. + * @return Like {@link Stream#collect(java.util.function.Supplier, java.util.function.BiConsumer, + * java.util.function.BiConsumer)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default R collect( + final IOSupplier supplier, + final IOBiConsumer accumulator, + final IOBiConsumer combiner) + throws IOException { + return unwrap() + .collect( + () -> Erase.get(supplier), + (t, u) -> Erase.accept(accumulator, t, u), + (t, u) -> Erase.accept(combiner, t, u)); + } + + /** + * Like {@link Stream#count()}. + * + * @return Like {@link Stream#count()}. + */ + default long count() { + return unwrap().count(); + } + + /** + * Like {@link Stream#distinct()}. + * + * @return Like {@link Stream#distinct()}. + */ + default IOStream distinct() { + return adapt(unwrap().distinct()); + } + + /** + * Like {@link Stream#filter(java.util.function.Predicate)}. + * + * @param predicate Like {@link Stream#filter(java.util.function.Predicate)}. + * @return Like {@link Stream#filter(java.util.function.Predicate)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default IOStream filter(final IOPredicate predicate) throws IOException { + return adapt(unwrap().filter(t -> Erase.test(predicate, t))); + } + + /** + * Like {@link Stream#findAny()}. + * + * @return Like {@link Stream#findAny()}. + */ + default Optional findAny() { + return unwrap().findAny(); + } + + /** + * Like {@link Stream#findFirst()}. + * + * @return Like {@link Stream#findFirst()}. + */ + default Optional findFirst() { + return unwrap().findFirst(); + } + + /** + * Like {@link Stream#flatMap(java.util.function.Function)}. + * + * @param Like {@link Stream#flatMap(java.util.function.Function)}. + * @param mapper Like {@link Stream#flatMap(java.util.function.Function)}. + * @return Like {@link Stream#flatMap(java.util.function.Function)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings({"unused", "resource"}) // thrown by Erase; resource closed by caller. + default IOStream flatMap( + final IOFunction> mapper) throws IOException { + return adapt(unwrap().flatMap(t -> Erase.apply(mapper, t).unwrap())); + } + + /** + * TODO Package-private for now, needs IODoubleStream? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#flatMapToDouble(java.util.function.Function)}. + * + * @param mapper Like {@link Stream#flatMapToDouble(java.util.function.Function)}. + * @return Like {@link Stream#flatMapToDouble(java.util.function.Function)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default DoubleStream flatMapToDouble(final IOFunction mapper) + throws IOException { + return unwrap().flatMapToDouble(t -> Erase.apply(mapper, t)); + } + + /** + * TODO Package-private for now, needs IOIntStream? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#flatMapToInt(java.util.function.Function)}. + * + * @param mapper Like {@link Stream#flatMapToInt(java.util.function.Function)}. + * @return Like {@link Stream#flatMapToInt(java.util.function.Function)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default IntStream flatMapToInt(final IOFunction mapper) + throws IOException { + return unwrap().flatMapToInt(t -> Erase.apply(mapper, t)); + } + + /** + * TODO Package-private for now, needs IOLongStream? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#flatMapToLong(java.util.function.Function)}. + * + * @param mapper Like {@link Stream#flatMapToLong(java.util.function.Function)}. + * @return Like {@link Stream#flatMapToLong(java.util.function.Function)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default LongStream flatMapToLong(final IOFunction mapper) + throws IOException { + return unwrap().flatMapToLong(t -> Erase.apply(mapper, t)); + } + + /** + * Performs an action for each element gathering any exceptions. + * + * @param action The action to apply to each element. + * @throws IOExceptionList if any I/O errors occur. + */ + default void forAll(final IOConsumer action) throws IOExceptionList { + forAll(action, (i, e) -> e); + } + + /** + * Performs an action for each element gathering any exceptions. + * + * @param action The action to apply to each element. + * @param exSupplier The exception supplier. + * @throws IOExceptionList if any I/O errors occur. + */ + default void forAll( + final IOConsumer action, final BiFunction exSupplier) + throws IOExceptionList { + final AtomicReference> causeList = new AtomicReference<>(); + final AtomicInteger index = new AtomicInteger(); + final IOConsumer safeAction = IOStreams.toIOConsumer(action); + unwrap() + .forEach( + e -> { + try { + safeAction.accept(e); + } catch (final IOException innerEx) { + if (causeList.get() == null) { + // Only allocate if required + causeList.set(new ArrayList<>()); + } + if (exSupplier != null) { + causeList.get().add(exSupplier.apply(index.get(), innerEx)); + } + } + index.incrementAndGet(); + }); + IOExceptionList.checkEmpty(causeList.get(), null); + } + + /** + * Like {@link Stream#forEach(java.util.function.Consumer)} but throws {@link IOException}. + * + * @param action Like {@link Stream#forEach(java.util.function.Consumer)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default void forEach(final IOConsumer action) throws IOException { + unwrap().forEach(e -> Erase.accept(action, e)); + } + + /** + * Like {@link Stream#forEachOrdered(java.util.function.Consumer)}. + * + * @param action Like {@link Stream#forEachOrdered(java.util.function.Consumer)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default void forEachOrdered(final IOConsumer action) throws IOException { + unwrap().forEachOrdered(e -> Erase.accept(action, e)); + } + + /** + * Like {@link Stream#limit(long)}. + * + * @param maxSize Like {@link Stream#limit(long)}. + * @return Like {@link Stream#limit(long)}. + */ + default IOStream limit(final long maxSize) { + return adapt(unwrap().limit(maxSize)); + } + + /** + * Like {@link Stream#map(java.util.function.Function)}. + * + * @param Like {@link Stream#map(java.util.function.Function)}. + * @param mapper Like {@link Stream#map(java.util.function.Function)}. + * @return Like {@link Stream#map(java.util.function.Function)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default IOStream map(final IOFunction mapper) throws IOException { + return adapt(unwrap().map(t -> Erase.apply(mapper, t))); + } + + /** + * TODO Package-private for now, needs IOToDoubleFunction? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#mapToDouble(ToDoubleFunction)}. + * + *

Package private for now. + * + * @param mapper Like {@link Stream#mapToDouble(ToDoubleFunction)}. + * @return Like {@link Stream#mapToDouble(ToDoubleFunction)}. + */ + default DoubleStream mapToDouble(final ToDoubleFunction mapper) { + return unwrap().mapToDouble(mapper); + } + + /** + * TODO Package-private for now, needs IOToIntFunction? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#mapToInt(ToIntFunction)}. + * + *

Package private for now. + * + * @param mapper Like {@link Stream#mapToInt(ToIntFunction)}. + * @return Like {@link Stream#mapToInt(ToIntFunction)}. + */ + default IntStream mapToInt(final ToIntFunction mapper) { + return unwrap().mapToInt(mapper); + } + + /** + * TODO Package-private for now, needs IOToLongFunction? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#mapToLong(ToLongFunction)}. + * + *

Package private for now. + * + * @param mapper Like {@link Stream#mapToLong(ToLongFunction)}. + * @return Like {@link Stream#mapToLong(ToLongFunction)}. + */ + default LongStream mapToLong(final ToLongFunction mapper) { + return unwrap().mapToLong(mapper); + } + + /** + * Like {@link Stream#max(java.util.Comparator)}. + * + * @param comparator Like {@link Stream#max(java.util.Comparator)}. + * @return Like {@link Stream#max(java.util.Comparator)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default Optional max(final IOComparator comparator) throws IOException { + return unwrap().max((t, u) -> Erase.compare(comparator, t, u)); + } + + /** + * Like {@link Stream#min(java.util.Comparator)}. + * + * @param comparator Like {@link Stream#min(java.util.Comparator)}. + * @return Like {@link Stream#min(java.util.Comparator)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default Optional min(final IOComparator comparator) throws IOException { + return unwrap().min((t, u) -> Erase.compare(comparator, t, u)); + } + + /** + * Like {@link Stream#noneMatch(java.util.function.Predicate)}. + * + * @param predicate Like {@link Stream#noneMatch(java.util.function.Predicate)}. + * @return Like {@link Stream#noneMatch(java.util.function.Predicate)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default boolean noneMatch(final IOPredicate predicate) throws IOException { + return unwrap().noneMatch(t -> Erase.test(predicate, t)); + } + + /** + * Like {@link Stream#peek(java.util.function.Consumer)}. + * + * @param action Like {@link Stream#peek(java.util.function.Consumer)}. + * @return Like {@link Stream#peek(java.util.function.Consumer)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default IOStream peek(final IOConsumer action) throws IOException { + return adapt(unwrap().peek(t -> Erase.accept(action, t))); + } + + /** + * Like {@link Stream#reduce(java.util.function.BinaryOperator)}. + * + * @param accumulator Like {@link Stream#reduce(java.util.function.BinaryOperator)}. + * @return Like {@link Stream#reduce(java.util.function.BinaryOperator)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default Optional reduce(final IOBinaryOperator accumulator) throws IOException { + return unwrap().reduce((t, u) -> Erase.apply(accumulator, t, u)); + } + + /** + * Like {@link Stream#reduce(Object, java.util.function.BinaryOperator)}. + * + * @param identity Like {@link Stream#reduce(Object, java.util.function.BinaryOperator)}. + * @param accumulator Like {@link Stream#reduce(Object, java.util.function.BinaryOperator)}. + * @return Like {@link Stream#reduce(Object, java.util.function.BinaryOperator)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default T reduce(final T identity, final IOBinaryOperator accumulator) throws IOException { + return unwrap().reduce(identity, (t, u) -> Erase.apply(accumulator, t, u)); + } + + /** + * Like {@link Stream#reduce(Object, BiFunction, java.util.function.BinaryOperator)}. + * + * @param Like {@link Stream#reduce(Object, BiFunction, java.util.function.BinaryOperator)}. + * @param identity Like {@link Stream#reduce(Object, BiFunction, + * java.util.function.BinaryOperator)}. + * @param accumulator Like {@link Stream#reduce(Object, BiFunction, + * java.util.function.BinaryOperator)}. + * @param combiner Like {@link Stream#reduce(Object, BiFunction, + * java.util.function.BinaryOperator)}. + * @return Like {@link Stream#reduce(Object, BiFunction, java.util.function.BinaryOperator)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default U reduce( + final U identity, + final IOBiFunction accumulator, + final IOBinaryOperator combiner) + throws IOException { + return unwrap() + .reduce( + identity, + (t, u) -> Erase.apply(accumulator, t, u), + (t, u) -> Erase.apply(combiner, t, u)); + } + + /** + * Like {@link Stream#skip(long)}. + * + * @param n Like {@link Stream#skip(long)}. + * @return Like {@link Stream#skip(long)}. + */ + default IOStream skip(final long n) { + return adapt(unwrap().skip(n)); + } + + /** + * Like {@link Stream#sorted()}. + * + * @return Like {@link Stream#sorted()}. + */ + default IOStream sorted() { + return adapt(unwrap().sorted()); + } + + /** + * Like {@link Stream#sorted(java.util.Comparator)}. + * + * @param comparator Like {@link Stream#sorted(java.util.Comparator)}. + * @return Like {@link Stream#sorted(java.util.Comparator)}. + * @throws IOException if an I/O error occurs. + */ + @SuppressWarnings("unused") // thrown by Erase. + default IOStream sorted(final IOComparator comparator) throws IOException { + return adapt(unwrap().sorted((t, u) -> Erase.compare(comparator, t, u))); + } + + /** + * Like {@link Stream#toArray()}. + * + * @return {@link Stream#toArray()}. + */ + default Object[] toArray() { + return unwrap().toArray(); + } + + /** + * TODO Package-private for now, needs IOIntFunction? + * + *

Adding this method now and an IO version later is an issue because call sites would have to + * type-cast to pick one. It would be ideal to have only one. + * + *

Like {@link Stream#toArray(IntFunction)}. + * + *

Package private for now. + * + * @param Like {@link Stream#toArray(IntFunction)}. + * @param generator Like {@link Stream#toArray(IntFunction)}. + * @return Like {@link Stream#toArray(IntFunction)}. + */ + default A[] toArray(final IntFunction generator) { + return unwrap().toArray(generator); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java new file mode 100644 index 000000000..c5aeb62fd --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.util.stream.Stream; + +/** + * Adapts an {@link Stream} as an {@link IOStream}. + * + *

Keep package-private for now. + * + * @param the type of the stream elements. + */ +final class IOStreamAdapter extends IOBaseStreamAdapter, Stream> + implements IOStream { + + static IOStream adapt(final Stream delegate) { + return delegate != null ? new IOStreamAdapter<>(delegate) : IOStream.empty(); + } + + private IOStreamAdapter(final Stream delegate) { + super(delegate); + } + + @Override + public IOStream wrap(final Stream delegate) { + return unwrap() == delegate ? this : adapt(delegate); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java new file mode 100644 index 000000000..32583e804 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import org.apache.commons.io.IOExceptionList; +import org.apache.commons.io.IOIndexedException; + +import java.io.IOException; +import java.util.function.BiFunction; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** Keep this code package-private for now. */ +final class IOStreams { + + static final Object NONE = new Object(); + + static void forAll(final Stream stream, final IOConsumer action) + throws IOExceptionList { + forAll(stream, action, (i, e) -> e); + } + + @SuppressWarnings("resource") // adapt() + static void forAll( + final Stream stream, + final IOConsumer action, + final BiFunction exSupplier) + throws IOExceptionList { + IOStream.adapt(stream).forAll(action, IOIndexedException::new); + } + + @SuppressWarnings("unused") // IOStreams.rethrow() throws + static void forEach(final Stream stream, final IOConsumer action) throws IOException { + final IOConsumer actualAction = toIOConsumer(action); + of(stream).forEach(e -> Erase.accept(actualAction, e)); + } + + /** + * Null-safe version of {@link StreamSupport#stream(java.util.Spliterator, boolean)}. + * + *

Copied from Apache Commons Lang. + * + * @param the type of stream elements. + * @param values the elements of the new stream, may be {@code null}. + * @return the new stream on {@code values} or {@link Stream#empty()}. + */ + static Stream of(final Iterable values) { + return values == null ? Stream.empty() : StreamSupport.stream(values.spliterator(), false); + } + + static Stream of(final Stream stream) { + return stream == null ? Stream.empty() : stream; + } + + /** + * Null-safe version of {@link Stream#of(Object[])}. + * + *

Copied from Apache Commons Lang. + * + * @param the type of stream elements. + * @param values the elements of the new stream, may be {@code null}. + * @return the new stream on {@code values} or {@link Stream#empty()}. + */ + @SafeVarargs // Creating a stream from an array is safe + static Stream of(final T... values) { + return values == null ? Stream.empty() : Stream.of(values); + } + + static IOConsumer toIOConsumer(final IOConsumer action) { + return action != null ? action : IOConsumer.noop(); + } + + private IOStreams() { + // no instances + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java new file mode 100644 index 000000000..8dac7856e --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.function.Supplier; + +/** + * Like {@link Supplier} but throws {@link IOException}. + * + *

Using an IOSupplier allows you to compose usage of checked and unchecked exceptions as you + * best see fit. + * + * @param the return type of the operations. + * @since 2.7 + */ +@FunctionalInterface +public interface IOSupplier { + + /** + * Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + * @return an UncheckedIOException Supplier. + * @since 2.12.0 + */ + default Supplier asSupplier() { + return this::getUnchecked; + } + + /** + * Gets a result. + * + * @return a result. + * @throws IOException if an I/O error occurs. + */ + T get() throws IOException; + + /** + * Gets a result. + * + * @return a result. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.17.0 + */ + default T getUnchecked() throws UncheckedIOException { + return Uncheck.get(this); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java new file mode 100644 index 000000000..3088d7e32 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.util.Objects; +import java.util.function.BiConsumer; + +/** + * Like {@link BiConsumer} but throws {@link IOException}. + * + * @param the type of the first argument to the operation + * @param the type of the second argument to the operation + * @param the type of the third argument to the operation + * @see BiConsumer + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOTriConsumer { + + /** + * Returns the no-op singleton. + * + * @param the type of the first argument to the operation + * @param the type of the second argument to the operation + * @param the type of the third argument to the operation + * @return The no-op singleton. + */ + @SuppressWarnings("unchecked") + static IOTriConsumer noop() { + return Constants.IO_TRI_CONSUMER; + } + + /** + * Performs this operation on the given arguments. + * + * @param t the first input argument + * @param u the second input argument + * @param v the second third argument + * @throws IOException if an I/O error occurs. + */ + void accept(T t, U u, V v) throws IOException; + + /** + * Creates a composed {@link IOTriConsumer} that performs, in sequence, this operation followed by + * the {@code after} operation. If performing either operation throws an exception, it is relayed + * to the caller of the composed operation. If performing this operation throws an exception, the + * {@code after} operation will not be performed. + * + * @param after the operation to perform after this operation + * @return a composed {@link IOTriConsumer} that performs in sequence this operation followed by + * the {@code after} operation + * @throws NullPointerException if {@code after} is null + */ + default IOTriConsumer andThen( + final IOTriConsumer after) { + Objects.requireNonNull(after); + return (t, u, v) -> { + accept(t, u, v); + after.accept(t, u, v); + }; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java new file mode 100644 index 000000000..8cd850070 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.function; + +import java.io.IOException; +import java.util.Objects; +import java.util.function.Function; + +/** + * Represents a function that accepts three arguments and produces a result. This is the three-arity + * specialization of {@link IOFunction}. + * + *

This is a functional interface whose functional method is + * {@link #apply(Object, Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function + * @param the type of the third argument to the function + * @param the type of the result of the function + * @see Function + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOTriFunction { + + /** + * Creates a composed function that first applies this function to its input, and then applies the + * {@code after} function to the result. If evaluation of either function throws an exception, it + * is relayed to the caller of the composed function. + * + * @param the type of output of the {@code after} function, and of the composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * function + * @throws NullPointerException if after is null + */ + default IOTriFunction andThen(final IOFunction after) { + Objects.requireNonNull(after); + return (final T t, final U u, final V v) -> after.apply(apply(t, u, v)); + } + + /** + * Applies this function to the given arguments. + * + * @param t the first function argument + * @param u the second function argument + * @param v the third function argument + * @return the function result + * @throws IOException if an I/O error occurs. + */ + R apply(T t, U u, V v) throws IOException; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java new file mode 100644 index 000000000..30660a9c4 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.function.UnaryOperator; + +/** + * Like {@link UnaryOperator} but throws {@link IOException}. + * + * @param the type of the operand and result of the operator. + * @see UnaryOperator + * @see IOFunction + * @since 2.12.0 + */ +@FunctionalInterface +public interface IOUnaryOperator extends IOFunction { + + /** + * Creates a unary operator that always returns its input argument. + * + * @param the type of the input and output of the operator. + * @return a unary operator that always returns its input argument. + */ + static IOUnaryOperator identity() { + return t -> t; + } + + /** + * Creates a {@link UnaryOperator} for this instance that throws {@link UncheckedIOException} + * instead of {@link IOException}. + * + * @return an unchecked BiFunction. + */ + default UnaryOperator asUnaryOperator() { + return t -> Uncheck.apply(this, t); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java b/java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java new file mode 100644 index 000000000..244c340c3 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java @@ -0,0 +1,310 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.function.Supplier; + +/** + * Unchecks calls by throwing {@link UncheckedIOException} instead of {@link IOException}. + * + * @since 2.12.0 + */ +public final class Uncheck { + + /** + * Accepts an IO consumer with the given arguments. + * + * @param the first input type. + * @param the second input type. + * @param t the first input argument. + * @param u the second input argument. + * @param consumer Consumes the value. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static void accept(final IOBiConsumer consumer, final T t, final U u) { + try { + consumer.accept(t, u); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Accepts an IO consumer with the given argument. + * + * @param the input type. + * @param t the input argument. + * @param consumer Consumes the value. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static void accept(final IOConsumer consumer, final T t) { + try { + consumer.accept(t); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Accepts an IO consumer with the given arguments. + * + * @param the first input type. + * @param the second input type. + * @param the third input type. + * @param t the first input argument. + * @param u the second input argument. + * @param v the third input argument. + * @param consumer Consumes the value. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static void accept( + final IOTriConsumer consumer, final T t, final U u, final V v) { + try { + consumer.accept(t, u, v); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Applies an IO function with the given arguments. + * + * @param the first function argument type. + * @param the second function argument type. + * @param the return type. + * @param function the function. + * @param t the first function argument. + * @param u the second function argument. + * @return the function result. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static R apply(final IOBiFunction function, final T t, final U u) { + try { + return function.apply(t, u); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Applies an IO function with the given arguments. + * + * @param function the function. + * @param the first function argument type. + * @param the return type. + * @param t the first function argument. + * @return the function result. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static R apply(final IOFunction function, final T t) { + try { + return function.apply(t); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Applies an IO quad-function with the given arguments. + * + * @param function the function. + * @param the first function argument type. + * @param the second function argument type. + * @param the third function argument type. + * @param the fourth function argument type. + * @param the return type. + * @param t the first function argument. + * @param u the second function argument. + * @param v the third function argument. + * @param w the fourth function argument. + * @return the function result. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static R apply( + final IOQuadFunction function, final T t, final U u, final V v, final W w) { + try { + return function.apply(t, u, v, w); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Applies an IO tri-function with the given arguments. + * + * @param the first function argument type. + * @param the second function argument type. + * @param the third function argument type. + * @param the return type. + * @param function the function. + * @param t the first function argument. + * @param u the second function argument. + * @param v the third function argument. + * @return the function result. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static R apply( + final IOTriFunction function, final T t, final U u, final V v) { + try { + return function.apply(t, u, v); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Compares the arguments with the comparator. + * + * @param the first function argument type. + * @param comparator the function. + * @param t the first function argument. + * @param u the second function argument. + * @return the comparator result. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static int compare(final IOComparator comparator, final T t, final T u) { + try { + return comparator.compare(t, u); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Gets the result from an IO supplier. + * + * @param the return type of the operations. + * @param supplier Supplies the return value. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static T get(final IOSupplier supplier) { + try { + return supplier.get(); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Gets the result from an IO supplier. + * + * @param the return type of the operations. + * @param supplier Supplies the return value. + * @param message The UncheckedIOException message if an I/O error occurs. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static T get(final IOSupplier supplier, final Supplier message) { + try { + return supplier.get(); + } catch (final IOException e) { + throw wrap(e, message); + } + } + + /** + * Gets the result from an IO int supplier. + * + * @param supplier Supplies the return value. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static int getAsInt(final IOIntSupplier supplier) { + try { + return supplier.getAsInt(); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Runs an IO runnable. + * + * @param runnable The runnable to run. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static void run(final IORunnable runnable) { + try { + runnable.run(); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Runs an IO runnable. + * + * @param runnable The runnable to run. + * @param message The UncheckedIOException message if an I/O error occurs. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static void run(final IORunnable runnable, final Supplier message) { + try { + runnable.run(); + } catch (final IOException e) { + throw wrap(e, message); + } + } + + /** + * Tests an IO predicate. + * + * @param the type of the input to the predicate. + * @param predicate the predicate. + * @param t the input to the predicate. + * @return {@code true} if the input argument matches the predicate, otherwise {@code false}. + */ + public static boolean test(final IOPredicate predicate, final T t) { + try { + return predicate.test(t); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Constructs a new {@link UncheckedIOException} for the given exception. + * + * @param e The exception to wrap. + * @return a new {@link UncheckedIOException}. + */ + private static UncheckedIOException wrap(final IOException e) { + return new UncheckedIOException(e); + } + + /** + * Constructs a new {@link UncheckedIOException} for the given exception and detail message. + * + * @param e The exception to wrap. + * @param message The UncheckedIOException message if an I/O error occurs. + * @return a new {@link UncheckedIOException}. + */ + private static UncheckedIOException wrap(final IOException e, final Supplier message) { + return new UncheckedIOException(message.get(), e); + } + + /** No instances needed. */ + private Uncheck() { + // no instances needed. + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java b/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java new file mode 100644 index 000000000..cfa4e12dc --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.stream.BaseStream; + +/** + * An {@link BaseStream} for a {@link IOBaseStream} that throws {@link UncheckedIOException} instead + * of {@link IOException}. + * + *

Keep package-private for now. + * + * @param the type of the stream elements. + * @param the type of the IO stream extending {@code IOBaseStream}. + * @param the type of the stream extending {@code BaseStream}. + */ +final class UncheckedIOBaseStream, B extends BaseStream> + implements BaseStream { + + private final S delegate; + + UncheckedIOBaseStream(final S delegate) { + this.delegate = delegate; + } + + @Override + public void close() { + delegate.close(); + } + + @Override + public boolean isParallel() { + return delegate.isParallel(); + } + + @Override + public Iterator iterator() { + return delegate.iterator().asIterator(); + } + + @SuppressWarnings("resource") + @Override + public B onClose(final Runnable closeHandler) { + return Uncheck.apply(delegate::onClose, () -> closeHandler.run()).unwrap(); + } + + @SuppressWarnings("resource") + @Override + public B parallel() { + return delegate.parallel().unwrap(); + } + + @SuppressWarnings("resource") + @Override + public B sequential() { + return delegate.sequential().unwrap(); + } + + @Override + public Spliterator spliterator() { + return delegate.spliterator().unwrap(); + } + + @SuppressWarnings("resource") + @Override + public B unordered() { + return delegate.unordered().unwrap(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java new file mode 100644 index 000000000..e88c445fd --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Iterator; +import java.util.Objects; + +/** + * An {@link Iterator} for a {@link IOIterator} that throws {@link UncheckedIOException} instead of + * {@link IOException}. + * + *

Keep package-private for now. + * + * @param the type of elements returned by this iterator. + */ +final class UncheckedIOIterator implements Iterator { + + private final IOIterator delegate; + + /** + * Constructs a new instance. + * + * @param delegate The delegate + */ + UncheckedIOIterator(final IOIterator delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate"); + } + + @Override + public boolean hasNext() { + return Uncheck.get(delegate::hasNext); + } + + @Override + public E next() { + return Uncheck.get(delegate::next); + } + + @Override + public void remove() { + Uncheck.run(delegate::remove); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java b/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java new file mode 100644 index 000000000..2f1875747 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Comparator; +import java.util.Objects; +import java.util.Spliterator; +import java.util.function.Consumer; + +/** + * A {@link Spliterator} for an {@link IOSpliterator} that throws {@link UncheckedIOException} + * instead of {@link IOException}. + * + *

Keep package-private for now. + * + * @param the type of elements returned by this iterator. + */ +final class UncheckedIOSpliterator implements Spliterator { + + private final IOSpliterator delegate; + + UncheckedIOSpliterator(final IOSpliterator delegate) { + this.delegate = Objects.requireNonNull(delegate, "delegate"); + } + + @Override + public int characteristics() { + return delegate.characteristics(); + } + + @Override + public long estimateSize() { + return delegate.estimateSize(); + } + + @Override + public void forEachRemaining(final Consumer action) { + Uncheck.accept(delegate::forEachRemaining, action::accept); + } + + @Override + public Comparator getComparator() { + return delegate.getComparator().asComparator(); + } + + @Override + public long getExactSizeIfKnown() { + return delegate.getExactSizeIfKnown(); + } + + @Override + public boolean hasCharacteristics(final int characteristics) { + return delegate.hasCharacteristics(characteristics); + } + + @Override + public boolean tryAdvance(final Consumer action) { + return Uncheck.apply(delegate::tryAdvance, action::accept); + } + + @Override + public Spliterator trySplit() { + return Uncheck.get(delegate::trySplit).unwrap(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java new file mode 100644 index 000000000..e5f2dd665 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import org.apache.commons.io.IOUtils; + +import java.io.InputStream; + +import static org.apache.commons.io.IOUtils.EOF; + +/** + * Always returns {@link IOUtils#EOF} to all attempts to read something from the stream. + * + *

Typically uses of this class include testing for corner cases in methods that accept input + * streams and acting as a sentinel value instead of a {@code null} input stream. + * + * @since 1.4 + */ +public class ClosedInputStream extends InputStream { + + /** + * The singleton instance. + * + * @since 2.12.0 + */ + public static final ClosedInputStream INSTANCE = new ClosedInputStream(); + + /** + * The singleton instance. + * + * @deprecated Use {@link #INSTANCE}. + */ + @Deprecated public static final ClosedInputStream CLOSED_INPUT_STREAM = INSTANCE; + + /** + * Returns -1 to indicate that the stream is closed. + * + * @return always -1 + */ + @Override + public int read() { + return EOF; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java new file mode 100644 index 000000000..e164c55a0 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java @@ -0,0 +1,453 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.build.AbstractOrigin; +import org.apache.commons.io.build.AbstractStreamBuilder; +import org.apache.commons.io.charset.CharsetEncoders; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.util.Objects; + +import static org.apache.commons.io.IOUtils.EOF; + +/** + * {@link InputStream} implementation that reads a character stream from a {@link Reader} and + * transforms it to a byte stream using a specified charset encoding. The stream is transformed + * using a {@link CharsetEncoder} object, guaranteeing that all charset encodings supported by the + * JRE are handled correctly. In particular for charsets such as UTF-16, the implementation ensures + * that one and only one byte order marker is produced. + * + *

Since in general it is not possible to predict the number of characters to be read from the + * {@link Reader} to satisfy a read request on the {@link ReaderInputStream}, all reads from the + * {@link Reader} are buffered. There is therefore no well defined correlation between the current + * position of the {@link Reader} and that of the {@link ReaderInputStream}. This also implies that + * in general there is no need to wrap the underlying {@link Reader} in a {@link + * java.io.BufferedReader}. + * + *

{@link ReaderInputStream} implements the inverse transformation of {@link + * java.io.InputStreamReader}; in the following example, reading from {@code in2} would return the + * same byte sequence as reading from {@code in} (provided that the initial byte sequence is legal + * with respect to the charset encoding): + * + *

To build an instance, see {@link Builder}. + * + *

+ * InputStream inputStream = ...
+ * Charset cs = ...
+ * InputStreamReader reader = new InputStreamReader(inputStream, cs);
+ * ReaderInputStream in2 = ReaderInputStream.builder()
+ *   .setReader(reader)
+ *   .setCharset(cs)
+ *   .get();
+ * 
+ * + *

{@link ReaderInputStream} implements the same transformation as {@link + * java.io.OutputStreamWriter}, except that the control flow is reversed: both classes transform a + * character stream into a byte stream, but {@link java.io.OutputStreamWriter} pushes data to the + * underlying stream, while {@link ReaderInputStream} pulls it from the underlying stream. + * + *

Note that while there are use cases where there is no alternative to using this class, very + * often the need to use this class is an indication of a flaw in the design of the code. This class + * is typically used in situations where an existing API only accepts an {@link InputStream}, but + * where the most natural way to produce the data is as a character stream, i.e. by providing a + * {@link Reader} instance. An example of a situation where this problem may appear is when + * implementing the {@code javax.activation.DataSource} interface from the Java Activation + * Framework. + * + *

The {@link #available()} method of this class always returns 0. The methods {@link #mark(int)} + * and {@link #reset()} are not supported. + * + *

Instances of {@link ReaderInputStream} are not thread safe. + * + * @see org.apache.commons.io.output.WriterOutputStream + * @since 2.0 + */ +public class ReaderInputStream extends InputStream { + + /** + * Builds a new {@link ReaderInputStream} instance. + * + *

For example: + * + *

{@code
+   * ReaderInputStream s = ReaderInputStream.builder()
+   *   .setPath(path)
+   *   .setCharsetEncoder(Charset.defaultCharset().newEncoder())
+   *   .get();
+   * }
+ * + * @since 2.12.0 + */ + public static class Builder extends AbstractStreamBuilder { + + private CharsetEncoder charsetEncoder = newEncoder(getCharset()); + + /** + * Constructs a new instance. + * + *

This builder use the aspects Reader, Charset, CharsetEncoder, buffer size. + * + *

You must provide an origin that can be converted to a Reader by this builder, otherwise, + * this call will throw an {@link UnsupportedOperationException}. + * + * @return a new instance. + * @throws UnsupportedOperationException if the origin cannot provide a Reader. + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @see AbstractOrigin#getReader(Charset) + */ + @SuppressWarnings("resource") + @Override + public ReaderInputStream get() throws IOException { + return new ReaderInputStream( + checkOrigin().getReader(getCharset()), charsetEncoder, getBufferSize()); + } + + CharsetEncoder getCharsetEncoder() { + return charsetEncoder; + } + + @Override + public Builder setCharset(final Charset charset) { + super.setCharset(charset); + charsetEncoder = newEncoder(getCharset()); + return this; + } + + /** + * Sets the charset encoder. Assumes that the caller has configured the encoder. + * + * @param newEncoder the charset encoder, null resets to a default encoder. + * @return this + */ + public Builder setCharsetEncoder(final CharsetEncoder newEncoder) { + charsetEncoder = + CharsetEncoders.toCharsetEncoder(newEncoder, () -> newEncoder(getCharsetDefault())); + super.setCharset(charsetEncoder.charset()); + return this; + } + } + + /** + * Constructs a new {@link Builder}. + * + * @return a new {@link Builder}. + * @since 2.12.0 + */ + public static Builder builder() { + return new Builder(); + } + + static int checkMinBufferSize(final CharsetEncoder charsetEncoder, final int bufferSize) { + final float minRequired = minBufferSize(charsetEncoder); + if (bufferSize < minRequired) { + throw new IllegalArgumentException( + String.format( + "Buffer size %,d must be at least %s for a CharsetEncoder %s.", + bufferSize, minRequired, charsetEncoder.charset().displayName())); + } + return bufferSize; + } + + static float minBufferSize(final CharsetEncoder charsetEncoder) { + return charsetEncoder.maxBytesPerChar() * 2; + } + + private static CharsetEncoder newEncoder(final Charset charset) { + // @formatter:off + return Charsets.toCharset(charset) + .newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + // @formatter:on + } + + private final Reader reader; + + private final CharsetEncoder charsetEncoder; + + /** + * CharBuffer used as input for the decoder. It should be reasonably large as we read data from + * the underlying Reader into this buffer. + */ + private final CharBuffer encoderIn; + + /** + * ByteBuffer used as output for the decoder. This buffer can be small as it is only used to + * transfer data from the decoder to the buffer provided by the caller. + */ + private final ByteBuffer encoderOut; + + private CoderResult lastCoderResult; + + private boolean endOfInput; + + /** + * Constructs a new {@link ReaderInputStream} that uses the default character encoding with a + * default input buffer size of {@value IOUtils#DEFAULT_BUFFER_SIZE} characters. + * + * @param reader the target {@link Reader} + * @deprecated Use {@link ReaderInputStream#builder()} instead + */ + @Deprecated + public ReaderInputStream(final Reader reader) { + this(reader, Charset.defaultCharset()); + } + + /** + * Constructs a new {@link ReaderInputStream} with a default input buffer size of {@value + * IOUtils#DEFAULT_BUFFER_SIZE} characters. + * + *

The encoder created for the specified charset will use {@link CodingErrorAction#REPLACE} for + * malformed input and unmappable characters. + * + * @param reader the target {@link Reader} + * @param charset the charset encoding + * @deprecated Use {@link ReaderInputStream#builder()} instead, will be protected for subclasses. + */ + @Deprecated + public ReaderInputStream(final Reader reader, final Charset charset) { + this(reader, charset, IOUtils.DEFAULT_BUFFER_SIZE); + } + + /** + * Constructs a new {@link ReaderInputStream}. + * + *

The encoder created for the specified charset will use {@link CodingErrorAction#REPLACE} for + * malformed input and unmappable characters. + * + * @param reader the target {@link Reader}. + * @param charset the charset encoding. + * @param bufferSize the size of the input buffer in number of characters. + * @deprecated Use {@link ReaderInputStream#builder()} instead + */ + @Deprecated + public ReaderInputStream(final Reader reader, final Charset charset, final int bufferSize) { + // @formatter:off + this( + reader, + Charsets.toCharset(charset) + .newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE), + bufferSize); + // @formatter:on + } + + /** + * Constructs a new {@link ReaderInputStream}. + * + *

This constructor does not call {@link CharsetEncoder#reset() reset} on the provided encoder. + * The caller of this constructor should do this when providing an encoder which had already been + * in use. + * + * @param reader the target {@link Reader} + * @param charsetEncoder the charset encoder + * @since 2.1 + * @deprecated Use {@link ReaderInputStream#builder()} instead + */ + @Deprecated + public ReaderInputStream(final Reader reader, final CharsetEncoder charsetEncoder) { + this(reader, charsetEncoder, IOUtils.DEFAULT_BUFFER_SIZE); + } + + /** + * Constructs a new {@link ReaderInputStream}. + * + *

This constructor does not call {@link CharsetEncoder#reset() reset} on the provided encoder. + * The caller of this constructor should do this when providing an encoder which had already been + * in use. + * + * @param reader the target {@link Reader} + * @param charsetEncoder the charset encoder, null defaults to the default Charset encoder. + * @param bufferSize the size of the input buffer in number of characters + * @since 2.1 + * @deprecated Use {@link ReaderInputStream#builder()} instead + */ + @Deprecated + public ReaderInputStream( + final Reader reader, final CharsetEncoder charsetEncoder, final int bufferSize) { + this.reader = reader; + this.charsetEncoder = CharsetEncoders.toCharsetEncoder(charsetEncoder); + this.encoderIn = CharBuffer.allocate(checkMinBufferSize(this.charsetEncoder, bufferSize)); + this.encoderIn.flip(); + this.encoderOut = ByteBuffer.allocate(128); + this.encoderOut.flip(); + } + + /** + * Constructs a new {@link ReaderInputStream} with a default input buffer size of {@value + * IOUtils#DEFAULT_BUFFER_SIZE} characters. + * + *

The encoder created for the specified charset will use {@link CodingErrorAction#REPLACE} for + * malformed input and unmappable characters. + * + * @param reader the target {@link Reader} + * @param charsetName the name of the charset encoding + * @deprecated Use {@link ReaderInputStream#builder()} instead + */ + @Deprecated + public ReaderInputStream(final Reader reader, final String charsetName) { + this(reader, charsetName, IOUtils.DEFAULT_BUFFER_SIZE); + } + + /** + * Constructs a new {@link ReaderInputStream}. + * + *

The encoder created for the specified charset will use {@link CodingErrorAction#REPLACE} for + * malformed input and unmappable characters. + * + * @param reader the target {@link Reader} + * @param charsetName the name of the charset encoding, null maps to the default Charset. + * @param bufferSize the size of the input buffer in number of characters + * @deprecated Use {@link ReaderInputStream#builder()} instead + */ + @Deprecated + public ReaderInputStream(final Reader reader, final String charsetName, final int bufferSize) { + this(reader, Charsets.toCharset(charsetName), bufferSize); + } + + /** + * Closes the stream. This method will cause the underlying {@link Reader} to be closed. + * + * @throws IOException if an I/O error occurs. + */ + @Override + public void close() throws IOException { + reader.close(); + } + + /** + * Fills the internal char buffer from the reader. + * + * @throws IOException If an I/O error occurs + */ + private void fillBuffer() throws IOException { + if (endOfInput) { + return; + } + if (!endOfInput && (lastCoderResult == null || lastCoderResult.isUnderflow())) { + encoderIn.compact(); + final int position = encoderIn.position(); + // We don't use Reader#read(CharBuffer) here because it is more efficient + // to write directly to the underlying char array (the default implementation + // copies data to a temporary char array). + final int c = reader.read(encoderIn.array(), position, encoderIn.remaining()); + if (c == EOF) { + endOfInput = true; + } else { + encoderIn.position(position + c); + } + encoderIn.flip(); + } + encoderOut.compact(); + lastCoderResult = charsetEncoder.encode(encoderIn, encoderOut, endOfInput); + if (endOfInput) { + lastCoderResult = charsetEncoder.flush(encoderOut); + } + if (lastCoderResult.isError()) { + lastCoderResult.throwException(); + } + encoderOut.flip(); + } + + /** + * Gets the CharsetEncoder. + * + * @return the CharsetEncoder. + */ + CharsetEncoder getCharsetEncoder() { + return charsetEncoder; + } + + /** + * Reads a single byte. + * + * @return either the byte read or {@code -1} if the end of the stream has been reached + * @throws IOException if an I/O error occurs. + */ + @Override + public int read() throws IOException { + for (; ; ) { + if (encoderOut.hasRemaining()) { + return encoderOut.get() & 0xFF; + } + fillBuffer(); + if (endOfInput && !encoderOut.hasRemaining()) { + return EOF; + } + } + } + + /** + * Reads the specified number of bytes into an array. + * + * @param b the byte array to read into + * @return the number of bytes read or {@code -1} if the end of the stream has been reached + * @throws IOException if an I/O error occurs. + */ + @Override + public int read(final byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Reads the specified number of bytes into an array. + * + * @param array the byte array to read into + * @param off the offset to start reading bytes into + * @param len the number of bytes to read + * @return the number of bytes read or {@code -1} if the end of the stream has been reached + * @throws IOException if an I/O error occurs. + */ + @Override + public int read(final byte[] array, int off, int len) throws IOException { + Objects.requireNonNull(array, "array"); + if (len < 0 || off < 0 || off + len > array.length) { + throw new IndexOutOfBoundsException( + "Array size=" + array.length + ", offset=" + off + ", length=" + len); + } + int read = 0; + if (len == 0) { + return 0; // Always return 0 if len == 0 + } + while (len > 0) { + if (encoderOut.hasRemaining()) { // Data from the last read not fully copied + final int c = Math.min(encoderOut.remaining(), len); + encoderOut.get(array, off, c); + off += c; + len -= c; + read += c; + } else if (endOfInput) { // Already reach EOF in the last read + break; + } else { // Read again + fillBuffer(); + } + } + return read == 0 && endOfInput ? EOF : read; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java new file mode 100644 index 000000000..7d54e2dd1 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java @@ -0,0 +1,276 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import org.apache.commons.io.build.AbstractOrigin; +import org.apache.commons.io.build.AbstractStreamBuilder; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static java.lang.Math.min; + +/** + * This is an alternative to {@link java.io.ByteArrayInputStream} which removes the synchronization + * overhead for non-concurrent access; as such this class is not thread-safe. + * + *

To build an instance, see {@link Builder}. + * + * @see ByteArrayInputStream + * @since 2.7 + */ +// @NotThreadSafe +public class UnsynchronizedByteArrayInputStream extends InputStream { + + /** + * Builds a new {@link UnsynchronizedByteArrayInputStream} instance. + * + *

Using a Byte Array: + * + *

{@code
+   * UnsynchronizedByteArrayInputStream s = UnsynchronizedByteArrayInputStream.builder()
+   *   .setByteArray(byteArray)
+   *   .setOffset(0)
+   *   .setLength(byteArray.length)
+   *   .get();
+   * }
+ * + *

Using File IO: + * + *

{@code
+   * UnsynchronizedByteArrayInputStream s = UnsynchronizedByteArrayInputStream.builder()
+   *   .setFile(file)
+   *   .setOffset(0)
+   *   .setLength(byteArray.length)
+   *   .get();
+   * }
+ * + *

Using NIO Path: + * + *

{@code
+   * UnsynchronizedByteArrayInputStream s = UnsynchronizedByteArrayInputStream.builder()
+   *   .setPath(path)
+   *   .setOffset(0)
+   *   .setLength(byteArray.length)
+   *   .get();
+   * }
+ */ + public static class Builder + extends AbstractStreamBuilder { + + private int offset; + private int length; + + /** + * Constructs a new instance. + * + *

This builder use the aspects byte[], offset and length. + * + *

You must provide an origin that can be converted to a byte[] by this builder, otherwise, + * this call will throw an {@link UnsupportedOperationException}. + * + * @return a new instance. + * @throws UnsupportedOperationException if the origin cannot provide a byte[]. + * @throws IllegalStateException if the {@code origin} is {@code null}. + * @see AbstractOrigin#getByteArray() + */ + @Override + public UnsynchronizedByteArrayInputStream get() throws IOException { + return new UnsynchronizedByteArrayInputStream(checkOrigin().getByteArray(), offset, length); + } + + @Override + public Builder setByteArray(final byte[] origin) { + length = Objects.requireNonNull(origin, "origin").length; + return super.setByteArray(origin); + } + + public Builder setLength(final int length) { + if (length < 0) { + throw new IllegalArgumentException("length cannot be negative"); + } + this.length = length; + return this; + } + + public Builder setOffset(final int offset) { + if (offset < 0) { + throw new IllegalArgumentException("offset cannot be negative"); + } + this.offset = offset; + return this; + } + } + + /** The end of stream marker. */ + public static final int END_OF_STREAM = -1; + + /** + * Constructs a new {@link Builder}. + * + * @return a new {@link Builder}. + */ + public static Builder builder() { + return new Builder(); + } + + /** The underlying data buffer. */ + private final byte[] data; + + /** + * End Of Data. + * + *

Similar to data.length, i.e. the last readable offset + 1. + */ + private final int eod; + + /** Current offset in the data buffer. */ + private int offset; + + /** The current mark (if any). */ + private int markedOffset; + + /** + * Constructs a new byte array input stream. + * + * @param data the buffer + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. + */ + @Deprecated + public UnsynchronizedByteArrayInputStream(final byte[] data) { + this.data = Objects.requireNonNull(data, "data"); + this.offset = 0; + this.eod = data.length; + this.markedOffset = this.offset; + } + + /** + * Constructs a new byte array input stream. + * + * @param data the buffer + * @param offset the offset into the buffer + * @throws IllegalArgumentException if the offset is less than zero + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. + */ + @Deprecated + public UnsynchronizedByteArrayInputStream(final byte[] data, final int offset) { + Objects.requireNonNull(data, "data"); + if (offset < 0) { + throw new IllegalArgumentException("offset cannot be negative"); + } + this.data = data; + this.offset = min(offset, data.length > 0 ? data.length : offset); + this.eod = data.length; + this.markedOffset = this.offset; + } + + /** + * Constructs a new byte array input stream. + * + * @param data the buffer + * @param offset the offset into the buffer + * @param length the length of the buffer + * @throws IllegalArgumentException if the offset or length less than zero + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. + */ + @Deprecated + public UnsynchronizedByteArrayInputStream(final byte[] data, final int offset, final int length) { + if (offset < 0) { + throw new IllegalArgumentException("offset cannot be negative"); + } + if (length < 0) { + throw new IllegalArgumentException("length cannot be negative"); + } + this.data = Objects.requireNonNull(data, "data"); + this.offset = min(offset, data.length > 0 ? data.length : offset); + this.eod = min(this.offset + length, data.length); + this.markedOffset = this.offset; + } + + @Override + public int available() { + return offset < eod ? eod - offset : 0; + } + + @SuppressWarnings("sync-override") + @Override + public void mark(final int readlimit) { + this.markedOffset = this.offset; + } + + @Override + public boolean markSupported() { + return true; + } + + @Override + public int read() { + return offset < eod ? data[offset++] & 0xff : END_OF_STREAM; + } + + @Override + public int read(final byte[] dest) { + Objects.requireNonNull(dest, "dest"); + return read(dest, 0, dest.length); + } + + @Override + public int read(final byte[] dest, final int off, final int len) { + Objects.requireNonNull(dest, "dest"); + if (off < 0 || len < 0 || off + len > dest.length) { + throw new IndexOutOfBoundsException(); + } + + if (offset >= eod) { + return END_OF_STREAM; + } + + int actualLen = eod - offset; + if (len < actualLen) { + actualLen = len; + } + if (actualLen <= 0) { + return 0; + } + System.arraycopy(data, offset, dest, off, actualLen); + offset += actualLen; + return actualLen; + } + + @SuppressWarnings("sync-override") + @Override + public void reset() { + this.offset = this.markedOffset; + } + + @Override + public long skip(final long n) { + if (n < 0) { + throw new IllegalArgumentException("Skipping backward is not supported"); + } + + long actualSkip = eod - offset; + if (n < actualSkip) { + actualSkip = n; + } + + offset = Math.addExact(offset, Math.toIntExact(n)); + return actualSkip; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java new file mode 100644 index 000000000..e3b789e8c --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java @@ -0,0 +1,394 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ClosedInputStream; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.SequenceInputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.apache.commons.io.IOUtils.EOF; + +/** + * This is the base class for implementing an output stream in which the data is written into a byte + * array. The buffer automatically grows as data is written to it. + * + *

The data can be retrieved using {@code toByteArray()} and {@code toString()}. Closing an + * {@link AbstractByteArrayOutputStream} has no effect. The methods in this class can be called + * after the stream has been closed without generating an {@link IOException}. + * + *

This is the base for an alternative implementation of the {@link + * java.io.ByteArrayOutputStream} class. The original implementation only allocates 32 bytes at the + * beginning. As this class is designed for heavy duty it starts at {@value #DEFAULT_SIZE} bytes. In + * contrast to the original it doesn't reallocate the whole memory block but allocates additional + * buffers. This way no buffers need to be garbage collected and the contents don't have to be + * copied to the new buffer. This class is designed to behave exactly like the original. The only + * exception is the deprecated {@link java.io.ByteArrayOutputStream#toString(int)} method that has + * been ignored. + * + * @since 2.7 + */ +public abstract class AbstractByteArrayOutputStream extends OutputStream { + + /** + * Constructor for an InputStream subclass. + * + * @param the type of the InputStream. + */ + @FunctionalInterface + protected interface InputStreamConstructor { + + /** + * Constructs an InputStream subclass. + * + * @param buffer the buffer + * @param offset the offset into the buffer + * @param length the length of the buffer + * @return the InputStream subclass. + */ + T construct(final byte[] buffer, final int offset, final int length); + } + + static final int DEFAULT_SIZE = 1024; + + /** The list of buffers, which grows and never reduces. */ + private final List buffers = new ArrayList<>(); + + /** The index of the current buffer. */ + private int currentBufferIndex; + + /** The total count of bytes in all the filled buffers. */ + private int filledBufferSum; + + /** The current buffer. */ + private byte[] currentBuffer; + + /** The total count of bytes written. */ + protected int count; + + /** Flag to indicate if the buffers can be reused after reset */ + private boolean reuseBuffers = true; + + /** + * Does nothing. + * + *

The methods in this class can be called after the stream has been closed without generating + * an {@link IOException}. + * + * @throws IOException never (this method should not declare this exception but it has to now due + * to backwards compatibility) + */ + @Override + public void close() throws IOException { + // nop + } + + /** + * Makes a new buffer available either by allocating a new one or re-cycling an existing one. + * + * @param newCount the size of the buffer if one is created + */ + protected void needNewBuffer(final int newCount) { + if (currentBufferIndex < buffers.size() - 1) { + // Recycling old buffer + filledBufferSum += currentBuffer.length; + + currentBufferIndex++; + currentBuffer = buffers.get(currentBufferIndex); + } else { + // Creating new buffer + final int newBufferSize; + if (currentBuffer == null) { + newBufferSize = newCount; + filledBufferSum = 0; + } else { + newBufferSize = Math.max(currentBuffer.length << 1, newCount - filledBufferSum); + filledBufferSum += currentBuffer.length; + } + + currentBufferIndex++; + currentBuffer = IOUtils.byteArray(newBufferSize); + buffers.add(currentBuffer); + } + } + + /** + * @see java.io.ByteArrayOutputStream#reset() + */ + public abstract void reset(); + + /** + * @see java.io.ByteArrayOutputStream#reset() + */ + protected void resetImpl() { + count = 0; + filledBufferSum = 0; + currentBufferIndex = 0; + if (reuseBuffers) { + currentBuffer = buffers.get(currentBufferIndex); + } else { + // Throw away old buffers + currentBuffer = null; + final int size = buffers.get(0).length; + buffers.clear(); + needNewBuffer(size); + reuseBuffers = true; + } + } + + /** + * Returns the current size of the byte array. + * + * @return the current size of the byte array + */ + public abstract int size(); + + /** + * Gets the current contents of this byte stream as a byte array. The result is independent of + * this stream. + * + * @return the current contents of this output stream, as a byte array + * @see java.io.ByteArrayOutputStream#toByteArray() + */ + public abstract byte[] toByteArray(); + + /** + * Gets the current contents of this byte stream as a byte array. The result is independent of + * this stream. + * + * @return the current contents of this output stream, as a byte array + * @see java.io.ByteArrayOutputStream#toByteArray() + */ + protected byte[] toByteArrayImpl() { + int remaining = count; + if (remaining == 0) { + return IOUtils.EMPTY_BYTE_ARRAY; + } + final byte[] newBuf = IOUtils.byteArray(remaining); + int pos = 0; + for (final byte[] buf : buffers) { + final int c = Math.min(buf.length, remaining); + System.arraycopy(buf, 0, newBuf, pos, c); + pos += c; + remaining -= c; + if (remaining == 0) { + break; + } + } + return newBuf; + } + + /** + * Gets the current contents of this byte stream as an Input Stream. The returned stream is backed + * by buffers of {@code this} stream, avoiding memory allocation and copy, thus saving space and + * time.
+ * + * @return the current contents of this output stream. + * @see java.io.ByteArrayOutputStream#toByteArray() + * @see #reset() + * @since 2.5 + */ + public abstract InputStream toInputStream(); + + /** + * Gets the current contents of this byte stream as an Input Stream. The returned stream is backed + * by buffers of {@code this} stream, avoiding memory allocation and copy, thus saving space and + * time.
+ * + * @param the type of the InputStream which makes up the {@link SequenceInputStream}. + * @param isConstructor A constructor for an InputStream which makes up the {@link + * SequenceInputStream}. + * @return the current contents of this output stream. + * @see java.io.ByteArrayOutputStream#toByteArray() + * @see #reset() + * @since 2.7 + */ + @SuppressWarnings("resource") // The result InputStream MUST be managed by the call site. + protected InputStream toInputStream( + final InputStreamConstructor isConstructor) { + int remaining = count; + if (remaining == 0) { + return ClosedInputStream.INSTANCE; + } + final List list = new ArrayList<>(buffers.size()); + for (final byte[] buf : buffers) { + final int c = Math.min(buf.length, remaining); + list.add(isConstructor.construct(buf, 0, c)); + remaining -= c; + if (remaining == 0) { + break; + } + } + reuseBuffers = false; + return new SequenceInputStream(Collections.enumeration(list)); + } + + /** + * Gets the current contents of this byte stream as a string using the platform default charset. + * + * @return the contents of the byte array as a String + * @see java.io.ByteArrayOutputStream#toString() + * @deprecated 2.5 use {@link #toString(String)} instead + */ + @Override + @Deprecated + public String toString() { + // make explicit the use of the default charset + return new String(toByteArray(), Charset.defaultCharset()); + } + + /** + * Gets the current contents of this byte stream as a string using the specified encoding. + * + * @param charset the character encoding + * @return the string converted from the byte array + * @see java.io.ByteArrayOutputStream#toString(String) + * @since 2.5 + */ + public String toString(final Charset charset) { + return new String(toByteArray(), charset); + } + + /** + * Gets the current contents of this byte stream as a string using the specified encoding. + * + * @param enc the name of the character encoding + * @return the string converted from the byte array + * @throws UnsupportedEncodingException if the encoding is not supported + * @see java.io.ByteArrayOutputStream#toString(String) + */ + public String toString(final String enc) throws UnsupportedEncodingException { + return new String(toByteArray(), enc); + } + + @Override + public abstract void write(final byte[] b, final int off, final int len); + + /** + * Writes the entire contents of the specified input stream to this byte stream. Bytes from the + * input stream are read directly into the internal buffer of this stream. + * + * @param in the input stream to read from + * @return total number of bytes read from the input stream (and written to this stream) + * @throws IOException if an I/O error occurs while reading the input stream + * @since 1.4 + */ + public abstract int write(final InputStream in) throws IOException; + + @Override + public abstract void write(final int b); + + /** + * Writes the bytes to the byte array. + * + * @param b the bytes to write + * @param off The start offset + * @param len The number of bytes to write + */ + protected void writeImpl(final byte[] b, final int off, final int len) { + final int newCount = count + len; + int remaining = len; + int inBufferPos = count - filledBufferSum; + while (remaining > 0) { + final int part = Math.min(remaining, currentBuffer.length - inBufferPos); + System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part); + remaining -= part; + if (remaining > 0) { + needNewBuffer(newCount); + inBufferPos = 0; + } + } + count = newCount; + } + + /** + * Writes the entire contents of the specified input stream to this byte stream. Bytes from the + * input stream are read directly into the internal buffer of this stream. + * + * @param in the input stream to read from + * @return total number of bytes read from the input stream (and written to this stream) + * @throws IOException if an I/O error occurs while reading the input stream + * @since 2.7 + */ + protected int writeImpl(final InputStream in) throws IOException { + int readCount = 0; + int inBufferPos = count - filledBufferSum; + int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos); + while (n != EOF) { + readCount += n; + inBufferPos += n; + count += n; + if (inBufferPos == currentBuffer.length) { + needNewBuffer(currentBuffer.length); + inBufferPos = 0; + } + n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos); + } + return readCount; + } + + /** + * Write a byte to byte array. + * + * @param b the byte to write + */ + protected void writeImpl(final int b) { + int inBufferPos = count - filledBufferSum; + if (inBufferPos == currentBuffer.length) { + needNewBuffer(count + 1); + inBufferPos = 0; + } + currentBuffer[inBufferPos] = (byte) b; + count++; + } + + /** + * Writes the entire contents of this byte stream to the specified output stream. + * + * @param out the output stream to write to + * @throws IOException if an I/O error occurs, such as if the stream is closed + * @see java.io.ByteArrayOutputStream#writeTo(OutputStream) + */ + public abstract void writeTo(final OutputStream out) throws IOException; + + /** + * Writes the entire contents of this byte stream to the specified output stream. + * + * @param out the output stream to write to + * @throws IOException if an I/O error occurs, such as if the stream is closed + * @see java.io.ByteArrayOutputStream#writeTo(OutputStream) + */ + protected void writeToImpl(final OutputStream out) throws IOException { + int remaining = count; + for (final byte[] buf : buffers) { + final int c = Math.min(buf.length, remaining); + out.write(buf, 0, c); + remaining -= c; + if (remaining == 0) { + break; + } + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java new file mode 100644 index 000000000..662506e13 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Implements a ThreadSafe version of {@link AbstractByteArrayOutputStream} using instance + * synchronization. + */ +// @ThreadSafe +public class ByteArrayOutputStream extends AbstractByteArrayOutputStream { + + /** + * Fetches entire contents of an {@link InputStream} and represent same data as result + * InputStream. + * + *

This method is useful where, + * + *

    + *
  • Source InputStream is slow. + *
  • It has network resources associated, so we cannot keep it open for long time. + *
  • It has network timeout associated. + *
+ * + * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and + * copy of byte[].
+ * This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input Stream to be fully buffered. + * @return A fully buffered stream. + * @throws IOException if an I/O error occurs. + * @since 2.0 + */ + public static InputStream toBufferedInputStream(final InputStream input) throws IOException { + return toBufferedInputStream(input, DEFAULT_SIZE); + } + + /** + * Fetches entire contents of an {@link InputStream} and represent same data as result + * InputStream. + * + *

This method is useful where, + * + *

    + *
  • Source InputStream is slow. + *
  • It has network resources associated, so we cannot keep it open for long time. + *
  • It has network timeout associated. + *
+ * + * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and + * copy of byte[].
+ * This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input Stream to be fully buffered. + * @param size the initial buffer size + * @return A fully buffered stream. + * @throws IOException if an I/O error occurs. + * @since 2.5 + */ + public static InputStream toBufferedInputStream(final InputStream input, final int size) + throws IOException { + try (ByteArrayOutputStream output = new ByteArrayOutputStream(size)) { + output.write(input); + return output.toInputStream(); + } + } + + /** + * Constructs a new byte array output stream. The buffer capacity is initially {@value + * AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary. + */ + public ByteArrayOutputStream() { + this(DEFAULT_SIZE); + } + + /** + * Constructs a new byte array output stream, with a buffer capacity of the specified size, in + * bytes. + * + * @param size the initial size + * @throws IllegalArgumentException if size is negative + */ + public ByteArrayOutputStream(final int size) { + if (size < 0) { + throw new IllegalArgumentException("Negative initial size: " + size); + } + synchronized (this) { + needNewBuffer(size); + } + } + + /** + * @see java.io.ByteArrayOutputStream#reset() + */ + @Override + public synchronized void reset() { + resetImpl(); + } + + @Override + public synchronized int size() { + return count; + } + + @Override + public synchronized byte[] toByteArray() { + return toByteArrayImpl(); + } + + @Override + public synchronized InputStream toInputStream() { + return toInputStream(java.io.ByteArrayInputStream::new); + } + + @Override + public void write(final byte[] b, final int off, final int len) { + if (off < 0 || off > b.length || len < 0 || off + len > b.length || off + len < 0) { + throw new IndexOutOfBoundsException(); + } + if (len == 0) { + return; + } + synchronized (this) { + writeImpl(b, off, len); + } + } + + @Override + public synchronized int write(final InputStream in) throws IOException { + return writeImpl(in); + } + + @Override + public synchronized void write(final int b) { + writeImpl(b); + } + + @Override + public synchronized void writeTo(final OutputStream out) throws IOException { + writeToImpl(out); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java new file mode 100644 index 000000000..6adfeafe6 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Never writes data. Calls never go beyond this class. + * + *

This output stream has no destination (file/socket etc.) and all bytes written to it are + * ignored and lost. + */ +public class NullOutputStream extends OutputStream { + + /** + * The singleton instance. + * + * @since 2.12.0 + */ + public static final NullOutputStream INSTANCE = new NullOutputStream(); + + /** + * The singleton instance. + * + * @deprecated Use {@link #INSTANCE}. + */ + @Deprecated public static final NullOutputStream NULL_OUTPUT_STREAM = INSTANCE; + + /** + * Deprecated in favor of {@link #INSTANCE}. + * + *

TODO: Will be private in 3.0. + * + * @deprecated Use {@link #INSTANCE}. + */ + @Deprecated + public NullOutputStream() {} + + /** + * Does nothing - output to {@code /dev/null}. + * + * @param b The bytes to write + * @throws IOException never + */ + @Override + public void write(final byte[] b) throws IOException { + // To /dev/null + } + + /** + * Does nothing - output to {@code /dev/null}. + * + * @param b The bytes to write + * @param off The start offset + * @param len The number of bytes to write + */ + @Override + public void write(final byte[] b, final int off, final int len) { + // To /dev/null + } + + /** + * Does nothing - output to {@code /dev/null}. + * + * @param b The byte to write + */ + @Override + public void write(final int b) { + // To /dev/null + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java b/java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java new file mode 100644 index 000000000..ab5210a90 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.Serializable; +import java.io.Writer; + +/** + * {@link Writer} implementation that outputs to a {@link StringBuilder}. + * + *

NOTE: This implementation, as an alternative to {@code java.io.StringWriter}, + * provides an un-synchronized (i.e. for use in a single thread) implementation for better + * performance. For safe usage with multiple {@link Thread}s then {@code java.io.StringWriter} + * should be used. + * + *

Deprecating Serialization

+ * + *

Serialization is deprecated and will be removed in 3.0. + * + * @since 2.0 + */ +public class StringBuilderWriter extends Writer implements Serializable { + + private static final long serialVersionUID = -146927496096066153L; + private final StringBuilder builder; + + /** Constructs a new {@link StringBuilder} instance with default capacity. */ + public StringBuilderWriter() { + this.builder = new StringBuilder(); + } + + /** + * Constructs a new {@link StringBuilder} instance with the specified capacity. + * + * @param capacity The initial capacity of the underlying {@link StringBuilder} + */ + public StringBuilderWriter(final int capacity) { + this.builder = new StringBuilder(capacity); + } + + /** + * Constructs a new instance with the specified {@link StringBuilder}. + * + *

If {@code builder} is null a new instance with default capacity will be created. + * + * @param builder The String builder. May be null. + */ + public StringBuilderWriter(final StringBuilder builder) { + this.builder = builder != null ? builder : new StringBuilder(); + } + + /** + * Appends a single character to this Writer. + * + * @param value The character to append + * @return This writer instance + */ + @Override + public Writer append(final char value) { + builder.append(value); + return this; + } + + /** + * Appends a character sequence to this Writer. + * + * @param value The character to append + * @return This writer instance + */ + @Override + public Writer append(final CharSequence value) { + builder.append(value); + return this; + } + + /** + * Appends a portion of a character sequence to the {@link StringBuilder}. + * + * @param value The character to append + * @param start The index of the first character + * @param end The index of the last character + 1 + * @return This writer instance + */ + @Override + public Writer append(final CharSequence value, final int start, final int end) { + builder.append(value, start, end); + return this; + } + + /** Closing this writer has no effect. */ + @Override + public void close() { + // no-op + } + + /** Flushing this writer has no effect. */ + @Override + public void flush() { + // no-op + } + + /** + * Returns the underlying builder. + * + * @return The underlying builder + */ + public StringBuilder getBuilder() { + return builder; + } + + /** + * Returns {@link StringBuilder#toString()}. + * + * @return The contents of the String builder. + */ + @Override + public String toString() { + return builder.toString(); + } + + /** + * Writes a portion of a character array to the {@link StringBuilder}. + * + * @param value The value to write + * @param offset The index of the first character + * @param length The number of characters to write + */ + @Override + public void write(final char[] value, final int offset, final int length) { + if (value != null) { + builder.append(value, offset, length); + } + } + + /** + * Writes a String to the {@link StringBuilder}. + * + * @param value The value to write + */ + @Override + public void write(final String value) { + if (value != null) { + builder.append(value); + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java new file mode 100644 index 000000000..56e7c5b5a --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import org.apache.commons.io.function.IOConsumer; +import org.apache.commons.io.function.IOFunction; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * An output stream which triggers an event when a specified number of bytes of data have been + * written to it. The event can be used, for example, to throw an exception if a maximum has been + * reached, or to switch the underlying stream type when the threshold is exceeded. + * + *

This class overrides all {@link OutputStream} methods. However, these overrides ultimately + * call the corresponding methods in the underlying output stream implementation. + * + *

NOTE: This implementation may trigger the event before the threshold is actually + * reached, since it triggers when a pending write operation would cause the threshold to be + * exceeded. + */ +public class ThresholdingOutputStream extends OutputStream { + + /** Noop output stream getter function. */ + private static final IOFunction NOOP_OS_GETTER = + os -> NullOutputStream.INSTANCE; + + /** The threshold at which the event will be triggered. */ + private final int threshold; + + /** Accepts reaching the threshold. */ + private final IOConsumer thresholdConsumer; + + /** Gets the output stream. */ + private final IOFunction outputStreamGetter; + + /** The number of bytes written to the output stream. */ + private long written; + + /** Whether or not the configured threshold has been exceeded. */ + private boolean thresholdExceeded; + + /** + * Constructs an instance of this class which will trigger an event at the specified threshold. + * + * @param threshold The number of bytes at which to trigger an event. + */ + public ThresholdingOutputStream(final int threshold) { + this(threshold, IOConsumer.noop(), NOOP_OS_GETTER); + } + + /** + * Constructs an instance of this class which will trigger an event at the specified threshold. + * + * @param threshold The number of bytes at which to trigger an event. + * @param thresholdConsumer Accepts reaching the threshold. + * @param outputStreamGetter Gets the output stream. + * @since 2.9.0 + */ + public ThresholdingOutputStream( + final int threshold, + final IOConsumer thresholdConsumer, + final IOFunction outputStreamGetter) { + this.threshold = threshold; + this.thresholdConsumer = thresholdConsumer == null ? IOConsumer.noop() : thresholdConsumer; + this.outputStreamGetter = outputStreamGetter == null ? NOOP_OS_GETTER : outputStreamGetter; + } + + /** + * Checks to see if writing the specified number of bytes would cause the configured threshold to + * be exceeded. If so, triggers an event to allow a concrete implementation to take action on + * this. + * + * @param count The number of bytes about to be written to the underlying output stream. + * @throws IOException if an error occurs. + */ + protected void checkThreshold(final int count) throws IOException { + if (!thresholdExceeded && written + count > threshold) { + thresholdExceeded = true; + thresholdReached(); + } + } + + /** + * Closes this output stream and releases any system resources associated with this stream. + * + * @throws IOException if an error occurs. + */ + @Override + public void close() throws IOException { + try { + flush(); + } catch (final IOException ignored) { + // ignore + } + // TODO for 4.0: Replace with getOutputStream() + getStream().close(); + } + + /** + * Flushes this output stream and forces any buffered output bytes to be written out. + * + * @throws IOException if an error occurs. + */ + @SuppressWarnings("resource") // the underlying stream is managed by a subclass. + @Override + public void flush() throws IOException { + // TODO for 4.0: Replace with getOutputStream() + getStream().flush(); + } + + /** + * Gets the number of bytes that have been written to this output stream. + * + * @return The number of bytes written. + */ + public long getByteCount() { + return written; + } + + /** + * Gets the underlying output stream, to which the corresponding {@link OutputStream} methods in + * this class will ultimately delegate. + * + * @return The underlying output stream. + * @throws IOException if an error occurs. + * @deprecated Use {@link #getOutputStream()}. + */ + @Deprecated + protected OutputStream getStream() throws IOException { + return getOutputStream(); + } + + /** + * Gets the underlying output stream, to which the corresponding {@link OutputStream} methods in + * this class will ultimately delegate. + * + * @return The underlying output stream. + * @throws IOException if an error occurs. + * @since 2.14.0 + */ + protected OutputStream getOutputStream() throws IOException { + return outputStreamGetter.apply(this); + } + + /** + * Gets the threshold, in bytes, at which an event will be triggered. + * + * @return The threshold point, in bytes. + */ + public int getThreshold() { + return threshold; + } + + /** + * Tests whether or not the configured threshold has been exceeded for this output stream. + * + * @return {@code true} if the threshold has been reached; {@code false} otherwise. + */ + public boolean isThresholdExceeded() { + return written > threshold; + } + + /** + * Resets the byteCount to zero. You can call this from {@link #thresholdReached()} if you want + * the event to be triggered again. + */ + protected void resetByteCount() { + this.thresholdExceeded = false; + this.written = 0; + } + + /** + * Sets the byteCount to count. Useful for re-opening an output stream that has previously been + * written to. + * + * @param count The number of bytes that have already been written to the output stream + * @since 2.5 + */ + protected void setByteCount(final long count) { + this.written = count; + } + + /** + * Indicates that the configured threshold has been reached, and that a subclass should take + * whatever action necessary on this event. This may include changing the underlying output + * stream. + * + * @throws IOException if an error occurs. + */ + protected void thresholdReached() throws IOException { + thresholdConsumer.accept(this); + } + + /** + * Writes {@code b.length} bytes from the specified byte array to this output stream. + * + * @param b The array of bytes to be written. + * @throws IOException if an error occurs. + */ + @SuppressWarnings("resource") // the underlying stream is managed by a subclass. + @Override + public void write(final byte[] b) throws IOException { + checkThreshold(b.length); + // TODO for 4.0: Replace with getOutputStream() + getStream().write(b); + written += b.length; + } + + /** + * Writes {@code len} bytes from the specified byte array starting at offset {@code off} to this + * output stream. + * + * @param b The byte array from which the data will be written. + * @param off The start offset in the byte array. + * @param len The number of bytes to write. + * @throws IOException if an error occurs. + */ + @SuppressWarnings("resource") // the underlying stream is managed by a subclass. + @Override + public void write(final byte[] b, final int off, final int len) throws IOException { + checkThreshold(len); + // TODO for 4.0: Replace with getOutputStream() + getStream().write(b, off, len); + written += len; + } + + /** + * Writes the specified byte to this output stream. + * + * @param b The byte to be written. + * @throws IOException if an error occurs. + */ + @SuppressWarnings("resource") // the underlying stream is managed by a subclass. + @Override + public void write(final int b) throws IOException { + checkThreshold(1); + // TODO for 4.0: Replace with getOutputStream() + getStream().write(b); + written++; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java new file mode 100644 index 000000000..56afbc6ab --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import org.apache.commons.io.build.AbstractOrigin; +import org.apache.commons.io.build.AbstractStreamBuilder; +import org.apache.commons.io.function.Uncheck; +import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Implements a version of {@link AbstractByteArrayOutputStream} without any concurrent + * thread safety. + * + *

To build an instance, see {@link Builder}. + * + * @since 2.7 + */ +// @NotThreadSafe +public final class UnsynchronizedByteArrayOutputStream extends AbstractByteArrayOutputStream { + + /** + * Builds a new {@link UnsynchronizedByteArrayOutputStream} instance. + * + *

Using File IO: + * + *

{@code
+   * UnsynchronizedByteArrayOutputStream s = UnsynchronizedByteArrayOutputStream.builder()
+   *   .setBufferSize(8192)
+   *   .get();
+   * }
+ * + *

Using NIO Path: + * + *

{@code
+   * UnsynchronizedByteArrayOutputStream s = UnsynchronizedByteArrayOutputStream.builder()
+   *   .setBufferSize(8192)
+   *   .get();
+   * }
+ */ + public static class Builder + extends AbstractStreamBuilder { + + /** + * Constructs a new instance. + * + *

This builder use the aspect buffer size. + * + * @return a new instance. + * @see AbstractOrigin#getByteArray() + */ + @Override + public UnsynchronizedByteArrayOutputStream get() { + return new UnsynchronizedByteArrayOutputStream(getBufferSize()); + } + } + + /** + * Constructs a new {@link Builder}. + * + * @return a new {@link Builder}. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Fetches entire contents of an {@link InputStream} and represent same data as result + * InputStream. + * + *

This method is useful where, + * + *

    + *
  • Source InputStream is slow. + *
  • It has network resources associated, so we cannot keep it open for long time. + *
  • It has network timeout associated. + *
+ * + * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and + * copy of byte[].
+ * This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input Stream to be fully buffered. + * @return A fully buffered stream. + * @throws IOException if an I/O error occurs. + */ + public static InputStream toBufferedInputStream(final InputStream input) throws IOException { + return toBufferedInputStream(input, DEFAULT_SIZE); + } + + /** + * Fetches entire contents of an {@link InputStream} and represent same data as result + * InputStream. + * + *

This method is useful where, + * + *

    + *
  • Source InputStream is slow. + *
  • It has network resources associated, so we cannot keep it open for long time. + *
  • It has network timeout associated. + *
+ * + * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and + * copy of byte[].
+ * This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input Stream to be fully buffered. + * @param size the initial buffer size + * @return A fully buffered stream. + * @throws IOException if an I/O error occurs. + */ + public static InputStream toBufferedInputStream(final InputStream input, final int size) + throws IOException { + // It does not matter if a ByteArrayOutputStream is not closed as close() is a no-op + try (UnsynchronizedByteArrayOutputStream output = builder().setBufferSize(size).get()) { + output.write(input); + return output.toInputStream(); + } + } + + /** + * Constructs a new byte array output stream. The buffer capacity is initially + * + *

{@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if + * necessary. + * + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. + */ + @Deprecated + public UnsynchronizedByteArrayOutputStream() { + this(DEFAULT_SIZE); + } + + /** + * Constructs a new byte array output stream, with a buffer capacity of the specified size, in + * bytes. + * + * @param size the initial size + * @throws IllegalArgumentException if size is negative + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. Will be private + * in 3.0.0. + */ + @Deprecated + public UnsynchronizedByteArrayOutputStream(final int size) { + if (size < 0) { + throw new IllegalArgumentException("Negative initial size: " + size); + } + needNewBuffer(size); + } + + /** + * @see java.io.ByteArrayOutputStream#reset() + */ + @Override + public void reset() { + resetImpl(); + } + + @Override + public int size() { + return count; + } + + @Override + public byte[] toByteArray() { + return toByteArrayImpl(); + } + + @Override + public InputStream toInputStream() { + // @formatter:off + return toInputStream( + (buffer, offset, length) -> + Uncheck.get( + () -> + UnsynchronizedByteArrayInputStream.builder() + .setByteArray(buffer) + .setOffset(offset) + .setLength(length) + .get())); + // @formatter:on + } + + @Override + public void write(final byte[] b, final int off, final int len) { + if (off < 0 || off > b.length || len < 0 || off + len > b.length || off + len < 0) { + throw new IndexOutOfBoundsException(String.format("offset=%,d, length=%,d", off, len)); + } + if (len == 0) { + return; + } + writeImpl(b, off, len); + } + + @Override + public int write(final InputStream in) throws IOException { + return writeImpl(in); + } + + @Override + public void write(final int b) { + writeImpl(b); + } + + @Override + public void writeTo(final OutputStream out) throws IOException { + writeToImpl(out); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java b/java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java new file mode 100644 index 000000000..02b624f6d --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java @@ -0,0 +1,479 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.build.AbstractStreamBuilder; +import org.apache.commons.io.charset.CharsetDecoders; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; + +/** + * {@link OutputStream} implementation that transforms a byte stream to a character stream using a + * specified charset encoding and writes the resulting stream to a {@link Writer}. The stream is + * transformed using a {@link CharsetDecoder} object, guaranteeing that all charset encodings + * supported by the JRE are handled correctly. + * + *

The output of the {@link CharsetDecoder} is buffered using a fixed size buffer. This implies + * that the data is written to the underlying {@link Writer} in chunks that are no larger than the + * size of this buffer. By default, the buffer is flushed only when it overflows or when {@link + * #flush()} or {@link #close()} is called. In general there is therefore no need to wrap the + * underlying {@link Writer} in a {@link java.io.BufferedWriter}. {@link WriterOutputStream} can + * also be instructed to flush the buffer after each write operation. In this case, all available + * data is written immediately to the underlying {@link Writer}, implying that the current position + * of the {@link Writer} is correlated to the current position of the {@link WriterOutputStream}. + * + *

{@link WriterOutputStream} implements the inverse transformation of {@link + * java.io.OutputStreamWriter}; in the following example, writing to {@code out2} would have the + * same result as writing to {@code out} directly (provided that the byte sequence is legal with + * respect to the charset encoding): + * + *

To build an instance, see {@link Builder}. + * + *

+ * OutputStream out = ...
+ * Charset cs = ...
+ * OutputStreamWriter writer = new OutputStreamWriter(out, cs);
+ * WriterOutputStream out2 = WriterOutputStream.builder()
+ *   .setWriter(writer)
+ *   .setCharset(cs)
+ *   .get();
+ * 
+ * + *

{@link WriterOutputStream} implements the same transformation as {@link + * java.io.InputStreamReader}, except that the control flow is reversed: both classes transform a + * byte stream into a character stream, but {@link java.io.InputStreamReader} pulls data from the + * underlying stream, while {@link WriterOutputStream} pushes it to the underlying stream. + * + *

Note that while there are use cases where there is no alternative to using this class, very + * often the need to use this class is an indication of a flaw in the design of the code. This class + * is typically used in situations where an existing API only accepts an {@link OutputStream} + * object, but where the stream is known to represent character data that must be decoded for + * further use. + * + *

Instances of {@link WriterOutputStream} are not thread safe. + * + * @see org.apache.commons.io.input.ReaderInputStream + * @since 2.0 + */ +public class WriterOutputStream extends OutputStream { + + /** + * Builds a new {@link WriterOutputStream} instance. + * + *

For example: + * + *

{@code
+   * WriterOutputStream s = WriterOutputStream.builder()
+   *   .setPath(path)
+   *   .setBufferSize(8192)
+   *   .setCharset(StandardCharsets.UTF_8)
+   *   .setWriteImmediately(false)
+   *   .get();
+   * }
+ * + * @since 2.12.0 + */ + public static class Builder extends AbstractStreamBuilder { + + private CharsetDecoder charsetDecoder; + private boolean writeImmediately; + + public Builder() { + this.charsetDecoder = getCharset().newDecoder(); + } + + /** + * Constructs a new instance. + * + *

This builder use the aspect Writer, OpenOption[], Charset, CharsetDecoder, buffer size and + * writeImmediately. + * + *

You must provide an origin that can be converted to a Writer by this builder, otherwise, + * this call will throw an {@link UnsupportedOperationException}. + * + * @return a new instance. + * @throws UnsupportedOperationException if the origin cannot provide a Writer. + * @see #getWriter() + */ + @SuppressWarnings("resource") + @Override + public WriterOutputStream get() throws IOException { + return new WriterOutputStream(getWriter(), charsetDecoder, getBufferSize(), writeImmediately); + } + + @Override + public Builder setCharset(final Charset charset) { + super.setCharset(charset); + this.charsetDecoder = getCharset().newDecoder(); + return this; + } + + @Override + public Builder setCharset(final String charset) { + super.setCharset(charset); + this.charsetDecoder = getCharset().newDecoder(); + return this; + } + + /** + * Sets the charset decoder. + * + * @param charsetDecoder the charset decoder. + * @return this + */ + public Builder setCharsetDecoder(final CharsetDecoder charsetDecoder) { + this.charsetDecoder = + charsetDecoder != null ? charsetDecoder : getCharsetDefault().newDecoder(); + super.setCharset(this.charsetDecoder.charset()); + return this; + } + + /** + * Sets whether the output buffer will be flushed after each write operation ({@code true}), + * i.e. all available data will be written to the underlying {@link Writer} immediately. If + * {@code false}, the output buffer will only be flushed when it overflows or when {@link + * #flush()} or {@link #close()} is called. + * + * @param writeImmediately If {@code true} the output buffer will be flushed after each write + * operation, i.e. all available data will be written to the underlying {@link Writer} + * immediately. If {@code false}, the output buffer will only be flushed when it overflows + * or when {@link #flush()} or {@link #close()} is called. + * @return this + */ + public Builder setWriteImmediately(final boolean writeImmediately) { + this.writeImmediately = writeImmediately; + return this; + } + } + + private static final int BUFFER_SIZE = IOUtils.DEFAULT_BUFFER_SIZE; + + /** + * Constructs a new {@link Builder}. + * + * @return a new {@link Builder}. + * @since 2.12.0 + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Checks if the JDK in use properly supports the given charset. + * + * @param charset the charset to check the support for + */ + private static void checkIbmJdkWithBrokenUTF16(final Charset charset) { + if (!StandardCharsets.UTF_16.name().equals(charset.name())) { + return; + } + final String TEST_STRING_2 = "v\u00e9s"; + final byte[] bytes = TEST_STRING_2.getBytes(charset); + + final CharsetDecoder charsetDecoder2 = charset.newDecoder(); + final ByteBuffer bb2 = ByteBuffer.allocate(16); + final CharBuffer cb2 = CharBuffer.allocate(TEST_STRING_2.length()); + final int len = bytes.length; + for (int i = 0; i < len; i++) { + bb2.put(bytes[i]); + bb2.flip(); + try { + charsetDecoder2.decode(bb2, cb2, i == len - 1); + } catch (final IllegalArgumentException e) { + throw new UnsupportedOperationException( + "UTF-16 requested when running on an IBM JDK with broken UTF-16 support. " + + "Please find a JDK that supports UTF-16 if you intend to use UF-16 with WriterOutputStream"); + } + bb2.compact(); + } + cb2.rewind(); + if (!TEST_STRING_2.equals(cb2.toString())) { + throw new UnsupportedOperationException( + "UTF-16 requested when running on an IBM JDK with broken UTF-16 support. " + + "Please find a JDK that supports UTF-16 if you intend to use UF-16 with WriterOutputStream"); + } + } + + private final Writer writer; + private final CharsetDecoder decoder; + + private final boolean writeImmediately; + + /** + * ByteBuffer used as input for the decoder. This buffer can be small as it is used only to + * transfer the received data to the decoder. + */ + private final ByteBuffer decoderIn = ByteBuffer.allocate(128); + + /** + * CharBuffer used as output for the decoder. It should be somewhat larger as we write from this + * buffer to the underlying Writer. + */ + private final CharBuffer decoderOut; + + /** + * Constructs a new {@link WriterOutputStream} that uses the default character encoding and with a + * default output buffer size of {@value #BUFFER_SIZE} characters. The output buffer will only be + * flushed when it overflows or when {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream(final Writer writer) { + this(writer, Charset.defaultCharset(), BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream} with a default output buffer size of {@value + * #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @param charset the charset encoding + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream(final Writer writer, final Charset charset) { + this(writer, charset, BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream}. + * + * @param writer the target {@link Writer} + * @param charset the charset encoding + * @param bufferSize the size of the output buffer in number of characters + * @param writeImmediately If {@code true} the output buffer will be flushed after each write + * operation, i.e. all available data will be written to the underlying {@link Writer} + * immediately. If {@code false}, the output buffer will only be flushed when it overflows or + * when {@link #flush()} or {@link #close()} is called. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream( + final Writer writer, + final Charset charset, + final int bufferSize, + final boolean writeImmediately) { + // @formatter:off + this( + writer, + Charsets.toCharset(charset) + .newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .replaceWith("?"), + bufferSize, + writeImmediately); + // @formatter:on + } + + /** + * Constructs a new {@link WriterOutputStream} with a default output buffer size of {@value + * #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @param decoder the charset decoder + * @since 2.1 + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream(final Writer writer, final CharsetDecoder decoder) { + this(writer, decoder, BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream}. + * + * @param writer the target {@link Writer} + * @param decoder the charset decoder + * @param bufferSize the size of the output buffer in number of characters + * @param writeImmediately If {@code true} the output buffer will be flushed after each write + * operation, i.e. all available data will be written to the underlying {@link Writer} + * immediately. If {@code false}, the output buffer will only be flushed when it overflows or + * when {@link #flush()} or {@link #close()} is called. + * @since 2.1 + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream( + final Writer writer, + final CharsetDecoder decoder, + final int bufferSize, + final boolean writeImmediately) { + checkIbmJdkWithBrokenUTF16(CharsetDecoders.toCharsetDecoder(decoder).charset()); + this.writer = writer; + this.decoder = CharsetDecoders.toCharsetDecoder(decoder); + this.writeImmediately = writeImmediately; + this.decoderOut = CharBuffer.allocate(bufferSize); + } + + /** + * Constructs a new {@link WriterOutputStream} with a default output buffer size of {@value + * #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @param charsetName the name of the charset encoding + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream(final Writer writer, final String charsetName) { + this(writer, charsetName, BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream}. + * + * @param writer the target {@link Writer} + * @param charsetName the name of the charset encoding + * @param bufferSize the size of the output buffer in number of characters + * @param writeImmediately If {@code true} the output buffer will be flushed after each write + * operation, i.e. all available data will be written to the underlying {@link Writer} + * immediately. If {@code false}, the output buffer will only be flushed when it overflows or + * when {@link #flush()} or {@link #close()} is called. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + */ + @Deprecated + public WriterOutputStream( + final Writer writer, + final String charsetName, + final int bufferSize, + final boolean writeImmediately) { + this(writer, Charsets.toCharset(charsetName), bufferSize, writeImmediately); + } + + /** + * Close the stream. Any remaining content accumulated in the output buffer will be written to the + * underlying {@link Writer}. After that {@link Writer#close()} will be called. + * + * @throws IOException if an I/O error occurs. + */ + @Override + public void close() throws IOException { + processInput(true); + flushOutput(); + writer.close(); + } + + /** + * Flush the stream. Any remaining content accumulated in the output buffer will be written to the + * underlying {@link Writer}. After that {@link Writer#flush()} will be called. + * + * @throws IOException if an I/O error occurs. + */ + @Override + public void flush() throws IOException { + flushOutput(); + writer.flush(); + } + + /** + * Flush the output. + * + * @throws IOException if an I/O error occurs. + */ + private void flushOutput() throws IOException { + if (decoderOut.position() > 0) { + writer.write(decoderOut.array(), 0, decoderOut.position()); + decoderOut.rewind(); + } + } + + /** + * Decode the contents of the input ByteBuffer into a CharBuffer. + * + * @param endOfInput indicates end of input + * @throws IOException if an I/O error occurs. + */ + private void processInput(final boolean endOfInput) throws IOException { + // Prepare decoderIn for reading + decoderIn.flip(); + CoderResult coderResult; + while (true) { + coderResult = decoder.decode(decoderIn, decoderOut, endOfInput); + if (coderResult.isOverflow()) { + flushOutput(); + } else if (coderResult.isUnderflow()) { + break; + } else { + // The decoder is configured to replace malformed input and unmappable characters, + // so we should not get here. + throw new IOException("Unexpected coder result"); + } + } + // Discard the bytes that have been read + decoderIn.compact(); + } + + /** + * Write bytes from the specified byte array to the stream. + * + * @param b the byte array containing the bytes to write + * @throws IOException if an I/O error occurs. + */ + @Override + public void write(final byte[] b) throws IOException { + write(b, 0, b.length); + } + + /** + * Write bytes from the specified byte array to the stream. + * + * @param b the byte array containing the bytes to write + * @param off the start offset in the byte array + * @param len the number of bytes to write + * @throws IOException if an I/O error occurs. + */ + @Override + public void write(final byte[] b, int off, int len) throws IOException { + while (len > 0) { + final int c = Math.min(len, decoderIn.remaining()); + decoderIn.put(b, off, c); + processInput(false); + len -= c; + off += c; + } + if (writeImmediately) { + flushOutput(); + } + } + + /** + * Write a single byte to the stream. + * + * @param b the byte to write + * @throws IOException if an I/O error occurs. + */ + @Override + public void write(final int b) throws IOException { + write(new byte[] {(byte) b}, 0, 1); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java b/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java new file mode 100644 index 000000000..f45168c94 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.commons.lang3; + +import java.util.Arrays; + +public class ArrayFill { + /** + * Fills and returns the given array, assigning the given {@code char} value to each element of + * the array. + * + * @param a the array to be filled (may be null). + * @param val the value to be stored in all elements of the array. + * @return the given array. + * @see Arrays#fill(char[],char) + */ + public static char[] fill(final char[] a, final char val) { + if (a != null) { + Arrays.fill(a, val); + } + return a; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java new file mode 100644 index 000000000..d787649bd --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java @@ -0,0 +1,355 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.commons.lang3; + +import java.lang.reflect.Array; +import java.util.function.Supplier; + +public class ArrayUtils { + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** An empty immutable {@code long} array. */ + public static final long[] EMPTY_LONG_ARRAY = {}; + + public static final String[] EMPTY_STRING_ARRAY = {}; + + /** + * Converts an array of object Longs to primitives. + * + *

This method returns {@code null} for a {@code null} input array. + * + * @param array a {@link Long} array, may be {@code null} + * @return a {@code long} array, {@code null} if null array input + * @throws NullPointerException if an array element is {@code null} + */ + public static long[] toPrimitive(final Long[] array) { + if (array == null) { + return null; + } + if (array.length == 0) { + return EMPTY_LONG_ARRAY; + } + final long[] result = new long[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i]; + } + return result; + } + + /** + * Removes the element at the specified position from the specified array. All subsequent elements + * are shifted to the left (subtracts one from their indices). + * + *

This method returns a new array with the same elements of the input array except the element + * on the specified position. The component type of the returned array is always the same as that + * of the input array. + * + *

If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in + * that case no valid index can be specified. + * + *

+   * ArrayUtils.remove(["a"], 0)           = []
+   * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
+   * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
+   * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
+   * 
+ * + * @param the component type of the array + * @param array the array to remove the element from, may not be {@code null} + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element at the specified + * position. + * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= + * array.length), or if the array is {@code null}. + * @since 2.1 + */ + @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input + public static T[] remove(final T[] array, final int index) { + return (T[]) remove((Object) array, index); + } + + /** + * Removes the element at the specified position from the specified array. All subsequent elements + * are shifted to the left (subtracts one from their indices). + * + *

This method returns a new array with the same elements of the input array except the element + * on the specified position. The component type of the returned array is always the same as that + * of the input array. + * + *

If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in + * that case no valid index can be specified. + * + * @param array the array to remove the element from, may not be {@code null} + * @param index the position of the element to be removed + * @return A new array containing the existing elements except the element at the specified + * position. + * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= + * array.length), or if the array is {@code null}. + * @since 2.1 + */ + private static Object remove(final Object array, final int index) { + final int length = getLength(array); + if (index < 0 || index >= length) { + throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length); + } + final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1); + System.arraycopy(array, 0, result, 0, index); + if (index < length - 1) { + System.arraycopy(array, index + 1, result, index, length - index - 1); + } + return result; + } + + /** + * Gets the length of the specified array. This method can deal with {@link Object} arrays and + * with primitive arrays. + * + *

If the input array is {@code null}, {@code 0} is returned. + * + *

+   * ArrayUtils.getLength(null)            = 0
+   * ArrayUtils.getLength([])              = 0
+   * ArrayUtils.getLength([null])          = 1
+   * ArrayUtils.getLength([true, false])   = 2
+   * ArrayUtils.getLength([1, 2, 3])       = 3
+   * ArrayUtils.getLength(["a", "b", "c"]) = 3
+   * 
+ * + * @param array the array to retrieve the length from, may be {@code null}. + * @return The length of the array, or {@code 0} if the array is {@code null} + * @throws IllegalArgumentException if the object argument is not an array. + * @since 2.1 + */ + public static int getLength(final Object array) { + return array != null ? Array.getLength(array) : 0; + } + + /** + * Reverses the order of the given array. + * + *

This method does nothing for a {@code null} input array. + * + * @param array the array to reverse, may be {@code null}. + */ + public static void reverse(final int[] array) { + if (array != null) { + reverse(array, 0, array.length); + } + } + + /** + * Reverses the order of the given array in the given range. + * + *

This method does nothing for a {@code null} input array. + * + * @param array the array to reverse, may be {@code null}. + * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue + * (>array.length) results in no change. + * @param endIndexExclusive elements up to endIndex-1 are reversed in the array. Undervalue (< + * start index) results in no change. Overvalue (>array.length) is demoted to array length. + * @since 3.2 + */ + public static void reverse( + final int[] array, final int startIndexInclusive, final int endIndexExclusive) { + if (array == null) { + return; + } + int i = Math.max(startIndexInclusive, 0); + int j = Math.min(array.length, endIndexExclusive) - 1; + int tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + } + + /** + * Tests whether an array of Objects is empty or {@code null}. + * + * @param array the array to test + * @return {@code true} if the array is empty or {@code null} + * @since 2.1 + */ + public static boolean isEmpty(final Object[] array) { + return isArrayEmpty(array); + } + + /** + * Checks if an array is empty or {@code null}. + * + * @param array the array to test + * @return {@code true} if the array is empty or {@code null} + */ + private static boolean isArrayEmpty(final Object array) { + return getLength(array) == 0; + } + + /** + * Adds all the elements of the given arrays into a new array. + * + *

The new array contains all of the element of {@code array1} followed by all of the elements + * {@code array2}. When an array is returned, it is always a new array. + * + *

+   * ArrayUtils.addAll(null, null)     = null
+   * ArrayUtils.addAll(array1, null)   = cloned copy of array1
+   * ArrayUtils.addAll(null, array2)   = cloned copy of array2
+   * ArrayUtils.addAll([], [])         = []
+   * ArrayUtils.addAll(null, null)     = null
+   * ArrayUtils.addAll([null], [null]) = [null, null]
+   * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
+   * 
+ * + * @param the component type of the array + * @param array1 the first array whose elements are added to the new array, may be {@code null} + * @param array2 the second array whose elements are added to the new array, may be {@code null} + * @return The new array, {@code null} if both arrays are {@code null}. The type of the new array + * is the type of the first array, unless the first array is null, in which case the type is + * the same as the second array. + * @throws IllegalArgumentException if the array types are incompatible + * @since 2.1 + */ + public static T[] addAll(final T[] array1, @SuppressWarnings("unchecked") final T... array2) { + if (array1 == null) { + return clone(array2); + } + if (array2 == null) { + return clone(array1); + } + final Class type1 = getComponentType(array1); + final T[] joinedArray = + arraycopy( + array1, 0, 0, array1.length, () -> newInstance(type1, array1.length + array2.length)); + try { + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + } catch (final ArrayStoreException ase) { + // Check if problem was due to incompatible types + /* + * We do this here, rather than before the copy because: - it would be a wasted check most of the time - safer, in case check turns out to be too + * strict + */ + final Class type2 = array2.getClass().getComponentType(); + if (!type1.isAssignableFrom(type2)) { + throw new IllegalArgumentException( + "Cannot store " + type2.getName() + " in an array of " + type1.getName(), ase); + } + throw ase; // No, so rethrow original + } + return joinedArray; + } + + /** + * Shallow clones an array or returns {@code null}. + * + *

The objects in the array are not cloned, thus there is no special handling for + * multi-dimensional arrays. + * + *

This method returns {@code null} for a {@code null} input array. + * + * @param the component type of the array + * @param array the array to shallow clone, may be {@code null} + * @return the cloned array, {@code null} if {@code null} input + */ + public static T[] clone(final T[] array) { + return array != null ? array.clone() : null; + } + + /** + * Gets an array's component type. + * + * @param The array type. + * @param array The array. + * @return The component type. + * @since 3.13.0 + */ + public static Class getComponentType(final T[] array) { + return ClassUtils.getComponentType(ObjectUtils.getClass(array)); + } + + /** + * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the + * destination array. + * + * @param the type. + * @param source the source array. + * @param sourcePos starting position in the source array. + * @param destPos starting position in the destination data. + * @param length the number of array elements to be copied. + * @param allocator allocates the array to populate and return. + * @return dest + * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. + * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the + * {@code dest} array because of a type mismatch. + * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}. + * @since 3.15.0 + */ + public static T arraycopy( + final T source, + final int sourcePos, + final int destPos, + final int length, + final Supplier allocator) { + return arraycopy(source, sourcePos, allocator.get(), destPos, length); + } + + /** + * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the + * destination array. + * + * @param the type + * @param source the source array. + * @param sourcePos starting position in the source array. + * @param dest the destination array. + * @param destPos starting position in the destination data. + * @param length the number of array elements to be copied. + * @return dest + * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. + * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the + * {@code dest} array because of a type mismatch. + * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}. + * @since 3.15.0 + */ + public static T arraycopy( + final T source, final int sourcePos, final T dest, final int destPos, final int length) { + System.arraycopy(source, sourcePos, dest, destPos, length); + return dest; + } + + /** + * Delegates to {@link Array#newInstance(Class,int)} using generics. + * + * @param The array type. + * @param componentType The array class. + * @param length the array length + * @return The new array. + * @throws NullPointerException if the specified {@code componentType} parameter is null. + * @since 3.13.0 + */ + @SuppressWarnings("unchecked") // OK, because array and values are of type T + public static T[] newInstance(final Class componentType, final int length) { + return (T[]) Array.newInstance(componentType, length); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java new file mode 100644 index 000000000..9d1d5332e --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +public class CharSequenceUtils { + + private static final int NOT_FOUND = -1; + + /** + * Returns the index within {@code cs} of the first occurrence of the specified character, + * starting the search at the specified index. + * + *

If a character with value {@code searchChar} occurs in the character sequence represented by + * the {@code cs} object at an index no smaller than {@code start}, then the index of the first + * such occurrence is returned. For values of {@code searchChar} in the range from 0 to 0xFFFF + * (inclusive), this is the smallest value k such that: + * + *

+ * + *
+   * (this.charAt(k) == searchChar) && (k >= start)
+   * 
+ * + *
+ * + * is true. For other values of {@code searchChar}, it is the smallest value k such that: + * + *
+ * + *
+   * (this.codePointAt(k) == searchChar) && (k >= start)
+   * 
+ * + *
+ * + *

is true. In either case, if no such character occurs inm {@code cs} at or after position + * {@code start}, then {@code -1} is returned. + * + *

There is no restriction on the value of {@code start}. If it is negative, it has the same + * effect as if it were zero: the entire {@link CharSequence} may be searched. If it is greater + * than the length of {@code cs}, it has the same effect as if it were equal to the length of + * {@code cs}: {@code -1} is returned. + * + *

All indices are specified in {@code char} values (Unicode code units). + * + * @param cs the {@link CharSequence} to be processed, not null + * @param searchChar the char to be searched for + * @param start the start index, negative starts at the string start + * @return the index where the search char was found, -1 if not found + * @since 3.6 updated to behave more like {@link String} + */ + static int indexOf(final CharSequence cs, final int searchChar, int start) { + if (cs instanceof String) { + return ((String) cs).indexOf(searchChar, start); + } + final int sz = cs.length(); + if (start < 0) { + start = 0; + } + if (searchChar < Character.MIN_SUPPLEMENTARY_CODE_POINT) { + for (int i = start; i < sz; i++) { + if (cs.charAt(i) == searchChar) { + return i; + } + } + return NOT_FOUND; + } + // supplementary characters (LANG1300) + if (searchChar <= Character.MAX_CODE_POINT) { + final char[] chars = Character.toChars(searchChar); + for (int i = start; i < sz - 1; i++) { + final char high = cs.charAt(i); + final char low = cs.charAt(i + 1); + if (high == chars[0] && low == chars[1]) { + return i; + } + } + } + return NOT_FOUND; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Green implementation of regionMatches. + * + * @param cs the {@link CharSequence} to be processed + * @param ignoreCase whether or not to be case-insensitive + * @param thisStart the index to start on the {@code cs} CharSequence + * @param substring the {@link CharSequence} to be looked for + * @param start the index to start on the {@code substring} CharSequence + * @param length character length of the region + * @return whether the region matched + * @see String#regionMatches(boolean, int, String, int, int) + */ + static boolean regionMatches( + final CharSequence cs, + final boolean ignoreCase, + final int thisStart, + final CharSequence substring, + final int start, + final int length) { + if (cs instanceof String && substring instanceof String) { + return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); + } + int index1 = thisStart; + int index2 = start; + int tmpLen = length; + + // Extract these first so we detect NPEs the same as the java.lang.String version + final int srcLen = cs.length() - thisStart; + final int otherLen = substring.length() - start; + + // Check for invalid parameters + if (thisStart < 0 || start < 0 || length < 0) { + return false; + } + + // Check that the regions are long enough + if (srcLen < length || otherLen < length) { + return false; + } + + while (tmpLen-- > 0) { + final char c1 = cs.charAt(index1++); + final char c2 = substring.charAt(index2++); + + if (c1 == c2) { + continue; + } + + if (!ignoreCase) { + return false; + } + + // The real same check as in String#regionMatches(boolean, int, String, int, int): + final char u1 = Character.toUpperCase(c1); + final char u2 = Character.toUpperCase(c2); + if (u1 != u2 && Character.toLowerCase(u1) != Character.toLowerCase(u2)) { + return false; + } + } + + return true; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java new file mode 100644 index 000000000..63663f99f --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +public class ClassUtils { + /** + * Delegates to {@link Class#getComponentType()} using generics. + * + * @param The array class type. + * @param cls A class or null. + * @return The array component type or null. + * @see Class#getComponentType() + * @since 3.13.0 + */ + @SuppressWarnings("unchecked") + public static Class getComponentType(final Class cls) { + return cls == null ? null : (Class) cls.getComponentType(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java b/java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java new file mode 100644 index 000000000..2eb8bfef0 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.lang3; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Thrown to indicate that a block of code has not been implemented. This exception supplements + * {@link UnsupportedOperationException} by providing a more semantically rich description of the + * problem. + * + *

{@link NotImplementedException} represents the case where the author has yet to implement the + * logic at this point in the program. This can act as an exception based TODO tag. + * + *

+ * public void foo() {
+ *   try {
+ *     // do something that throws an Exception
+ *   } catch (Exception ex) {
+ *     // don't know what to do here yet
+ *     throw new NotImplementedException("TODO", ex);
+ *   }
+ * }
+ * 
+ * + * This class was originally added in Lang 2.0, but removed in 3.0. + * + * @since 3.2 + */ +public class NotImplementedException extends UnsupportedOperationException { + + private static final long serialVersionUID = 20131021L; + + /** A resource for more information regarding the lack of implementation. */ + private final String code; + + /** + * Constructs a NotImplementedException. + * + * @since 3.10 + */ + public NotImplementedException() { + this.code = null; + } + + /** + * Constructs a NotImplementedException. + * + * @param message description of the exception + * @since 3.2 + */ + public NotImplementedException(final String message) { + this(message, (String) null); + } + + /** + * Constructs a NotImplementedException. + * + * @param message description of the exception + * @param code code indicating a resource for more information regarding the lack of + * implementation + * @since 3.2 + */ + public NotImplementedException(final String message, final String code) { + super(message); + this.code = code; + } + + /** + * Constructs a NotImplementedException. + * + * @param message description of the exception + * @param cause cause of the exception + * @since 3.2 + */ + public NotImplementedException(final String message, final Throwable cause) { + this(message, cause, null); + } + + /** + * Constructs a NotImplementedException. + * + * @param message description of the exception + * @param cause cause of the exception + * @param code code indicating a resource for more information regarding the lack of + * implementation + * @since 3.2 + */ + public NotImplementedException(final String message, final Throwable cause, final String code) { + super(message, cause); + this.code = code; + } + + /** + * Constructs a NotImplementedException. + * + * @param cause cause of the exception + * @since 3.2 + */ + public NotImplementedException(final Throwable cause) { + this(cause, null); + } + + /** + * Constructs a NotImplementedException. + * + * @param cause cause of the exception + * @param code code indicating a resource for more information regarding the lack of + * implementation + * @since 3.2 + */ + public NotImplementedException(final Throwable cause, final String code) { + super(cause); + this.code = code; + } + + /** + * Obtain the not implemented code. This is an unformatted piece of text intended to point to + * further information regarding the lack of implementation. It might, for example, be an issue + * tracker ID or a URL. + * + * @return a code indicating a resource for more information regarding the lack of implementation + */ + public String getCode() { + return this.code; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java new file mode 100644 index 000000000..58c04fe98 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +public class ObjectUtils { + /** + * Delegates to {@link Object#getClass()} using generics. + * + * @param The argument type or null. + * @param object The argument. + * @return The argument's Class or null. + * @since 3.13.0 + */ + @SuppressWarnings("unchecked") + public static Class getClass(final T object) { + return object == null ? null : (Class) object.getClass(); + } + + /** + * Tests if an Object is not empty and not null. + * + *

The following types are supported: + * + *

    + *
  • {@link CharSequence}: Considered empty if its length is zero. + *
  • {@link Array}: Considered empty if its length is zero. + *
  • {@link Collection}: Considered empty if it has zero elements. + *
  • {@link Map}: Considered empty if it has zero key-value mappings. + *
  • {@link Optional}: Considered empty if {@link Optional#isPresent} returns false, + * regardless of the "emptiness" of the contents. + *
+ * + *
+   * ObjectUtils.isNotEmpty(null)             = false
+   * ObjectUtils.isNotEmpty("")               = false
+   * ObjectUtils.isNotEmpty("ab")             = true
+   * ObjectUtils.isNotEmpty(new int[]{})      = false
+   * ObjectUtils.isNotEmpty(new int[]{1,2,3}) = true
+   * ObjectUtils.isNotEmpty(1234)             = true
+   * ObjectUtils.isNotEmpty(Optional.of(""))  = true
+   * ObjectUtils.isNotEmpty(Optional.empty()) = false
+   * 
+ * + * @param object the {@link Object} to test, may be {@code null} + * @return {@code true} if the object has an unsupported type or is not empty and not null, {@code + * false} otherwise + * @since 3.9 + */ + public static boolean isNotEmpty(final Object object) { + return !isEmpty(object); + } + + /** + * Tests if an Object is empty or null. + * + *

The following types are supported: + * + *

    + *
  • {@link CharSequence}: Considered empty if its length is zero. + *
  • {@link Array}: Considered empty if its length is zero. + *
  • {@link Collection}: Considered empty if it has zero elements. + *
  • {@link Map}: Considered empty if it has zero key-value mappings. + *
  • {@link Optional}: Considered empty if {@link Optional#isPresent} returns false, + * regardless of the "emptiness" of the contents. + *
+ * + *
+   * ObjectUtils.isEmpty(null)             = true
+   * ObjectUtils.isEmpty("")               = true
+   * ObjectUtils.isEmpty("ab")             = false
+   * ObjectUtils.isEmpty(new int[]{})      = true
+   * ObjectUtils.isEmpty(new int[]{1,2,3}) = false
+   * ObjectUtils.isEmpty(1234)             = false
+   * ObjectUtils.isEmpty(1234)             = false
+   * ObjectUtils.isEmpty(Optional.of(""))  = false
+   * ObjectUtils.isEmpty(Optional.empty()) = true
+   * 
+ * + * @param object the {@link Object} to test, may be {@code null} + * @return {@code true} if the object has a supported type and is empty or null, {@code false} + * otherwise + * @since 3.9 + */ + public static boolean isEmpty(final Object object) { + if (object == null) { + return true; + } + if (object instanceof CharSequence) { + return ((CharSequence) object).length() == 0; + } + if (isArray(object)) { + return Array.getLength(object) == 0; + } + if (object instanceof Collection) { + return ((Collection) object).isEmpty(); + } + if (object instanceof Map) { + return ((Map) object).isEmpty(); + } + if (object instanceof Optional) { + // TODO Java 11 Use Optional#isEmpty() + return !((Optional) object).isPresent(); + } + return false; + } + + /** + * Tests whether the given object is an Object array or a primitive array in a null-safe manner. + * + *

A {@code null} {@code object} Object will return {@code false}. + * + *

+   * ObjectUtils.isArray(null)             = false
+   * ObjectUtils.isArray("")               = false
+   * ObjectUtils.isArray("ab")             = false
+   * ObjectUtils.isArray(new int[]{})      = true
+   * ObjectUtils.isArray(new int[]{1,2,3}) = true
+   * ObjectUtils.isArray(1234)             = false
+   * 
+ * + * @param object the object to check, may be {@code null} + * @return {@code true} if the object is an {@code array}, {@code false} otherwise + * @since 3.13.0 + */ + public static boolean isArray(final Object object) { + return object != null && object.getClass().isArray(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java new file mode 100644 index 000000000..7ea1d5743 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java @@ -0,0 +1,498 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.commons.lang3; + +import org.apache.commons.lang3.function.Suppliers; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class StringUtils { + + /** + * Checks if a CharSequence is empty ("") or null. + * + *
+   * StringUtils.isEmpty(null)      = true
+   * StringUtils.isEmpty("")        = true
+   * StringUtils.isEmpty(" ")       = false
+   * StringUtils.isEmpty("bob")     = false
+   * StringUtils.isEmpty("  bob  ") = false
+   * 
+ * + *

NOTE: This method changed in Lang version 2.0. It no longer trims the CharSequence. That + * functionality is available in isBlank(). + * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is empty or null + * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence) + */ + public static boolean isEmpty(final CharSequence cs) { + return cs == null || cs.length() == 0; + } + + /** + * Checks if a CharSequence is empty (""), null or whitespace only. + * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * + *

+   * StringUtils.isBlank(null)      = true
+   * StringUtils.isBlank("")        = true
+   * StringUtils.isBlank(" ")       = true
+   * StringUtils.isBlank("bob")     = false
+   * StringUtils.isBlank("  bob  ") = false
+   * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is null, empty or whitespace only + * @since 2.0 + * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence) + */ + public static boolean isBlank(final CharSequence cs) { + final int strLen = length(cs); + if (strLen == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + /** + * Checks if CharSequence contains a search character, handling {@code null}. This method uses + * {@link String#indexOf(int)} if possible. + * + *

A {@code null} or empty ("") CharSequence will return {@code false}. + * + *

+   * StringUtils.contains(null, *)    = false
+   * StringUtils.contains("", *)      = false
+   * StringUtils.contains("abc", 'a') = true
+   * StringUtils.contains("abc", 'z') = false
+   * 
+ * + * @param seq the CharSequence to check, may be null + * @param searchChar the character to find + * @return true if the CharSequence contains the search character, false if not or {@code null} + * string input + * @since 2.0 + * @since 3.0 Changed signature from contains(String, int) to contains(CharSequence, int) + */ + public static boolean contains(final CharSequence seq, final int searchChar) { + if (isEmpty(seq)) { + return false; + } + return CharSequenceUtils.indexOf(seq, searchChar, 0) >= 0; + } + + public static int length(final CharSequence cs) { + return cs == null ? 0 : cs.length(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * The empty String {@code ""}. + * + * @since 2.0 + */ + public static final String EMPTY = ""; + + /** The maximum size to which the padding constant(s) can expand. */ + private static final int PAD_LIMIT = 8192; + + /** + * A String for a space character. + * + * @since 3.2 + */ + public static final String SPACE = " "; + + /** + * Repeats a String {@code repeat} times to form a new String. + * + *
+   * StringUtils.repeat(null, 2) = null
+   * StringUtils.repeat("", 0)   = ""
+   * StringUtils.repeat("", 2)   = ""
+   * StringUtils.repeat("a", 3)  = "aaa"
+   * StringUtils.repeat("ab", 2) = "abab"
+   * StringUtils.repeat("a", -2) = ""
+   * 
+ * + * @param repeat the String to repeat, may be null + * @param count number of times to repeat str, negative treated as zero + * @return a new String consisting of the original String repeated, {@code null} if null String + * input + */ + public static String repeat(final String repeat, final int count) { + // Performance tuned for 2.0 (JDK1.4) + if (repeat == null) { + return null; + } + if (count <= 0) { + return EMPTY; + } + final int inputLength = repeat.length(); + if (count == 1 || inputLength == 0) { + return repeat; + } + if (inputLength == 1 && count <= PAD_LIMIT) { + return repeat(repeat.charAt(0), count); + } + + final int outputLength = inputLength * count; + switch (inputLength) { + case 1: + return repeat(repeat.charAt(0), count); + case 2: + final char ch0 = repeat.charAt(0); + final char ch1 = repeat.charAt(1); + final char[] output2 = new char[outputLength]; + for (int i = count * 2 - 2; i >= 0; i--, i--) { + output2[i] = ch0; + output2[i + 1] = ch1; + } + return new String(output2); + default: + final StringBuilder buf = new StringBuilder(outputLength); + for (int i = 0; i < count; i++) { + buf.append(repeat); + } + return buf.toString(); + } + } + + /** + * Returns padding using the specified delimiter repeated to a given length. + * + *
+   * StringUtils.repeat('e', 0)  = ""
+   * StringUtils.repeat('e', 3)  = "eee"
+   * StringUtils.repeat('e', -2) = ""
+   * 
+ * + *

Note: this method does not support padding with Unicode Supplementary + * Characters as they require a pair of {@code char}s to be represented. If you are needing to + * support full I18N of your applications consider using {@link #repeat(String, int)} instead. + * + * @param repeat character to repeat + * @param count number of times to repeat char, negative treated as zero + * @return String with repeated character + * @see #repeat(String, int) + */ + public static String repeat(final char repeat, final int count) { + if (count <= 0) { + return EMPTY; + } + return new String(ArrayFill.fill(new char[count], repeat)); + } + + /** + * Joins the elements of the provided array into a single String containing the provided list of + * elements. + * + *

No delimiter is added before or after the list. Null objects or empty strings within the + * array are represented by empty strings. + * + *

+   * StringUtils.join(null, *)               = null
+   * StringUtils.join([], *)                 = ""
+   * StringUtils.join([null], *)             = ""
+   * StringUtils.join([1, 2, 3], ';')  = "1;2;3"
+   * StringUtils.join([1, 2, 3], null) = "123"
+   * 
+ * + * @param array the array of values to join together, may be null + * @param separator the separator character to use + * @return the joined String, {@code null} if null array input + * @since 3.2 + */ + public static String join(final int[] array, final char separator) { + if (array == null) { + return null; + } + return join(array, separator, 0, array.length); + } + + /** + * Joins the elements of the provided array into a single String containing the provided list of + * elements. + * + *

No delimiter is added before or after the list. Null objects or empty strings within the + * array are represented by empty strings. + * + *

+   * StringUtils.join(null, *)               = null
+   * StringUtils.join([], *)                 = ""
+   * StringUtils.join([null], *)             = ""
+   * StringUtils.join([1, 2, 3], ';')  = "1;2;3"
+   * StringUtils.join([1, 2, 3], null) = "123"
+   * 
+ * + * @param array the array of values to join together, may be null + * @param delimiter the separator character to use + * @param startIndex the first index to start joining from. It is an error to pass in a start + * index past the end of the array + * @param endIndex the index to stop joining from (exclusive). It is an error to pass in an end + * index past the end of the array + * @return the joined String, {@code null} if null array input + * @since 3.2 + */ + public static String join( + final int[] array, final char delimiter, final int startIndex, final int endIndex) { + if (array == null) { + return null; + } + if (endIndex - startIndex <= 0) { + return EMPTY; + } + final StringBuilder stringBuilder = new StringBuilder(); + for (int i = startIndex; i < endIndex; i++) { + stringBuilder.append(array[i]).append(delimiter); + } + return stringBuilder.substring(0, stringBuilder.length() - 1); + } + + /** + * Tests if a CharSequence is not {@link #isBlank(CharSequence) blank} (whitespaces, empty ({@code + * ""}) or {@code null}). + * + *

Whitespace is defined by {@link Character#isWhitespace(char)}. + * + *

+   * StringUtils.isNotBlank(null)      = false
+   * StringUtils.isNotBlank("")        = false
+   * StringUtils.isNotBlank(" ")       = false
+   * StringUtils.isNotBlank("bob")     = true
+   * StringUtils.isNotBlank("  bob  ") = true
+   * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is not {@link #isBlank(CharSequence) blank} + * (whitespaces, empty ({@code ""}) or {@code null}) + * @see #isBlank(CharSequence) + * @since 2.0 + * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence) + */ + public static boolean isNotBlank(final CharSequence cs) { + return !isBlank(cs); + } + + /** + * Removes control characters (char <= 32) from both ends of this String, handling {@code null} + * by returning {@code null}. + * + *

The String is trimmed using {@link String#trim()}. Trim removes start and end characters + * <= 32. To strip whitespace use {@link #strip(String)}. + * + *

To trim your choice of characters, use the {@link #strip(String, String)} methods. + * + *

+   * StringUtils.trim(null)          = null
+   * StringUtils.trim("")            = ""
+   * StringUtils.trim("     ")       = ""
+   * StringUtils.trim("abc")         = "abc"
+   * StringUtils.trim("    abc    ") = "abc"
+   * 
+ * + * @param str the String to be trimmed, may be null + * @return the trimmed string, {@code null} if null String input + */ + public static String trim(final String str) { + return str == null ? null : str.trim(); + } + + /** + * Splits the provided text into an array, separators specified, preserving all tokens, including + * empty tokens created by adjacent separators. This is an alternative to using StringTokenizer. + * + *

The separator is not included in the returned String array. Adjacent separators are treated + * as separators for empty tokens. For more control over the split use the StrTokenizer class. + * + *

A {@code null} input String returns {@code null}. A {@code null} separatorChars splits on + * whitespace. + * + *

+   * StringUtils.splitPreserveAllTokens(null, *)           = null
+   * StringUtils.splitPreserveAllTokens("", *)             = []
+   * StringUtils.splitPreserveAllTokens("abc def", null)   = ["abc", "def"]
+   * StringUtils.splitPreserveAllTokens("abc def", " ")    = ["abc", "def"]
+   * StringUtils.splitPreserveAllTokens("abc  def", " ")   = ["abc", "", "def"]
+   * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":")   = ["ab", "cd", "ef"]
+   * StringUtils.splitPreserveAllTokens("ab:cd:ef:", ":")  = ["ab", "cd", "ef", ""]
+   * StringUtils.splitPreserveAllTokens("ab:cd:ef::", ":") = ["ab", "cd", "ef", "", ""]
+   * StringUtils.splitPreserveAllTokens("ab::cd:ef", ":")  = ["ab", "", "cd", "ef"]
+   * StringUtils.splitPreserveAllTokens(":cd:ef", ":")     = ["", "cd", "ef"]
+   * StringUtils.splitPreserveAllTokens("::cd:ef", ":")    = ["", "", "cd", "ef"]
+   * StringUtils.splitPreserveAllTokens(":cd:ef:", ":")    = ["", "cd", "ef", ""]
+   * 
+ * + * @param str the String to parse, may be {@code null} + * @param separatorChars the characters used as the delimiters, {@code null} splits on whitespace + * @return an array of parsed Strings, {@code null} if null String input + * @since 2.1 + */ + public static String[] splitPreserveAllTokens(final String str, final String separatorChars) { + return splitWorker(str, separatorChars, -1, true); + } + + /** + * Performs the logic for the {@code split} and {@code splitPreserveAllTokens} methods that return + * a maximum array length. + * + * @param str the String to parse, may be {@code null} + * @param separatorChars the separate character + * @param max the maximum number of elements to include in the array. A zero or negative value + * implies no limit. + * @param preserveAllTokens if {@code true}, adjacent separators are treated as empty token + * separators; if {@code false}, adjacent separators are treated as one separator. + * @return an array of parsed Strings, {@code null} if null String input + */ + private static String[] splitWorker( + final String str, + final String separatorChars, + final int max, + final boolean preserveAllTokens) { + // Performance tuned for 2.0 (JDK1.4) + // Direct code is quicker than StringTokenizer. + // Also, StringTokenizer uses isSpace() not isWhitespace() + + if (str == null) { + return null; + } + final int len = str.length(); + if (len == 0) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + final List list = new ArrayList<>(); + int sizePlus1 = 1; + int i = 0; + int start = 0; + boolean match = false; + boolean lastMatch = false; + if (separatorChars == null) { + // Null separator means use whitespace + while (i < len) { + if (Character.isWhitespace(str.charAt(i))) { + if (match || preserveAllTokens) { + lastMatch = true; + if (sizePlus1++ == max) { + i = len; + lastMatch = false; + } + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + lastMatch = false; + match = true; + i++; + } + } else if (separatorChars.length() == 1) { + // Optimize 1 character case + final char sep = separatorChars.charAt(0); + while (i < len) { + if (str.charAt(i) == sep) { + if (match || preserveAllTokens) { + lastMatch = true; + if (sizePlus1++ == max) { + i = len; + lastMatch = false; + } + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + lastMatch = false; + match = true; + i++; + } + } else { + // standard case + while (i < len) { + if (separatorChars.indexOf(str.charAt(i)) >= 0) { + if (match || preserveAllTokens) { + lastMatch = true; + if (sizePlus1++ == max) { + i = len; + lastMatch = false; + } + list.add(str.substring(start, i)); + match = false; + } + start = ++i; + continue; + } + lastMatch = false; + match = true; + i++; + } + } + if (match || preserveAllTokens && lastMatch) { + list.add(str.substring(start, i)); + } + return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY); + } + + /** + * Returns either the passed in CharSequence, or if the CharSequence is empty or {@code null}, the + * value supplied by {@code defaultStrSupplier}. + * + *

Caller responsible for thread-safety and exception handling of default value supplier + * + *

{@code
+   * StringUtils.getIfEmpty(null, () -> "NULL")    = "NULL"
+   * StringUtils.getIfEmpty("", () -> "NULL")      = "NULL"
+   * StringUtils.getIfEmpty(" ", () -> "NULL")     = " "
+   * StringUtils.getIfEmpty("bat", () -> "NULL")   = "bat"
+   * StringUtils.getIfEmpty("", () -> null)        = null
+   * StringUtils.getIfEmpty("", null)              = null
+   * }
+ * + * @param the specific kind of CharSequence + * @param str the CharSequence to check, may be null + * @param defaultSupplier the supplier of default CharSequence to return if the input is empty + * ("") or {@code null}, may be null + * @return the passed in CharSequence, or the default + * @see StringUtils#defaultString(String, String) + * @since 3.10 + */ + public static T getIfEmpty( + final T str, final Supplier defaultSupplier) { + return isEmpty(str) ? Suppliers.get(defaultSupplier) : str; + } + + public static boolean isNotEmpty(CharSequence cs) { + return !isEmpty(cs); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java b/java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java new file mode 100644 index 000000000..f435e0c57 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java @@ -0,0 +1,464 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +public abstract class Strings { + /** The Case-Insensitive singleton instance. */ + public static final Strings CI = new CiStrings(true); + + /** + * Represents a failed index search. + * + * @since 2.1 + */ + public static final int INDEX_NOT_FOUND = -1; + + /** Ignores case when possible. */ + private final boolean ignoreCase; + + /** Compares null as less when possible. */ + private final boolean nullIsLess; + + /** + * Constructs a new instance. + * + * @param ignoreCase Ignores case when possible. + * @param nullIsLess Compares null as less when possible. + */ + private Strings(final boolean ignoreCase, final boolean nullIsLess) { + this.ignoreCase = ignoreCase; + this.nullIsLess = nullIsLess; + } + + /** + * Compare two Strings lexicographically, like {@link String#compareTo(String)}. + * + *

The return values are: + * + *

    + *
  • {@code int = 0}, if {@code str1} is equal to {@code str2} (or both {@code null}) + *
  • {@code int < 0}, if {@code str1} is less than {@code str2} + *
  • {@code int > 0}, if {@code str1} is greater than {@code str2} + *
+ * + *

This is a {@code null} safe version of : + * + *

+   * str1.compareTo(str2)
+   * 
+ * + *

{@code null} value is considered less than non-{@code null} value. Two {@code null} + * references are considered equal. + * + *

Case-sensitive examples + * + *

{@code
+   * Strings.CS.compare(null, null)   = 0
+   * Strings.CS.compare(null , "a")   < 0
+   * Strings.CS.compare("a", null)   > 0
+   * Strings.CS.compare("abc", "abc") = 0
+   * Strings.CS.compare("a", "b")     < 0
+   * Strings.CS.compare("b", "a")     > 0
+   * Strings.CS.compare("a", "B")     > 0
+   * Strings.CS.compare("ab", "abc")  < 0
+   * }
+ * + *

Case-insensitive examples + * + *

{@code
+   * Strings.CI.compareIgnoreCase(null, null)   = 0
+   * Strings.CI.compareIgnoreCase(null , "a")   < 0
+   * Strings.CI.compareIgnoreCase("a", null)    > 0
+   * Strings.CI.compareIgnoreCase("abc", "abc") = 0
+   * Strings.CI.compareIgnoreCase("abc", "ABC") = 0
+   * Strings.CI.compareIgnoreCase("a", "b")     < 0
+   * Strings.CI.compareIgnoreCase("b", "a")     > 0
+   * Strings.CI.compareIgnoreCase("a", "B")     < 0
+   * Strings.CI.compareIgnoreCase("A", "b")     < 0
+   * Strings.CI.compareIgnoreCase("ab", "ABC")  < 0
+   * }
+ * + * @see String#compareTo(String) + * @param str1 the String to compare from + * @param str2 the String to compare to + * @return < 0, 0, > 0, if {@code str1} is respectively less, equal or greater than {@code + * str2} + */ + public abstract int compare(String str1, String str2); + + /** + * Tests if CharSequence contains a search CharSequence, handling {@code null}. This method uses + * {@link String#indexOf(String)} if possible. + * + *

A {@code null} CharSequence will return {@code false}. + * + *

Case-sensitive examples + * + *

+   * Strings.CS.contains(null, *)     = false
+   * Strings.CS.contains(*, null)     = false
+   * Strings.CS.contains("", "")      = true
+   * Strings.CS.contains("abc", "")   = true
+   * Strings.CS.contains("abc", "a")  = true
+   * Strings.CS.contains("abc", "z")  = false
+   * 
+ * + *

Case-insensitive examples + * + *

+   * Strings.CI.containsIgnoreCase(null, *)    = false
+   * Strings.CI.containsIgnoreCase(*, null)    = false
+   * Strings.CI.containsIgnoreCase("", "")     = true
+   * Strings.CI.containsIgnoreCase("abc", "")  = true
+   * Strings.CI.containsIgnoreCase("abc", "a") = true
+   * Strings.CI.containsIgnoreCase("abc", "z") = false
+   * Strings.CI.containsIgnoreCase("abc", "A") = true
+   * Strings.CI.containsIgnoreCase("abc", "Z") = false
+   * 
+ * + * @param seq the CharSequence to check, may be null + * @param searchSeq the CharSequence to find, may be null + * @return true if the CharSequence contains the search CharSequence, false if not or {@code null} + * string input + */ + public abstract boolean contains(CharSequence seq, CharSequence searchSeq); + + /** + * Compares two CharSequences, returning {@code true} if they represent equal sequences of + * characters. + * + *

{@code null}s are handled without exceptions. Two {@code null} references are considered to + * be equal. + * + *

Case-sensitive examples + * + *

+   * Strings.CS.equals(null, null)   = true
+   * Strings.CS.equals(null, "abc")  = false
+   * Strings.CS.equals("abc", null)  = false
+   * Strings.CS.equals("abc", "abc") = true
+   * Strings.CS.equals("abc", "ABC") = false
+   * 
+ * + *

Case-insensitive examples + * + *

+   * Strings.CI.equalsIgnoreCase(null, null)   = true
+   * Strings.CI.equalsIgnoreCase(null, "abc")  = false
+   * Strings.CI.equalsIgnoreCase("abc", null)  = false
+   * Strings.CI.equalsIgnoreCase("abc", "abc") = true
+   * Strings.CI.equalsIgnoreCase("abc", "ABC") = true
+   * 
+ * + * @param cs1 the first CharSequence, may be {@code null} + * @param cs2 the second CharSequence, may be {@code null} + * @return {@code true} if the CharSequences are equal (case-sensitive), or both {@code null} + * @see Object#equals(Object) + * @see String#compareTo(String) + * @see String#equalsIgnoreCase(String) + */ + public abstract boolean equals(CharSequence cs1, CharSequence cs2); + + /** + * Compares two CharSequences, returning {@code true} if they represent equal sequences of + * characters. + * + *

{@code null}s are handled without exceptions. Two {@code null} references are considered to + * be equal. + * + *

Case-sensitive examples + * + *

+   * Strings.CS.equals(null, null)   = true
+   * Strings.CS.equals(null, "abc")  = false
+   * Strings.CS.equals("abc", null)  = false
+   * Strings.CS.equals("abc", "abc") = true
+   * Strings.CS.equals("abc", "ABC") = false
+   * 
+ * + *

Case-insensitive examples + * + *

+   * Strings.CI.equalsIgnoreCase(null, null)   = true
+   * Strings.CI.equalsIgnoreCase(null, "abc")  = false
+   * Strings.CI.equalsIgnoreCase("abc", null)  = false
+   * Strings.CI.equalsIgnoreCase("abc", "abc") = true
+   * Strings.CI.equalsIgnoreCase("abc", "ABC") = true
+   * 
+ * + * @param str1 the first CharSequence, may be {@code null} + * @param str2 the second CharSequence, may be {@code null} + * @return {@code true} if the CharSequences are equal (case-sensitive), or both {@code null} + * @see Object#equals(Object) + * @see String#compareTo(String) + * @see String#equalsIgnoreCase(String) + */ + public abstract boolean equals(String str1, String str2); + + /** + * Finds the first index within a CharSequence, handling {@code null}. This method uses {@link + * String#indexOf(String, int)} if possible. + * + *

A {@code null} CharSequence will return {@code -1}. A negative start position is treated as + * zero. An empty ("") search CharSequence always matches. A start position greater than the + * string length only matches an empty search CharSequence. + * + *

Case-sensitive examples + * + *

+   * Strings.CS.indexOf(null, *, *)          = -1
+   * Strings.CS.indexOf(*, null, *)          = -1
+   * Strings.CS.indexOf("", "", 0)           = 0
+   * Strings.CS.indexOf("", *, 0)            = -1 (except when * = "")
+   * Strings.CS.indexOf("aabaabaa", "a", 0)  = 0
+   * Strings.CS.indexOf("aabaabaa", "b", 0)  = 2
+   * Strings.CS.indexOf("aabaabaa", "ab", 0) = 1
+   * Strings.CS.indexOf("aabaabaa", "b", 3)  = 5
+   * Strings.CS.indexOf("aabaabaa", "b", 9)  = -1
+   * Strings.CS.indexOf("aabaabaa", "b", -1) = 2
+   * Strings.CS.indexOf("aabaabaa", "", 2)   = 2
+   * Strings.CS.indexOf("abc", "", 9)        = 3
+   * 
+ * + *

Case-insensitive examples + * + *

+   * Strings.CI.indexOfIgnoreCase(null, *, *)          = -1
+   * Strings.CI.indexOfIgnoreCase(*, null, *)          = -1
+   * Strings.CI.indexOfIgnoreCase("", "", 0)           = 0
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+   * Strings.CI.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+   * Strings.CI.indexOfIgnoreCase("abc", "", 9)        = -1
+   * 
+ * + * @param seq the CharSequence to check, may be null + * @param searchSeq the CharSequence to find, may be null + * @param startPos the start position, negative treated as zero + * @return the first index of the search CharSequence (always ≥ startPos), -1 if no match or + * {@code null} string input + */ + public abstract int indexOf(CharSequence seq, CharSequence searchSeq, int startPos); + + /** + * Finds the last index within a CharSequence, handling {@code null}. This method uses {@link + * String#lastIndexOf(String, int)} if possible. + * + *

A {@code null} CharSequence will return {@code -1}. A negative start position returns {@code + * -1}. An empty ("") search CharSequence always matches unless the start position is negative. A + * start position greater than the string length searches the whole string. The search starts at + * the startPos and works backwards; matches starting after the start position are ignored. + * + *

Case-sensitive examples + * + *

+   * Strings.CS.lastIndexOf(null, *, *)          = -1
+   * Strings.CS.lastIndexOf(*, null, *)          = -1
+   * Strings.CS.lastIndexOf("aabaabaa", "a", 8)  = 7
+   * Strings.CS.lastIndexOf("aabaabaa", "b", 8)  = 5
+   * Strings.CS.lastIndexOf("aabaabaa", "ab", 8) = 4
+   * Strings.CS.lastIndexOf("aabaabaa", "b", 9)  = 5
+   * Strings.CS.lastIndexOf("aabaabaa", "b", -1) = -1
+   * Strings.CS.lastIndexOf("aabaabaa", "a", 0)  = 0
+   * Strings.CS.lastIndexOf("aabaabaa", "b", 0)  = -1
+   * Strings.CS.lastIndexOf("aabaabaa", "b", 1)  = -1
+   * Strings.CS.lastIndexOf("aabaabaa", "b", 2)  = 2
+   * Strings.CS.lastIndexOf("aabaabaa", "ba", 2)  = 2
+   * 
+ * + *

Case-insensitive examples + * + *

+   * Strings.CI.lastIndexOfIgnoreCase(null, *, *)          = -1
+   * Strings.CI.lastIndexOfIgnoreCase(*, null, *)          = -1
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "A", 8)  = 7
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "B", 8)  = 5
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "B", 9)  = 5
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+   * Strings.CI.lastIndexOfIgnoreCase("aabaabaa", "B", 0)  = -1
+   * 
+ * + * @param seq the CharSequence to check, may be null + * @param searchSeq the CharSequence to find, may be null + * @param startPos the start position, negative treated as zero + * @return the last index of the search CharSequence (always ≤ startPos), -1 if no match or + * {@code null} string input + */ + public abstract int lastIndexOf(CharSequence seq, CharSequence searchSeq, int startPos); + + /** + * Tests whether null is less when comparing. + * + * @return whether null is less when comparing. + */ + boolean isNullIsLess() { + return nullIsLess; + } + + /** + * Tests if a CharSequence starts with a specified prefix. + * + *

{@code null}s are handled without exceptions. Two {@code null} references are considered to + * be equal. + * + *

Case-sensitive examples + * + *

+   * Strings.CS.startsWith(null, null)      = true
+   * Strings.CS.startsWith(null, "abc")     = false
+   * Strings.CS.startsWith("abcdef", null)  = false
+   * Strings.CS.startsWith("abcdef", "abc") = true
+   * Strings.CS.startsWith("ABCDEF", "abc") = false
+   * 
+ * + *

Case-insensitive examples + * + *

+   * Strings.CI.startsWithIgnoreCase(null, null)      = true
+   * Strings.CI.startsWithIgnoreCase(null, "abc")     = false
+   * Strings.CI.startsWithIgnoreCase("abcdef", null)  = false
+   * Strings.CI.startsWithIgnoreCase("abcdef", "abc") = true
+   * Strings.CI.startsWithIgnoreCase("ABCDEF", "abc") = true
+   * 
+ * + * @see String#startsWith(String) + * @param str the CharSequence to check, may be null + * @param prefix the prefix to find, may be null + * @return {@code true} if the CharSequence starts with the prefix, case-sensitive, or both {@code + * null} + */ + public boolean startsWith(final CharSequence str, final CharSequence prefix) { + if (str == null || prefix == null) { + return str == prefix; + } + final int preLen = prefix.length(); + if (preLen > str.length()) { + return false; + } + return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, preLen); + } + + private static final class CiStrings extends Strings { + + private CiStrings(final boolean nullIsLess) { + super(true, nullIsLess); + } + + @Override + public int compare(final String s1, final String s2) { + if (s1 == s2) { + // Both null or same object + return 0; + } + if (s1 == null) { + return isNullIsLess() ? -1 : 1; + } + if (s2 == null) { + return isNullIsLess() ? 1 : -1; + } + return s1.compareToIgnoreCase(s2); + } + + @Override + public boolean contains(final CharSequence str, final CharSequence searchStr) { + if (str == null || searchStr == null) { + return false; + } + final int len = searchStr.length(); + final int max = str.length() - len; + for (int i = 0; i <= max; i++) { + if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, len)) { + return true; + } + } + return false; + } + + @Override + public boolean equals(final CharSequence cs1, final CharSequence cs2) { + if (cs1 == cs2) { + return true; + } + if (cs1 == null || cs2 == null) { + return false; + } + if (cs1.length() != cs2.length()) { + return false; + } + return CharSequenceUtils.regionMatches(cs1, true, 0, cs2, 0, cs1.length()); + } + + @Override + public boolean equals(final String s1, final String s2) { + return s1 == null ? s2 == null : s1.equalsIgnoreCase(s2); + } + + @Override + public int indexOf(final CharSequence str, final CharSequence searchStr, int startPos) { + if (str == null || searchStr == null) { + return INDEX_NOT_FOUND; + } + if (startPos < 0) { + startPos = 0; + } + final int endLimit = str.length() - searchStr.length() + 1; + if (startPos > endLimit) { + return INDEX_NOT_FOUND; + } + if (searchStr.length() == 0) { + return startPos; + } + for (int i = startPos; i < endLimit; i++) { + if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStr.length())) { + return i; + } + } + return INDEX_NOT_FOUND; + } + + @Override + public int lastIndexOf(final CharSequence str, final CharSequence searchStr, int startPos) { + if (str == null || searchStr == null) { + return INDEX_NOT_FOUND; + } + final int searchStrLength = searchStr.length(); + final int strLength = str.length(); + if (startPos > strLength - searchStrLength) { + startPos = strLength - searchStrLength; + } + if (startPos < 0) { + return INDEX_NOT_FOUND; + } + if (searchStrLength == 0) { + return startPos; + } + for (int i = startPos; i >= 0; i--) { + if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStrLength)) { + return i; + } + } + return INDEX_NOT_FOUND; + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java b/java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java new file mode 100644 index 000000000..1993a2da2 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +import org.apache.commons.lang3.function.Suppliers; + +import java.util.function.Supplier; + +public class SystemProperties { + + /** The System property name {@value}. */ + public static final String OS_NAME = "os.name"; + + /** The System property name {@value}. */ + public static final String JAVA_SPECIFICATION_VERSION = "java.specification.version"; + + /** + * Gets the current value from the system properties map for {@value #OS_NAME}. + * + *

Returns {@code null} if the property cannot be read due to a {@link SecurityException}. + * + * @return the current value from the system properties map. + */ + public static String getOsName() { + return getProperty(OS_NAME); + } + + /** + * Gets the current value from the system properties map. + * + *

Returns {@code null} if the property cannot be read due to a {@link SecurityException}. + * + * @return the current value from the system properties map. + */ + public static String getJavaSpecificationVersion() { + return getProperty(JAVA_SPECIFICATION_VERSION); + } + + /** + * Gets a System property, defaulting to {@code null} if the property cannot be read. + * + *

If a {@link SecurityException} is caught, the return value is {@code null}. + * + * @param property the system property name + * @return the system property value or {@code null} if a security problem occurs + */ + public static String getProperty(final String property) { + return getProperty(property, Suppliers.nul()); + } + + /** + * Gets a System property, defaulting to {@code null} if the property cannot be read. + * + *

If a {@link SecurityException} is caught, the return value is {@code null}. + * + * @param property the system property name. + * @param defaultIfAbsent get this Supplier when the property is empty or throws + * SecurityException. + * @return the system property value or {@code null} if a security problem occurs + */ + static String getProperty(final String property, final Supplier defaultIfAbsent) { + try { + if (StringUtils.isEmpty(property)) { + return Suppliers.get(defaultIfAbsent); + } + return StringUtils.getIfEmpty(System.getProperty(property), defaultIfAbsent); + } catch (final SecurityException ignore) { + // We are not allowed to look at this property. + // + // System.err.println("Caught a SecurityException reading the system property '" + property + // + "'; the SystemUtils property value will default to null."); + return defaultIfAbsent.get(); + } + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java new file mode 100644 index 000000000..060d6be17 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class SystemUtils { + + /** The prefix String for all Windows OS. */ + private static final String OS_NAME_WINDOWS_PREFIX = "Windows"; + + /** + * A constant for the System Property {@code java.specification.version}. Java Runtime Environment + * specification version. + * + *

Defaults to {@code null} if the runtime does not have security access to read this property + * or the property does not exist. + * + *

This value is initialized when the class is loaded. If {@link + * System#setProperty(String,String)} or {@link System#setProperties(java.util.Properties)} is + * called after this class is loaded, the value will be out of sync with that System property. + * + * @see SystemProperties#getJavaSpecificationVersion() + * @since Java 1.3 + */ + public static final String JAVA_SPECIFICATION_VERSION = + SystemProperties.getJavaSpecificationVersion(); + + /** + * A constant for the System Property {@code os.name}. Operating system name. + * + *

Defaults to {@code null} if the runtime does not have security access to read this property + * or the property does not exist. + * + *

This value is initialized when the class is loaded. If {@link + * System#setProperty(String,String)} or {@link System#setProperties(java.util.Properties)} is + * called after this class is loaded, the value will be out of sync with that System property. + * + * @see SystemProperties#getOsName() + * @since Java 1.1 + */ + public static final String OS_NAME = SystemProperties.getOsName(); + + /** + * The constant {@code true} if this is Windows. + * + *

The result depends on the value of the {@link #OS_NAME} constant. + * + *

The field will return {@code false} if {@link #OS_NAME} is {@code null}. + * + *

This value is initialized when the class is loaded. + * + * @since 2.0 + */ + public static final boolean IS_OS_WINDOWS = getOsNameMatches(OS_NAME_WINDOWS_PREFIX); + + /** + * The constant {@code true} if this is Java version 1.8 (also 1.8.x versions). + * + *

The result depends on the value of the {@link #JAVA_SPECIFICATION_VERSION} constant. + * + *

The field will return {@code false} if {@link #JAVA_SPECIFICATION_VERSION} is {@code null}. + * + *

This value is initialized when the class is loaded. + * + * @since 3.3.2 + */ + public static final boolean IS_JAVA_1_8 = getJavaVersionMatches("1.8"); + + /** + * Tests if the operating system matches the given string with a case-insensitive comparison. + * + *

The result depends on the value of the {@link #OS_NAME} constant. + * + *

The method returns {@code false} if {@link #OS_NAME} is {@code null}. + * + * @param osNamePrefix the prefix for the OS name. + * @return true if matches, or false if not or can't determine. + */ + private static boolean getOsNameMatches(final String osNamePrefix) { + return isOsNameMatch(OS_NAME, osNamePrefix); + } + + /** + * Tests whether the operating system matches with a case-insensitive comparison. + * + *

This method is package private instead of private to support unit test invocation. + * + * @param osName the actual OS name. + * @param osNamePrefix the prefix for the expected OS name. + * @return true for a case-insensitive match, or false if not. + */ + static boolean isOsNameMatch(final String osName, final String osNamePrefix) { + if (osName == null) { + return false; + } + return Strings.CI.startsWith(osName, osNamePrefix); + } + + /** + * Tests if the Java version matches the version we are running. + * + *

The result depends on the value of the {@link #JAVA_SPECIFICATION_VERSION} constant. + * + * @param versionPrefix the prefix for the Java version. + * @return true if matches, or false if not or can't determine. + */ + private static boolean getJavaVersionMatches(final String versionPrefix) { + return isJavaVersionMatch(JAVA_SPECIFICATION_VERSION, versionPrefix); + } + + /** + * Tests whether the Java version matches. + * + *

This method is package private instead of private to support unit test invocation. + * + * @param version the actual Java version. + * @param versionPrefix the prefix for the expected Java version. + * @return true if matches, or false if not or can't determine. + */ + static boolean isJavaVersionMatch(final String version, final String versionPrefix) { + if (version == null) { + return false; + } + return version.startsWith(versionPrefix); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java b/java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java new file mode 100644 index 000000000..b3a41e717 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.commons.lang3; + +import java.util.Objects; +import java.util.function.Supplier; + +public class Validate { + private static final String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false"; + private static final String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null"; + + public static void isTrue(final boolean expression) { + if (!expression) { + throw new IllegalArgumentException(DEFAULT_IS_TRUE_EX_MESSAGE); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // IoTDB + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Validate that the specified argument is not {@code null}; otherwise throwing an exception. + * + *

Validate.notNull(myObject, "The object must not be null");
+ * + *

The message of the exception is "The validated object is null". + * + * @param the object type + * @param object the object to check + * @return the validated object (never {@code null} for method chaining) + * @throws NullPointerException if the object is {@code null} + * @see #notNull(Object, String, Object...) + * @deprecated Use {@link Objects#requireNonNull(Object)}. + */ + @Deprecated + public static T notNull(final T object) { + return notNull(object, DEFAULT_IS_NULL_EX_MESSAGE); + } + + /** + * Validate that the specified argument is not {@code null}; otherwise throwing an exception with + * the specified message. + * + *

Validate.notNull(myObject, "The object must not be null");
+ * + * @param the object type + * @param object the object to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not + * null + * @param values the optional values for the formatted exception message + * @return the validated object (never {@code null} for method chaining) + * @throws NullPointerException if the object is {@code null} + * @see Objects#requireNonNull(Object) + */ + public static T notNull(final T object, final String message, final Object... values) { + return Objects.requireNonNull(object, toSupplier(message, values)); + } + + private static Supplier toSupplier(final String message, final Object... values) { + return () -> getMessage(message, values); + } + + /** + * Gets the message using {@link String#format(String, Object...) String.format(message, values)} + * if the values are not empty, otherwise return the message unformatted. This method exists to + * allow validation methods declaring a String message and varargs parameters to be used without + * any message parameters when the message contains special characters, e.g. {@code + * Validate.isTrue(false, "%Failed%")}. + * + * @param message the {@link String#format(String, Object...)} exception message if invalid, not + * null + * @param values the optional values for the formatted message + * @return formatted message using {@link String#format(String, Object...) String.format(message, + * values)} if the values are not empty, otherwise return the unformatted message. + */ + private static String getMessage(final String message, final Object... values) { + return ArrayUtils.isEmpty(values) ? message : String.format(message, values); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java new file mode 100644 index 000000000..d7c8a616c --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.exception; + +import java.util.ArrayList; +import java.util.List; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class ExceptionUtils { + + /** + * Walks the {@link Throwable} to obtain its root cause. + * + *

This method walks through the exception chain until the last element, the root cause of the + * chain, using {@link Throwable#getCause()}, and returns that exception. + * + *

This method handles recursive cause chains that might otherwise cause infinite loops. The + * cause chain is processed until the end, or until the next item in the chain is already + * processed. If we detect a loop, then return the element before the loop. + * + * @param throwable the throwable to get the root cause for, may be null + * @return the root cause of the {@link Throwable}, {@code null} if null throwable input + */ + public static Throwable getRootCause(final Throwable throwable) { + final List list = getThrowableList(throwable); + return list.isEmpty() ? null : list.get(list.size() - 1); + } + + /** + * Gets the list of {@link Throwable} objects in the exception chain. + * + *

A throwable without cause will return a list containing one element - the input throwable. A + * throwable with one cause will return a list containing two elements. - the input throwable and + * the cause throwable. A {@code null} throwable will return a list of size zero. + * + *

This method handles recursive cause chains that might otherwise cause infinite loops. The + * cause chain is processed until the end, or until the next item in the chain is already in the + * result list. + * + * @param throwable the throwable to inspect, may be null + * @return the list of throwables, never null + * @since 2.2 + */ + public static List getThrowableList(Throwable throwable) { + final List list = new ArrayList<>(); + while (throwable != null && !list.contains(throwable)) { + list.add(throwable); + throwable = throwable.getCause(); + } + return list; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java b/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java new file mode 100644 index 000000000..2d49cd8f6 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.function; + +import java.util.Objects; +import java.util.function.BiConsumer; + +/** + * A functional interface like {@link BiConsumer} that declares a {@link Throwable}. + * + * @param Consumed type 1. + * @param Consumed type 2. + * @param The kind of thrown exception or error. + * @since 3.11 + */ +@FunctionalInterface +public interface FailableBiConsumer { + + /** NOP singleton */ + @SuppressWarnings("rawtypes") + FailableBiConsumer NOP = + (t, u) -> { + /* NOP */ + }; + + /** + * Gets the NOP singleton. + * + * @param Consumed type 1. + * @param Consumed type 2. + * @param The kind of thrown exception or error. + * @return The NOP singleton. + */ + @SuppressWarnings("unchecked") + static FailableBiConsumer nop() { + return NOP; + } + + /** + * Accepts the given arguments. + * + * @param t the first parameter for the consumable to accept + * @param u the second parameter for the consumable to accept + * @throws E Thrown when the consumer fails. + */ + void accept(T t, U u) throws E; + + /** + * Returns a composed {@link FailableBiConsumer} like {@link BiConsumer#andThen(BiConsumer)}. + * + * @param after the operation to perform after this one. + * @return a composed {@link FailableBiConsumer} like {@link BiConsumer#andThen(BiConsumer)}. + * @throws NullPointerException when {@code after} is null. + */ + default FailableBiConsumer andThen( + final FailableBiConsumer after) { + Objects.requireNonNull(after); + return (t, u) -> { + accept(t, u); + after.accept(t, u); + }; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java b/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java new file mode 100644 index 000000000..02872d5c3 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.function; + +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * A functional interface like {@link BiFunction} that declares a {@link Throwable}. + * + * @param Input type 1. + * @param Input type 2. + * @param Return type. + * @param The kind of thrown exception or error. + * @since 3.11 + */ +@FunctionalInterface +public interface FailableBiFunction { + + /** NOP singleton */ + @SuppressWarnings("rawtypes") + FailableBiFunction NOP = (t, u) -> null; + + /** + * Gets the NOP singleton. + * + * @param Consumed type 1. + * @param Consumed type 2. + * @param Return type. + * @param The kind of thrown exception or error. + * @return The NOP singleton. + */ + @SuppressWarnings("unchecked") + static FailableBiFunction nop() { + return NOP; + } + + /** + * Returns a composed {@link FailableBiFunction} that like {@link BiFunction#andThen(Function)}. + * + * @param the output type of the {@code after} function, and of the composed function. + * @param after the operation to perform after this one. + * @return a composed {@link FailableBiFunction} that like {@link BiFunction#andThen(Function)}. + * @throws NullPointerException when {@code after} is null. + */ + default FailableBiFunction andThen( + final FailableFunction after) { + Objects.requireNonNull(after); + return (final T t, final U u) -> after.apply(apply(t, u)); + } + + /** + * Applies this function. + * + * @param input1 the first input for the function + * @param input2 the second input for the function + * @return the result of the function + * @throws E Thrown when the function fails. + */ + R apply(T input1, U input2) throws E; +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java b/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java new file mode 100644 index 000000000..a6cd1fd85 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.function; + +import java.util.Objects; +import java.util.function.Function; + +/** + * A functional interface like {@link Function} that declares a {@link Throwable}. + * + * @param Input type 1. + * @param Return type. + * @param The kind of thrown exception or error. + * @since 3.11 + */ +@FunctionalInterface +public interface FailableFunction { + + /** NOP singleton */ + @SuppressWarnings("rawtypes") + FailableFunction NOP = t -> null; + + /** + * Starts a fluent chain like {@code function(foo::bar).andThen(...).andThen(...).apply(...);} + * + * @param Input type. + * @param Return type. + * @param The kind of thrown exception or error. + * @param function the argument to return. + * @return the argument + * @since 3.14.0 + */ + static FailableFunction function( + final FailableFunction function) { + return function; + } + + /** + * Returns a function that always returns its input argument. + * + * @param the type of the input and output objects to the function + * @param The kind of thrown exception or error. + * @return a function that always returns its input argument + */ + static FailableFunction identity() { + return t -> t; + } + + /** + * Gets the NOP singleton. + * + * @param Consumed type. + * @param Return type. + * @param The kind of thrown exception or error. + * @return The NOP singleton. + */ + @SuppressWarnings("unchecked") + static FailableFunction nop() { + return NOP; + } + + /** + * Returns a composed {@link FailableFunction} like {@link Function#andThen(Function)}. + * + * @param the output type of the {@code after} function, and of the composed function. + * @return a composed {@link FailableFunction} like {@link Function#andThen(Function)}. + * @param after the operation to perform after this one. + * @throws NullPointerException when {@code after} is null. + */ + default FailableFunction andThen( + final FailableFunction after) { + Objects.requireNonNull(after); + return (final T t) -> after.apply(apply(t)); + } + + /** + * Applies this function. + * + * @param input the input for the function + * @return the result of the function + * @throws E Thrown when the function fails. + */ + R apply(T input) throws E; + + /** + * Returns a composed {@link FailableFunction} like {@link Function#compose(Function)}. + * + * @param the input type to the {@code before} function, and to the composed function. + * @param before the operator to apply before this one. + * @return a composed {@link FailableFunction} like {@link Function#compose(Function)}. + * @throws NullPointerException if before is null. + * @see #andThen(FailableFunction) + */ + default FailableFunction compose( + final FailableFunction before) { + Objects.requireNonNull(before); + return (final V v) -> apply(before.apply(v)); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java b/java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java new file mode 100644 index 000000000..e92a8fb1c --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.function; + +import java.util.function.Supplier; + +/** + * Helps use {@link Supplier}. + * + * @since 3.13.0 + */ +public class Suppliers { + + /** + * Returns the singleton supplier that always returns null. + * + *

This supplier never throws an exception. + */ + @SuppressWarnings("rawtypes") + private static Supplier NUL = () -> null; + + /** + * Null-safe call to {@link Supplier#get()}. + * + * @param the type of results supplied by this supplier. + * @param supplier the supplier or null. + * @return Result of {@link Supplier#get()} or null. + */ + public static T get(final Supplier supplier) { + return supplier == null ? null : supplier.get(); + } + + /** + * Gets the singleton supplier that always returns null. + * + *

This supplier never throws an exception. + * + * @param Supplied type. + * @return The NUL singleton. + * @since 3.14.0 + */ + @SuppressWarnings("unchecked") + public static Supplier nul() { + return NUL; + } + + /** + * Make private in 4.0. + * + * @deprecated TODO Make private in 4.0. + */ + @Deprecated + public Suppliers() { + // empty + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java b/java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java new file mode 100644 index 000000000..b1c69b0ca --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.function; + +import java.util.Objects; +import java.util.function.Function; + +/** + * Represents a function that accepts three arguments and produces a result. This is the three-arity + * specialization of {@link Function}. + * + *

This is a functional interface whose functional method is + * {@link #apply(Object, Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function + * @param the type of the third argument to the function + * @param the type of the result of the function + * @see Function + * @since 3.12.0 + */ +@FunctionalInterface +public interface TriFunction { + + /** + * Returns a composed function that first applies this function to its input, and then applies the + * {@code after} function to the result. If evaluation of either function throws an exception, it + * is relayed to the caller of the composed function. + * + * @param the type of output of the {@code after} function, and of the composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then applies the {@code after} + * function + * @throws NullPointerException if after is null + */ + default TriFunction andThen(final Function after) { + Objects.requireNonNull(after); + return (final T t, final U u, final V v) -> after.apply(apply(t, u, v)); + } + + /** + * Applies this function to the given arguments. + * + * @param t the first function argument + * @param u the second function argument + * @param v the third function argument + * @return the function result + */ + R apply(T t, U u, V v); +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java b/java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java new file mode 100644 index 000000000..804b9e38c --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.math; + +import org.apache.commons.lang3.StringUtils; + +public class NumberUtils { + /** + * Checks whether the String is a valid Java number. + * + *

Valid numbers include hexadecimal marked with the {@code 0x} or {@code 0X} qualifier, octal + * numbers, scientific notation and numbers marked with a type qualifier (e.g. 123L). + * + *

Non-hexadecimal strings beginning with a leading zero are treated as octal values. Thus the + * string {@code 09} will return {@code false}, since {@code 9} is not a valid octal value. + * However, numbers beginning with {@code 0.} are treated as decimal. + * + *

{@code null} and empty/blank {@link String} will return {@code false}. + * + *

Note, {@link #createNumber(String)} should return a number for every input resulting in + * {@code true}. + * + * @param str the {@link String} to check + * @return {@code true} if the string is a correctly formatted number + * @since 3.5 + */ + public static boolean isCreatable(final String str) { + if (StringUtils.isEmpty(str)) { + return false; + } + final char[] chars = str.toCharArray(); + int sz = chars.length; + boolean hasExp = false; + boolean hasDecPoint = false; + boolean allowSigns = false; + boolean foundDigit = false; + // deal with any possible sign up front + final int start = chars[0] == '-' || chars[0] == '+' ? 1 : 0; + if (sz > start + 1 + && chars[start] == '0' + && !StringUtils.contains(str, '.')) { // leading 0, skip if is a decimal number + if (chars[start + 1] == 'x' || chars[start + 1] == 'X') { // leading 0x/0X + int i = start + 2; + if (i == sz) { + return false; // str == "0x" + } + // checking hex (it can't be anything else) + for (; i < chars.length; i++) { + if ((chars[i] < '0' || chars[i] > '9') + && (chars[i] < 'a' || chars[i] > 'f') + && (chars[i] < 'A' || chars[i] > 'F')) { + return false; + } + } + return true; + } + if (Character.isDigit(chars[start + 1])) { + // leading 0, but not hex, must be octal + int i = start + 1; + for (; i < chars.length; i++) { + if (chars[i] < '0' || chars[i] > '7') { + return false; + } + } + return true; + } + } + sz--; // don't want to loop to the last char, check it afterwards + // for type qualifiers + int i = start; + // loop to the next to last char or to the last char if we need another digit to + // make a valid number (e.g. chars[0..5] = "1234E") + while (i < sz || i < sz + 1 && allowSigns && !foundDigit) { + if (chars[i] >= '0' && chars[i] <= '9') { + foundDigit = true; + allowSigns = false; + + } else if (chars[i] == '.') { + if (hasDecPoint || hasExp) { + // two decimal points or dec in exponent + return false; + } + hasDecPoint = true; + } else if (chars[i] == 'e' || chars[i] == 'E') { + // we've already taken care of hex. + if (hasExp) { + // two E's + return false; + } + if (!foundDigit) { + return false; + } + hasExp = true; + allowSigns = true; + } else if (chars[i] == '+' || chars[i] == '-') { + if (!allowSigns) { + return false; + } + allowSigns = false; + foundDigit = false; // we need a digit after the E + } else { + return false; + } + i++; + } + if (i < chars.length) { + if (chars[i] >= '0' && chars[i] <= '9') { + // no type qualifier, OK + return true; + } + if (chars[i] == 'e' || chars[i] == 'E') { + // can't have an E at the last byte + return false; + } + if (chars[i] == '.') { + if (hasDecPoint || hasExp) { + // two decimal points or dec in exponent + return false; + } + // single trailing decimal point after non-exponent is ok + return foundDigit; + } + if (!allowSigns + && (chars[i] == 'd' || chars[i] == 'D' || chars[i] == 'f' || chars[i] == 'F')) { + return foundDigit; + } + if (chars[i] == 'l' || chars[i] == 'L') { + // not allowing L with an exponent or decimal point + return foundDigit && !hasExp && !hasDecPoint; + } + // last character is illegal + return false; + } + // allowSigns is true iff the val ends in 'E' + // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass + return !allowSigns && foundDigit; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java new file mode 100644 index 000000000..05b8fdd16 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.tuple; + +import java.util.Map; +import java.util.Objects; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * An immutable pair consisting of two {@link Object} elements. + * + *

Although the implementation is immutable, there is no restriction on the objects that may be + * stored. If mutable objects are stored in the pair, then the pair itself effectively becomes + * mutable. + * + *

#ThreadSafe# if both paired objects are thread-safe + * + * @param the left element type + * @param the right element type + * @since 3.0 + */ +public class ImmutablePair extends Pair { + + /** + * An empty array. + * + *

Consider using {@link #emptyArray()} to avoid generics warnings. + * + * @since 3.10 + */ + public static final ImmutablePair[] EMPTY_ARRAY = {}; + + /** An immutable pair of nulls. */ + // This is not defined with generics to avoid warnings in call sites. + @SuppressWarnings("rawtypes") + private static final ImmutablePair NULL = new ImmutablePair<>(null, null); + + /** Serialization version */ + private static final long serialVersionUID = 4954918890077093841L; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @param the left element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10 + */ + @SuppressWarnings("unchecked") + public static ImmutablePair[] emptyArray() { + return (ImmutablePair[]) EMPTY_ARRAY; + } + + /** + * Creates an immutable pair of two objects inferring the generic types. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type + * @param the right element type + * @param left the left element, may be null + * @return a pair formed from the two parameters, not null + * @since 3.11 + */ + public static Pair left(final L left) { + return of(left, null); + } + + /** + * Returns an immutable pair of nulls. + * + * @param the left element of this pair. Value is {@code null}. + * @param the right element of this pair. Value is {@code null}. + * @return an immutable pair of nulls. + * @since 3.6 + */ + @SuppressWarnings("unchecked") + public static ImmutablePair nullPair() { + return NULL; + } + + /** + * Creates an immutable pair of two objects inferring the generic types. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type + * @param the right element type + * @param left the left element, may be null + * @param right the right element, may be null + * @return a pair formed from the two parameters, not null + */ + public static ImmutablePair of(final L left, final R right) { + return left != null || right != null ? new ImmutablePair<>(left, right) : nullPair(); + } + + /** + * Creates an immutable pair from a map entry. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type + * @param the right element type + * @param pair the existing map entry. + * @return a pair formed from the map entry + * @since 3.10 + */ + public static ImmutablePair of(final Map.Entry pair) { + return pair != null ? new ImmutablePair<>(pair.getKey(), pair.getValue()) : nullPair(); + } + + /** + * Creates an immutable pair of two non-null objects inferring the generic types. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type + * @param the right element type + * @param left the left element, may not be null + * @param right the right element, may not be null + * @return a pair formed from the two parameters, not null + * @throws NullPointerException if any input is null + * @since 3.13.0 + */ + public static ImmutablePair ofNonNull(final L left, final R right) { + return of(Objects.requireNonNull(left, "left"), Objects.requireNonNull(right, "right")); + } + + /** + * Creates an immutable pair of two objects inferring the generic types. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type + * @param the right element type + * @param right the right element, may be null + * @return a pair formed from the two parameters, not null + * @since 3.11 + */ + public static Pair right(final R right) { + return of(null, right); + } + + /** Left object */ + public final L left; + + /** Right object */ + public final R right; + + /** + * Create a new pair instance. + * + * @param left the left value, may be null + * @param right the right value, may be null + */ + public ImmutablePair(final L left, final R right) { + this.left = left; + this.right = right; + } + + /** {@inheritDoc} */ + @Override + public L getLeft() { + return left; + } + + /** {@inheritDoc} */ + @Override + public R getRight() { + return right; + } + + /** + * Throws {@link UnsupportedOperationException}. + * + *

This pair is immutable, so this operation is not supported. + * + * @param value the value to set + * @return never + * @throws UnsupportedOperationException as this operation is not supported + */ + @Override + public R setValue(final R value) { + throw new UnsupportedOperationException(); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java new file mode 100644 index 000000000..b5b4e8e64 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.tuple; + +import java.util.Objects; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * An immutable triple consisting of three {@link Object} elements. + * + *

Although the implementation is immutable, there is no restriction on the objects that may be + * stored. If mutable objects are stored in the triple, then the triple itself effectively becomes + * mutable. + * + *

#ThreadSafe# if all three objects are thread-safe. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @since 3.2 + */ +public class ImmutableTriple extends Triple { + + /** + * An empty array. + * + *

Consider using {@link #emptyArray()} to avoid generics warnings. + * + * @since 3.10 + */ + public static final ImmutableTriple[] EMPTY_ARRAY = {}; + + /** An immutable triple of nulls. */ + // This is not defined with generics to avoid warnings in call sites. + @SuppressWarnings("rawtypes") + private static final ImmutableTriple NULL = new ImmutableTriple<>(null, null, null); + + /** Serialization version. */ + private static final long serialVersionUID = 1L; + + /** + * Gets the empty array singleton that can be assigned without compiler warning. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10 + */ + @SuppressWarnings("unchecked") + public static ImmutableTriple[] emptyArray() { + return (ImmutableTriple[]) EMPTY_ARRAY; + } + + /** + * Gets the immutable triple of nulls singleton. + * + * @param the left element of this triple. Value is {@code null}. + * @param the middle element of this triple. Value is {@code null}. + * @param the right element of this triple. Value is {@code null}. + * @return an immutable triple of nulls. + * @since 3.6 + */ + @SuppressWarnings("unchecked") + public static ImmutableTriple nullTriple() { + return NULL; + } + + /** + * Creates an immutable triple of three objects inferring the generic types. + * + *

This factory allows the triple to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @param left the left element, may be null. + * @param middle the middle element, may be null. + * @param right the right element, may be null. + * @return a triple formed from the three parameters, not null. + */ + public static ImmutableTriple of(final L left, final M middle, final R right) { + return left != null | middle != null || right != null + ? new ImmutableTriple<>(left, middle, right) + : nullTriple(); + } + + /** + * Creates an immutable triple of three non-null objects inferring the generic types. + * + *

This factory allows the triple to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @param left the left element, may not be null. + * @param middle the middle element, may not be null. + * @param right the right element, may not be null. + * @return a triple formed from the three parameters, not null. + * @throws NullPointerException if any input is null. + * @since 3.13.0 + */ + public static ImmutableTriple ofNonNull( + final L left, final M middle, final R right) { + return of( + Objects.requireNonNull(left, "left"), + Objects.requireNonNull(middle, "middle"), + Objects.requireNonNull(right, "right")); + } + + /** Left object. */ + public final L left; + + /** Middle object. */ + public final M middle; + + /** Right object. */ + public final R right; + + /** + * Constructs a new triple instance. + * + * @param left the left value, may be null. + * @param middle the middle value, may be null. + * @param right the right value, may be null. + */ + public ImmutableTriple(final L left, final M middle, final R right) { + this.left = left; + this.middle = middle; + this.right = right; + } + + /** {@inheritDoc} */ + @Override + public L getLeft() { + return left; + } + + /** {@inheritDoc} */ + @Override + public M getMiddle() { + return middle; + } + + /** {@inheritDoc} */ + @Override + public R getRight() { + return right; + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java new file mode 100644 index 000000000..12a767c19 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.tuple; + +import org.apache.commons.lang3.function.FailableBiConsumer; +import org.apache.commons.lang3.function.FailableBiFunction; + +import java.io.Serializable; +import java.util.Map; +import java.util.Objects; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * A pair consisting of two elements. + * + *

This class is an abstract implementation defining the basic API. It refers to the elements as + * 'left' and 'right'. It also implements the {@code Map.Entry} interface where the key is 'left' + * and the value is 'right'. + * + *

Subclass implementations may be mutable or immutable. However, there is no restriction on the + * type of the stored objects that may be stored. If mutable objects are stored in the pair, then + * the pair itself effectively becomes mutable. + * + * @param the left element type. + * @param the right element type. + * @since 3.0 + */ +public abstract class Pair implements Map.Entry, Comparable>, Serializable { + + /** Serialization version */ + private static final long serialVersionUID = 4954918890077093841L; + + /** + * An empty array. + * + *

Consider using {@link #emptyArray()} to avoid generics warnings. + * + * @since 3.10 + */ + public static final Pair[] EMPTY_ARRAY = {}; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @param the left element type. + * @param the right element type. + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10 + */ + @SuppressWarnings("unchecked") + public static Pair[] emptyArray() { + return (Pair[]) EMPTY_ARRAY; + } + + /** + * Creates an immutable pair of two objects inferring the generic types. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the right element type. + * @param left the left element, may be null. + * @param right the right element, may be null. + * @return a pair formed from the two parameters, not null. + */ + public static Pair of(final L left, final R right) { + return ImmutablePair.of(left, right); + } + + /** + * Creates an immutable pair from a map entry. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the right element type. + * @param pair the map entry. + * @return a pair formed from the map entry. + * @since 3.10 + */ + public static Pair of(final Map.Entry pair) { + return ImmutablePair.of(pair); + } + + /** + * Creates an immutable pair of two non-null objects inferring the generic types. + * + *

This factory allows the pair to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the right element type. + * @param left the left element, may not be null. + * @param right the right element, may not be null. + * @return a pair formed from the two parameters, not null. + * @throws NullPointerException if any input is null. + * @since 3.13.0 + */ + public static Pair ofNonNull(final L left, final R right) { + return ImmutablePair.ofNonNull(left, right); + } + + /** Constructs a new instance. */ + public Pair() { + // empty + } + + /** + * Accepts this key and value as arguments to the given consumer. + * + * @param The kind of thrown exception or error. + * @param consumer the consumer to call. + * @throws E Thrown when the consumer fails. + * @since 3.13.0 + */ + public void accept(final FailableBiConsumer consumer) throws E { + consumer.accept(getKey(), getValue()); + } + + /** + * Applies this key and value as arguments to the given function. + * + * @param The function return type. + * @param The kind of thrown exception or error. + * @param function the consumer to call. + * @return the function's return value. + * @throws E Thrown when the consumer fails. + * @since 3.13.0 + */ + public V apply(final FailableBiFunction function) throws E { + return function.apply(getKey(), getValue()); + } + + /** + * Compares the pair based on the left element followed by the right element. The types must be + * {@link Comparable}. + * + * @param other the other pair, not null. + * @return negative if this is less, zero if equal, positive if greater. + */ + @Override + public int compareTo(final Pair other) { + // Currently not used + return 0; + } + + /** + * Compares this pair to another based on the two elements. + * + * @param obj the object to compare to, null returns false. + * @return true if the elements of the pair are equal. + */ + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Map.Entry) { + final Map.Entry other = (Map.Entry) obj; + return Objects.equals(getKey(), other.getKey()) + && Objects.equals(getValue(), other.getValue()); + } + return false; + } + + /** + * Gets the key from this pair. + * + *

This method implements the {@code Map.Entry} interface returning the left element as the + * key. + * + * @return the left element as the key, may be null. + */ + @Override + public final L getKey() { + return getLeft(); + } + + /** + * Gets the left element from this pair. + * + *

When treated as a key-value pair, this is the key. + * + * @return the left element, may be null. + */ + public abstract L getLeft(); + + /** + * Gets the right element from this pair. + * + *

When treated as a key-value pair, this is the value. + * + * @return the right element, may be null. + */ + public abstract R getRight(); + + /** + * Gets the value from this pair. + * + *

This method implements the {@code Map.Entry} interface returning the right element as the + * value. + * + * @return the right element as the value, may be null. + */ + @Override + public R getValue() { + return getRight(); + } + + /** + * Returns a suitable hash code. + * + *

The hash code follows the definition in {@code Map.Entry}. + * + * @return the hash code. + */ + @Override + public int hashCode() { + // See Map.Entry API specification + return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); + } + + /** + * Returns a String representation of this pair using the format {@code (left,right)}. + * + * @return a string describing this object, not null. + */ + @Override + public String toString() { + return "(" + getLeft() + ',' + getRight() + ')'; + } + + /** + * Formats the receiver using the given format. + * + *

This uses {@link String#format(String, Object...)} to the format. Two variables may be used + * to embed the left and right elements. Use {@code %1$s} for the left element (key) and {@code + * %2$s} for the right element (value). + * + * @param format the format string, optionally containing {@code %1$s} and {@code %2$s}, not null. + * @return the formatted string, not null. + * @see String#format(String, Object...) + */ + public String toString(final String format) { + return String.format(format, getLeft(), getRight()); + } +} diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java new file mode 100644 index 000000000..cfb13da5a --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3.tuple; + +import java.io.Serializable; +import java.util.Objects; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * A triple consisting of three elements. + * + *

This class is an abstract implementation defining the basic API. It refers to the elements as + * 'left', 'middle' and 'right'. + * + *

Subclass implementations may be mutable or immutable. However, there is no restriction on the + * type of the stored objects that may be stored. If mutable objects are stored in the triple, then + * the triple itself effectively becomes mutable. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @since 3.2 + */ +public abstract class Triple implements Comparable>, Serializable { + + /** Serialization version */ + private static final long serialVersionUID = 1L; + + /** + * An empty array. + * + *

Consider using {@link #emptyArray()} to avoid generics warnings. + * + * @since 3.10 + */ + public static final Triple[] EMPTY_ARRAY = {}; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10 + */ + @SuppressWarnings("unchecked") + public static Triple[] emptyArray() { + return (Triple[]) EMPTY_ARRAY; + } + + /** + * Obtains an immutable triple of three objects inferring the generic types. + * + *

This factory allows the triple to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @param left the left element, may be null. + * @param middle the middle element, may be null. + * @param right the right element, may be null. + * @return a triple formed from the three parameters, not null. + */ + public static Triple of(final L left, final M middle, final R right) { + return ImmutableTriple.of(left, middle, right); + } + + /** + * Obtains an immutable triple of three non-null objects inferring the generic types. + * + *

This factory allows the triple to be created using inference to obtain the generic types. + * + * @param the left element type. + * @param the middle element type. + * @param the right element type. + * @param left the left element, may not be null. + * @param middle the middle element, may not be null. + * @param right the right element, may not be null. + * @return a triple formed from the three parameters, not null. + * @throws NullPointerException if any input is null. + * @since 3.13.0 + */ + public static Triple ofNonNull(final L left, final M middle, final R right) { + return ImmutableTriple.ofNonNull(left, middle, right); + } + + /** Constructs a new instance. */ + public Triple() { + // empty + } + + /** + * Compares the triple based on the left element, followed by the middle element, finally the + * right element. The types must be {@link Comparable}. + * + * @param other the other triple, not null. + * @return negative if this is less, zero if equal, positive if greater. + */ + @Override + public int compareTo(final Triple other) { + // Currently not used + return 0; + } + + /** + * Compares this triple to another based on the three elements. + * + * @param obj the object to compare to, null returns false. + * @return true if the elements of the triple are equal. + */ + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Triple) { + final Triple other = (Triple) obj; + return Objects.equals(getLeft(), other.getLeft()) + && Objects.equals(getMiddle(), other.getMiddle()) + && Objects.equals(getRight(), other.getRight()); + } + return false; + } + + /** + * Gets the left element from this triple. + * + * @return the left element, may be null. + */ + public abstract L getLeft(); + + /** + * Gets the middle element from this triple. + * + * @return the middle element, may be null. + */ + public abstract M getMiddle(); + + /** + * Gets the right element from this triple. + * + * @return the right element, may be null. + */ + public abstract R getRight(); + + /** + * Returns a suitable hash code. + * + *

The hash code is adapted from the definition in {@code Map.Entry}. + * + * @return the hash code. + */ + @Override + public int hashCode() { + // See Map.Entry API specification + return Objects.hashCode(getLeft()) + ^ Objects.hashCode(getMiddle()) + ^ Objects.hashCode(getRight()); + } + + /** + * Returns a String representation of this triple using the format {@code (left,middle,right)}. + * + * @return a string describing this object, not null. + */ + @Override + public String toString() { + return "(" + getLeft() + "," + getMiddle() + "," + getRight() + ")"; + } + + /** + * Formats the receiver using the given format. + * + *

This uses {@link java.util.Formattable} to perform the formatting. Three variables may be + * used to embed the left and right elements. Use {@code %1$s} for the left element, {@code %2$s} + * for the middle and {@code %3$s} for the right element. The default format used by {@code + * toString()} is {@code (%1$s,%2$s,%3$s)}. + * + * @param format the format string, optionally containing {@code %1$s}, {@code %2$s} and {@code + * %3$s}, not null. + * @return the formatted string, not null. + */ + public String toString(final String format) { + return String.format(format, getLeft(), getMiddle(), getRight()); + } +} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/read/common/block/column/DictionaryColumn.java b/java/tsfile/src/main/java/org/apache/tsfile/read/common/block/column/DictionaryColumn.java index 50a2dd1ef..376055337 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/read/common/block/column/DictionaryColumn.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/read/common/block/column/DictionaryColumn.java @@ -26,8 +26,6 @@ import org.apache.tsfile.utils.RamUsageEstimator; import org.apache.tsfile.utils.TsPrimitiveType; -import org.apache.commons.lang3.ArrayUtils; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -347,7 +345,7 @@ public Column copyPositions(int[] positions, int offset, int length) { } Column compactDictionary = dictionary.copyPositions( - ArrayUtils.toPrimitive(positionsToCopy.toArray(new Integer[0])), + positionsToCopy.stream().mapToInt(Integer::intValue).toArray(), 0, positionsToCopy.size()); if (positionsToCopy.size() == length) { @@ -512,7 +510,7 @@ public DictionaryColumn compact() { try { Column compactDictionary = dictionary.copyPositions( - ArrayUtils.toPrimitive(dictionaryPositionsToCopy.toArray(new Integer[0])), + dictionaryPositionsToCopy.stream().mapToInt(Integer::intValue).toArray(), 0, dictionaryPositionsToCopy.size()); return new DictionaryColumn( diff --git a/java/tsfile/src/main/java/org/apache/tsfile/utils/Pair.java b/java/tsfile/src/main/java/org/apache/tsfile/utils/Pair.java index 4ced2a76e..927f6efe9 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/utils/Pair.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/utils/Pair.java @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.tsfile.utils; import java.io.Serializable; diff --git a/java/tsfile/src/test/java/org/apache/tsfile/read/query/timegenerator/TsFileGeneratorForSeriesReaderByTimestamp.java b/java/tsfile/src/test/java/org/apache/tsfile/read/query/timegenerator/TsFileGeneratorForSeriesReaderByTimestamp.java index 155fe86af..11170c6c7 100755 --- a/java/tsfile/src/test/java/org/apache/tsfile/read/query/timegenerator/TsFileGeneratorForSeriesReaderByTimestamp.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/read/query/timegenerator/TsFileGeneratorForSeriesReaderByTimestamp.java @@ -25,8 +25,7 @@ import org.apache.tsfile.file.metadata.enums.CompressionType; import org.apache.tsfile.file.metadata.enums.TSEncoding; import org.apache.tsfile.read.common.Path; -import org.apache.tsfile.utils.FileUtils; -import org.apache.tsfile.utils.FileUtils.Unit; +import org.apache.tsfile.utils.FileTestUtils; import org.apache.tsfile.utils.RecordUtils; import org.apache.tsfile.utils.TsFileGeneratorForTest; import org.apache.tsfile.write.TsFileWriter; @@ -263,8 +262,11 @@ public static void writeToFile(Schema schema) throws IOException, WriteProcessEx in.close(); endTime = System.currentTimeMillis(); LOG.info("write total:{},use time:{}s", lineCount, (endTime - startTime) / 1000); - LOG.info("src file size:{}GB", FileUtils.getLocalFileByte(inputDataFile, Unit.GB)); - LOG.info("src file size:{}MB", FileUtils.getLocalFileByte(outputDataFile, Unit.MB)); + LOG.info( + "src file size:{}GB", FileTestUtils.getLocalFileByte(inputDataFile, FileTestUtils.Unit.GB)); + LOG.info( + "src file size:{}MB", + FileTestUtils.getLocalFileByte(outputDataFile, FileTestUtils.Unit.MB)); } private static Scanner getDataFile(String path) { diff --git a/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java b/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java index e3dadf3b9..8b1abe536 100644 --- a/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.tsfile.utils; -import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -27,6 +27,8 @@ import java.io.File; import java.io.IOException; +import static org.apache.commons.io.FileUtils.forceMkdirParent; + public class FilePathUtilsTest { private static final String storageGroupName = "root.group_9"; @@ -51,7 +53,7 @@ public void setUp() { tsFile = new File(fullPath); boolean success = false; try { - FileUtils.forceMkdirParent(tsFile); + forceMkdirParent(tsFile); success = tsFile.createNewFile(); } catch (IOException e) { Assert.fail(e.getMessage()); diff --git a/java/tsfile/src/test/java/org/apache/tsfile/utils/FileUtils.java b/java/tsfile/src/test/java/org/apache/tsfile/utils/FileTestUtils.java similarity index 98% rename from java/tsfile/src/test/java/org/apache/tsfile/utils/FileUtils.java rename to java/tsfile/src/test/java/org/apache/tsfile/utils/FileTestUtils.java index d6b70742b..768742bed 100644 --- a/java/tsfile/src/test/java/org/apache/tsfile/utils/FileUtils.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/utils/FileTestUtils.java @@ -26,7 +26,7 @@ * FileUtils is just used for return file attribute like file size, and contains some measurement * conversion among B, KB, MB etc. */ -public class FileUtils { +public class FileTestUtils { public static double getLocalFileByte(String filePath, Unit unit) { File f = FSFactoryProducer.getFSFactory().getFile(filePath); diff --git a/java/tsfile/src/test/java/org/apache/tsfile/utils/FileUtilsTest.java b/java/tsfile/src/test/java/org/apache/tsfile/utils/FileTestUtilsTest.java old mode 100755 new mode 100644 similarity index 58% rename from java/tsfile/src/test/java/org/apache/tsfile/utils/FileUtilsTest.java rename to java/tsfile/src/test/java/org/apache/tsfile/utils/FileTestUtilsTest.java index ec8955254..7e1245ff9 --- a/java/tsfile/src/test/java/org/apache/tsfile/utils/FileUtilsTest.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/utils/FileTestUtilsTest.java @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.tsfile.utils; import org.apache.tsfile.constant.TestConstant; @@ -25,7 +26,7 @@ import static org.junit.Assert.assertEquals; -public class FileUtilsTest { +public class FileTestUtilsTest { @Test public void testConvertUnit() { @@ -33,19 +34,26 @@ public void testConvertUnit() { long mb = kb * 1024; long gb = mb * 1024; Assert.assertEquals( - 3.0 * 1024, FileUtils.transformUnit(kb, FileUtils.Unit.B), TestConstant.double_min_delta); - assertEquals(3, FileUtils.transformUnit(kb, FileUtils.Unit.KB), TestConstant.double_min_delta); + 3.0 * 1024, + FileTestUtils.transformUnit(kb, FileTestUtils.Unit.B), + TestConstant.double_min_delta); + assertEquals( + 3, FileTestUtils.transformUnit(kb, FileTestUtils.Unit.KB), TestConstant.double_min_delta); - assertEquals(3, FileUtils.transformUnit(mb, FileUtils.Unit.MB), TestConstant.double_min_delta); - assertEquals(3, FileUtils.transformUnit(gb, FileUtils.Unit.GB), TestConstant.double_min_delta); + assertEquals( + 3, FileTestUtils.transformUnit(mb, FileTestUtils.Unit.MB), TestConstant.double_min_delta); + assertEquals( + 3, FileTestUtils.transformUnit(gb, FileTestUtils.Unit.GB), TestConstant.double_min_delta); } @Test public void testConvertToByte() { - assertEquals(3l, (long) FileUtils.transformUnitToByte(3, FileUtils.Unit.B)); - assertEquals(3l * 1024, (long) FileUtils.transformUnitToByte(3, FileUtils.Unit.KB)); - assertEquals(3l * 1024 * 1024, (long) FileUtils.transformUnitToByte(3, FileUtils.Unit.MB)); + assertEquals(3l, (long) FileTestUtils.transformUnitToByte(3, FileTestUtils.Unit.B)); + assertEquals(3l * 1024, (long) FileTestUtils.transformUnitToByte(3, FileTestUtils.Unit.KB)); + assertEquals( + 3l * 1024 * 1024, (long) FileTestUtils.transformUnitToByte(3, FileTestUtils.Unit.MB)); assertEquals( - 3l * 1024 * 1024 * 1024, (long) FileUtils.transformUnitToByte(3, FileUtils.Unit.GB)); + 3l * 1024 * 1024 * 1024, + (long) FileTestUtils.transformUnitToByte(3, FileTestUtils.Unit.GB)); } } diff --git a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathLexer.java b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathLexer.java index 4d382ccf0..272fb98e6 100644 --- a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathLexer.java +++ b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathLexer.java @@ -1,4 +1,4 @@ -// Generated from org/apache/tsfile/parser/PathLexer.g4 by ANTLR 4.9.3 +// Generated from org\apache\tsfile\parser\PathLexer.g4 by ANTLR 4.9.3 package org.apache.tsfile.parser; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.CharStream; diff --git a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParser.java b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParser.java index 5d3f00318..70ad806ce 100644 --- a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParser.java +++ b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParser.java @@ -1,4 +1,4 @@ -// Generated from org/apache/tsfile/parser/PathParser.g4 by ANTLR 4.9.3 +// Generated from org\apache\tsfile\parser\PathParser.g4 by ANTLR 4.9.3 package org.apache.tsfile.parser; import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.dfa.DFA; diff --git a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserBaseVisitor.java b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserBaseVisitor.java index 654db27af..4c5f336fe 100644 --- a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserBaseVisitor.java +++ b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserBaseVisitor.java @@ -1,4 +1,4 @@ -// Generated from org/apache/tsfile/parser/PathParser.g4 by ANTLR 4.9.3 +// Generated from org\apache\tsfile\parser\PathParser.g4 by ANTLR 4.9.3 package org.apache.tsfile.parser; import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; diff --git a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserVisitor.java b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserVisitor.java index 9b0c8e5e1..fccea3d76 100644 --- a/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserVisitor.java +++ b/java/tsfile/target/generated-sources/antlr4/org/apache/tsfile/parser/PathParserVisitor.java @@ -1,4 +1,4 @@ -// Generated from org/apache/tsfile/parser/PathParser.g4 by ANTLR 4.9.3 +// Generated from org\apache\tsfile\parser\PathParser.g4 by ANTLR 4.9.3 package org.apache.tsfile.parser; import org.antlr.v4.runtime.tree.ParseTreeVisitor; From bf7f824138c7afc6061db52d014e73a668d811aa Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 11:05:04 +0800 Subject: [PATCH 2/8] refactor --- .../org/apache/tsfile/tools/TsFileTool.java | 3 ++- .../apache/tsfile/tools/TsfiletoolsTest.java | 2 +- .../external}/commons/codec/binary/Hex.java | 2 +- .../codec/binary/MessageDigestAlgorithms.java | 2 +- .../commons/codec/binary/StringUtils.java | 2 +- .../commons/codec/digest/DigestUtils.java | 8 ++++---- .../commons/collections4/BoundedMap.java | 2 +- .../commons/collections4/CollectionUtils.java | 2 +- .../external}/commons/collections4/Get.java | 2 +- .../commons/collections4/IterableGet.java | 2 +- .../commons/collections4/IterableMap.java | 2 +- .../commons/collections4/KeyValue.java | 2 +- .../commons/collections4/MapIterator.java | 2 +- .../commons/collections4/MapUtils.java | 2 +- .../commons/collections4/OrderedIterator.java | 2 +- .../commons/collections4/OrderedMap.java | 2 +- .../collections4/OrderedMapIterator.java | 2 +- .../external}/commons/collections4/Put.java | 2 +- .../collections4/ResettableIterator.java | 2 +- .../comparators/ComparatorChain.java | 2 +- .../iterators/AbstractEmptyIterator.java | 2 +- .../iterators/AbstractEmptyMapIterator.java | 2 +- .../collections4/iterators/EmptyIterator.java | 4 ++-- .../iterators/EmptyMapIterator.java | 6 +++--- .../iterators/EmptyOrderedIterator.java | 6 +++--- .../iterators/EmptyOrderedMapIterator.java | 6 +++--- .../collections4/map/AbstractHashedMap.java | 12 +++++------ .../collections4/map/AbstractLinkedMap.java | 16 +++++++-------- .../commons/collections4/map/LRUMap.java | 7 ++++--- .../external}/commons/io/Charsets.java | 2 +- .../commons/io/FileExistsException.java | 2 +- .../external}/commons/io/FileUtils.java | 20 ++++++++++--------- .../external}/commons/io/FilenameUtils.java | 2 +- .../external}/commons/io/IOCase.java | 2 +- .../external}/commons/io/IOExceptionList.java | 2 +- .../commons/io/IOIndexedException.java | 2 +- .../external}/commons/io/IOUtils.java | 12 +++++------ .../commons/io/RandomAccessFileMode.java | 2 +- .../commons/io/RandomAccessFiles.java | 2 +- .../commons/io/build/AbstractOrigin.java | 12 +++++------ .../io/build/AbstractOriginSupplier.java | 20 +++++++++---------- .../io/build/AbstractStreamBuilder.java | 8 ++++---- .../commons/io/build/AbstractSupplier.java | 4 ++-- .../commons/io/charset/CharsetDecoders.java | 2 +- .../commons/io/charset/CharsetEncoders.java | 2 +- .../external}/commons/io/file/Counters.java | 2 +- .../commons/io/file/CountingPathVisitor.java | 12 +++++------ .../commons/io/file/DeleteOption.java | 2 +- .../commons/io/file/DeletingPathVisitor.java | 4 ++-- .../external}/commons/io/file/PathFilter.java | 2 +- .../external}/commons/io/file/PathUtils.java | 6 +++--- .../commons/io/file/PathVisitor.java | 2 +- .../commons/io/file/SimplePathVisitor.java | 4 ++-- .../commons/io/file/StandardDeleteOption.java | 4 ++-- .../io/filefilter/AbstractFileFilter.java | 8 ++++---- .../commons/io/filefilter/AndFileFilter.java | 2 +- .../io/filefilter/ConditionalFileFilter.java | 2 +- .../io/filefilter/FalseFileFilter.java | 2 +- .../commons/io/filefilter/FileFileFilter.java | 2 +- .../commons/io/filefilter/IOFileFilter.java | 4 ++-- .../commons/io/filefilter/NotFileFilter.java | 2 +- .../commons/io/filefilter/OrFileFilter.java | 2 +- .../io/filefilter/SuffixFileFilter.java | 4 ++-- .../io/filefilter/SymbolicLinkFileFilter.java | 2 +- .../commons/io/filefilter/TrueFileFilter.java | 2 +- .../commons/io/function/Constants.java | 2 +- .../external}/commons/io/function/Erase.java | 2 +- .../commons/io/function/IOBaseStream.java | 2 +- .../io/function/IOBaseStreamAdapter.java | 2 +- .../commons/io/function/IOBiConsumer.java | 2 +- .../commons/io/function/IOBiFunction.java | 2 +- .../commons/io/function/IOBinaryOperator.java | 2 +- .../commons/io/function/IOComparator.java | 2 +- .../commons/io/function/IOConsumer.java | 4 ++-- .../commons/io/function/IOFunction.java | 2 +- .../commons/io/function/IOIntSupplier.java | 2 +- .../commons/io/function/IOIterator.java | 2 +- .../io/function/IOIteratorAdapter.java | 2 +- .../commons/io/function/IOLongSupplier.java | 2 +- .../commons/io/function/IOPredicate.java | 2 +- .../commons/io/function/IOQuadFunction.java | 2 +- .../commons/io/function/IORunnable.java | 2 +- .../commons/io/function/IOSpliterator.java | 2 +- .../io/function/IOSpliteratorAdapter.java | 2 +- .../commons/io/function/IOStream.java | 4 ++-- .../commons/io/function/IOStreamAdapter.java | 2 +- .../commons/io/function/IOStreams.java | 6 +++--- .../commons/io/function/IOSupplier.java | 2 +- .../commons/io/function/IOTriConsumer.java | 2 +- .../commons/io/function/IOTriFunction.java | 2 +- .../commons/io/function/IOUnaryOperator.java | 2 +- .../commons/io/function/Uncheck.java | 2 +- .../io/function/UncheckedIOBaseStream.java | 2 +- .../io/function/UncheckedIOIterator.java | 2 +- .../io/function/UncheckedIOSpliterator.java | 2 +- .../commons/io/input/ClosedInputStream.java | 6 +++--- .../commons/io/input/ReaderInputStream.java | 16 +++++++-------- .../UnsynchronizedByteArrayInputStream.java | 6 +++--- .../output/AbstractByteArrayOutputStream.java | 8 ++++---- .../io/output/ByteArrayOutputStream.java | 2 +- .../commons/io/output/NullOutputStream.java | 2 +- .../io/output/StringBuilderWriter.java | 2 +- .../io/output/ThresholdingOutputStream.java | 6 +++--- .../UnsynchronizedByteArrayOutputStream.java | 10 +++++----- .../commons/io/output/WriterOutputStream.java | 12 +++++------ .../external}/commons/lang3/ArrayFill.java | 2 +- .../external}/commons/lang3/ArrayUtils.java | 2 +- .../commons/lang3/CharSequenceUtils.java | 2 +- .../external}/commons/lang3/ClassUtils.java | 2 +- .../lang3/NotImplementedException.java | 2 +- .../external}/commons/lang3/ObjectUtils.java | 2 +- .../external}/commons/lang3/StringUtils.java | 4 ++-- .../external}/commons/lang3/Strings.java | 2 +- .../commons/lang3/SystemProperties.java | 4 ++-- .../external}/commons/lang3/SystemUtils.java | 2 +- .../external}/commons/lang3/Validate.java | 2 +- .../lang3/exception/ExceptionUtils.java | 2 +- .../lang3/function/FailableBiConsumer.java | 2 +- .../lang3/function/FailableBiFunction.java | 2 +- .../lang3/function/FailableFunction.java | 2 +- .../commons/lang3/function/Suppliers.java | 2 +- .../commons/lang3/function/TriFunction.java | 2 +- .../commons/lang3/math/NumberUtils.java | 4 ++-- .../commons/lang3/tuple/ImmutablePair.java | 2 +- .../commons/lang3/tuple/ImmutableTriple.java | 2 +- .../external}/commons/lang3/tuple/Pair.java | 6 +++--- .../external}/commons/lang3/tuple/Triple.java | 2 +- .../fileSystem/fsFactory/LocalFSFactory.java | 2 +- .../org/apache/tsfile/read/common/Path.java | 5 ++--- .../read/common/parser/PathVisitor.java | 3 +-- .../tsfile/write/v4/TsFileWriterBuilder.java | 3 +-- .../tsfile/write/writer/TsFileIOWriter.java | 2 +- .../reader/chunk/TableChunkReaderTest.java | 2 +- .../tsfile/tableview/TableViewTest.java | 2 +- .../tsfile/utils/FilePathUtilsTest.java | 2 +- .../TsFileIOWriterMemoryControlTest.java | 2 +- 136 files changed, 245 insertions(+), 244 deletions(-) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/codec/binary/Hex.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/codec/binary/MessageDigestAlgorithms.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/codec/binary/StringUtils.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/codec/digest/DigestUtils.java (93%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/BoundedMap.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/CollectionUtils.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/Get.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/IterableGet.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/IterableMap.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/KeyValue.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/MapIterator.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/MapUtils.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/OrderedIterator.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/OrderedMap.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/OrderedMapIterator.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/Put.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/ResettableIterator.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/comparators/ComparatorChain.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/iterators/AbstractEmptyIterator.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/iterators/AbstractEmptyMapIterator.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/iterators/EmptyIterator.java (93%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/iterators/EmptyMapIterator.java (88%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/iterators/EmptyOrderedIterator.java (87%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/iterators/EmptyOrderedMapIterator.java (88%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/map/AbstractHashedMap.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/map/AbstractLinkedMap.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/collections4/map/LRUMap.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/Charsets.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/FileExistsException.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/FileUtils.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/FilenameUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/IOCase.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/IOExceptionList.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/IOIndexedException.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/IOUtils.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/RandomAccessFileMode.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/RandomAccessFiles.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/build/AbstractOrigin.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/build/AbstractOriginSupplier.java (90%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/build/AbstractStreamBuilder.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/build/AbstractSupplier.java (91%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/charset/CharsetDecoders.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/charset/CharsetEncoders.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/Counters.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/CountingPathVisitor.java (93%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/DeleteOption.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/DeletingPathVisitor.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/PathFilter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/PathUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/PathVisitor.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/SimplePathVisitor.java (94%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/file/StandardDeleteOption.java (93%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/AbstractFileFilter.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/AndFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/ConditionalFileFilter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/FalseFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/FileFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/IOFileFilter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/NotFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/OrFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/SuffixFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/SymbolicLinkFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/filefilter/TrueFileFilter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/Constants.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/Erase.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOBaseStream.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOBaseStreamAdapter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOBiConsumer.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOBiFunction.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOBinaryOperator.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOComparator.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOConsumer.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOFunction.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOIntSupplier.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOIterator.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOIteratorAdapter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOLongSupplier.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOPredicate.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOQuadFunction.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IORunnable.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOSpliterator.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOSpliteratorAdapter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOStream.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOStreamAdapter.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOStreams.java (94%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOSupplier.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOTriConsumer.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOTriFunction.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/IOUnaryOperator.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/Uncheck.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/UncheckedIOBaseStream.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/UncheckedIOIterator.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/function/UncheckedIOSpliterator.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/input/ClosedInputStream.java (90%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/input/ReaderInputStream.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/input/UnsynchronizedByteArrayInputStream.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/AbstractByteArrayOutputStream.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/ByteArrayOutputStream.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/NullOutputStream.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/StringBuilderWriter.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/ThresholdingOutputStream.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/UnsynchronizedByteArrayOutputStream.java (95%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/io/output/WriterOutputStream.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/ArrayFill.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/ArrayUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/CharSequenceUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/ClassUtils.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/NotImplementedException.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/ObjectUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/StringUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/Strings.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/SystemProperties.java (96%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/SystemUtils.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/Validate.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/exception/ExceptionUtils.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/function/FailableBiConsumer.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/function/FailableBiFunction.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/function/FailableFunction.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/function/Suppliers.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/function/TriFunction.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/math/NumberUtils.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/tuple/ImmutablePair.java (99%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/tuple/ImmutableTriple.java (98%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/tuple/Pair.java (97%) rename java/tsfile/src/main/java/org/apache/{ => tsfile/external}/commons/lang3/tuple/Triple.java (99%) diff --git a/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java b/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java index 559c8377e..dc993dff5 100644 --- a/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java +++ b/java/tools/src/main/java/org/apache/tsfile/tools/TsFileTool.java @@ -16,10 +16,12 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.tsfile.tools; import org.apache.tsfile.enums.ColumnCategory; import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.external.commons.io.FilenameUtils; import org.apache.tsfile.file.metadata.TableSchema; import org.apache.tsfile.file.metadata.enums.CompressionType; import org.apache.tsfile.file.metadata.enums.TSEncoding; @@ -35,7 +37,6 @@ import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/java/tools/src/test/java/org/apache/tsfile/tools/TsfiletoolsTest.java b/java/tools/src/test/java/org/apache/tsfile/tools/TsfiletoolsTest.java index ddbe32e8a..5fb09c757 100644 --- a/java/tools/src/test/java/org/apache/tsfile/tools/TsfiletoolsTest.java +++ b/java/tools/src/test/java/org/apache/tsfile/tools/TsfiletoolsTest.java @@ -19,6 +19,7 @@ package org.apache.tsfile.tools; +import org.apache.tsfile.external.commons.io.FileUtils; import org.apache.tsfile.read.TsFileSequenceReader; import org.apache.tsfile.read.common.block.TsBlock; import org.apache.tsfile.read.controller.CachedChunkLoaderImpl; @@ -26,7 +27,6 @@ import org.apache.tsfile.read.query.executor.TableQueryExecutor; import org.apache.tsfile.read.reader.block.TsBlockReader; -import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/Hex.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/Hex.java index 01b92eee8..982b519c1 100644 --- a/java/tsfile/src/main/java/org/apache/commons/codec/binary/Hex.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/Hex.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.codec.binary; +package org.apache.tsfile.external.commons.codec.binary; ///////////////////////////////////////////////////////////////////////////////////////////////// // IoTDB diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/MessageDigestAlgorithms.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/MessageDigestAlgorithms.java index f27532699..738af14d0 100644 --- a/java/tsfile/src/main/java/org/apache/commons/codec/binary/MessageDigestAlgorithms.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/MessageDigestAlgorithms.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.codec.binary; +package org.apache.tsfile.external.commons.codec.binary; import java.security.MessageDigest; diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/StringUtils.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/StringUtils.java index fe13454fe..5106d8b40 100644 --- a/java/tsfile/src/main/java/org/apache/commons/codec/binary/StringUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/binary/StringUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.codec.binary; +package org.apache.tsfile.external.commons.codec.binary; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; diff --git a/java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java similarity index 93% rename from java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java index 5f1b742c0..d2dfa6c50 100644 --- a/java/tsfile/src/main/java/org/apache/commons/codec/digest/DigestUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.apache.commons.codec.digest; +package org.apache.tsfile.external.commons.codec.digest; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.binary.MessageDigestAlgorithms; -import org.apache.commons.codec.binary.StringUtils; +import org.apache.tsfile.external.commons.codec.binary.Hex; +import org.apache.tsfile.external.commons.codec.binary.MessageDigestAlgorithms; +import org.apache.tsfile.external.commons.codec.binary.StringUtils; import java.io.IOException; import java.io.InputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/BoundedMap.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/BoundedMap.java index 8ac6bc769..d0a5ab164 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/BoundedMap.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/BoundedMap.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; /** * Defines a map that is bounded in size. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/CollectionUtils.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/CollectionUtils.java index 37eb6806d..db35216d9 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/CollectionUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/CollectionUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Collection; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/Get.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/Get.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/collections4/Get.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/Get.java index 7f14acb45..adb43c4ec 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/Get.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/Get.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Collection; import java.util.Set; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/IterableGet.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/IterableGet.java index 485acc7df..5767c7495 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/IterableGet.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/IterableGet.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; /** * The "read" subset of the {@link java.util.Map} interface. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/IterableMap.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/IterableMap.java index c46366ffb..e7ad28ca6 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/IterableMap.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/IterableMap.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Map; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/KeyValue.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/KeyValue.java index 1956c7a67..d173b68e0 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/KeyValue.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/KeyValue.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; /** * Defines a simple key value pair. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/MapIterator.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/MapIterator.java index 68198f7d8..9f9de0a7a 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/MapIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/MapIterator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Iterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/MapUtils.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/MapUtils.java index d9240870a..d8e941181 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/MapUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/MapUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; ///////////////////////////////////////////////////////////////////////////////////////////////// // IoTDB diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedIterator.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedIterator.java index 44aa020f3..7f81134ee 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedIterator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Iterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedMap.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedMap.java index 7239f6deb..f87f00579 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMap.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedMap.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; /** * Defines a map that maintains order and allows both forward and backward iteration through that diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedMapIterator.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedMapIterator.java index 72a4f7b87..6f3b4368d 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/OrderedMapIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/OrderedMapIterator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; /** * Defines an iterator that operates over an ordered Map. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/Put.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/Put.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/collections4/Put.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/Put.java index 2bff27d5e..9bab97739 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/Put.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/Put.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Map; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/ResettableIterator.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/ResettableIterator.java index c798c3b30..2b8b2ec16 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/ResettableIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/ResettableIterator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4; +package org.apache.tsfile.external.commons.collections4; import java.util.Iterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java index 69de70464..7edc25538 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/comparators/ComparatorChain.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.comparators; +package org.apache.tsfile.external.commons.collections4.comparators; import java.io.Serializable; import java.util.ArrayList; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java index b16d8b4a8..95ae7b159 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.iterators; +package org.apache.tsfile.external.commons.collections4.iterators; import java.util.NoSuchElementException; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyMapIterator.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyMapIterator.java index cb9b0b604..ae45cf5c6 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/AbstractEmptyMapIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyMapIterator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.iterators; +package org.apache.tsfile.external.commons.collections4.iterators; /** * Provides an implementation of an empty map iterator. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyIterator.java similarity index 93% rename from java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyIterator.java index 1342809e2..f108487c3 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyIterator.java @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.iterators; +package org.apache.tsfile.external.commons.collections4.iterators; -import org.apache.commons.collections4.ResettableIterator; +import org.apache.tsfile.external.commons.collections4.ResettableIterator; import java.util.Iterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyMapIterator.java similarity index 88% rename from java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyMapIterator.java index 18acaace4..3d27b12a2 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyMapIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyMapIterator.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.iterators; +package org.apache.tsfile.external.commons.collections4.iterators; -import org.apache.commons.collections4.MapIterator; -import org.apache.commons.collections4.ResettableIterator; +import org.apache.tsfile.external.commons.collections4.MapIterator; +import org.apache.tsfile.external.commons.collections4.ResettableIterator; /** * Provides an implementation of an empty map iterator. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyOrderedIterator.java similarity index 87% rename from java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyOrderedIterator.java index 90582e208..ea144b265 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyOrderedIterator.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.iterators; +package org.apache.tsfile.external.commons.collections4.iterators; -import org.apache.commons.collections4.OrderedIterator; -import org.apache.commons.collections4.ResettableIterator; +import org.apache.tsfile.external.commons.collections4.OrderedIterator; +import org.apache.tsfile.external.commons.collections4.ResettableIterator; /** * Provides an implementation of an empty ordered iterator. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyOrderedMapIterator.java similarity index 88% rename from java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyOrderedMapIterator.java index 9a3682e18..8a1b502c2 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/iterators/EmptyOrderedMapIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/EmptyOrderedMapIterator.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.iterators; +package org.apache.tsfile.external.commons.collections4.iterators; -import org.apache.commons.collections4.OrderedMapIterator; -import org.apache.commons.collections4.ResettableIterator; +import org.apache.tsfile.external.commons.collections4.OrderedMapIterator; +import org.apache.tsfile.external.commons.collections4.ResettableIterator; /** * Provides an implementation of an empty ordered map iterator. diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/AbstractHashedMap.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/AbstractHashedMap.java index a3e9a1454..47718bbb9 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractHashedMap.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/AbstractHashedMap.java @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.map; +package org.apache.tsfile.external.commons.collections4.map; -import org.apache.commons.collections4.IterableMap; -import org.apache.commons.collections4.KeyValue; -import org.apache.commons.collections4.MapIterator; -import org.apache.commons.collections4.iterators.EmptyIterator; -import org.apache.commons.collections4.iterators.EmptyMapIterator; +import org.apache.tsfile.external.commons.collections4.IterableMap; +import org.apache.tsfile.external.commons.collections4.KeyValue; +import org.apache.tsfile.external.commons.collections4.MapIterator; +import org.apache.tsfile.external.commons.collections4.iterators.EmptyIterator; +import org.apache.tsfile.external.commons.collections4.iterators.EmptyMapIterator; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/AbstractLinkedMap.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/AbstractLinkedMap.java index e27e21693..a60e670ba 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/map/AbstractLinkedMap.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/AbstractLinkedMap.java @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.map; - -import org.apache.commons.collections4.OrderedIterator; -import org.apache.commons.collections4.OrderedMap; -import org.apache.commons.collections4.OrderedMapIterator; -import org.apache.commons.collections4.ResettableIterator; -import org.apache.commons.collections4.iterators.EmptyOrderedIterator; -import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator; +package org.apache.tsfile.external.commons.collections4.map; + +import org.apache.tsfile.external.commons.collections4.OrderedIterator; +import org.apache.tsfile.external.commons.collections4.OrderedMap; +import org.apache.tsfile.external.commons.collections4.OrderedMapIterator; +import org.apache.tsfile.external.commons.collections4.ResettableIterator; +import org.apache.tsfile.external.commons.collections4.iterators.EmptyOrderedIterator; +import org.apache.tsfile.external.commons.collections4.iterators.EmptyOrderedMapIterator; import java.util.ConcurrentModificationException; import java.util.Iterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/LRUMap.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/LRUMap.java index 2b4371fbc..4ae916a64 100644 --- a/java/tsfile/src/main/java/org/apache/commons/collections4/map/LRUMap.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/map/LRUMap.java @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.collections4.map; +package org.apache.tsfile.external.commons.collections4.map; -import org.apache.commons.collections4.BoundedMap; +import org.apache.tsfile.external.commons.collections4.BoundedMap; import java.io.IOException; import java.io.ObjectInputStream; @@ -36,7 +36,8 @@ * #get(Object)} stand a very good chance of modifying the map's iteration order and thus * invalidating any iterators currently in use. It is therefore suggested that iterations over an * {@link LRUMap} instance access entry values only through a {@link - * org.apache.commons.collections4.MapIterator MapIterator} or {@link #entrySet()} iterator. + * org.apache.tsfile.external.commons.collections4.MapIterator MapIterator} or {@link #entrySet()} + * iterator. * *

The map implements OrderedMap and entries may be queried using the bidirectional * OrderedMapIterator. The order returned is least recently used to most recently used. diff --git a/java/tsfile/src/main/java/org/apache/commons/io/Charsets.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/Charsets.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/Charsets.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/Charsets.java index f73e3bcf4..2429385f2 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/Charsets.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/Charsets.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java index 6e6098be7..e441a782a 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/FileExistsException.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.io.File; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java index f3f1f9cb2..1f89607f0 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/FileUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java @@ -12,16 +12,16 @@ * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; -import org.apache.commons.io.file.Counters; -import org.apache.commons.io.file.PathUtils; -import org.apache.commons.io.file.StandardDeleteOption; -import org.apache.commons.io.filefilter.FileFileFilter; -import org.apache.commons.io.filefilter.IOFileFilter; -import org.apache.commons.io.filefilter.SuffixFileFilter; -import org.apache.commons.io.function.IOConsumer; -import org.apache.commons.io.function.Uncheck; +import org.apache.tsfile.external.commons.io.file.Counters; +import org.apache.tsfile.external.commons.io.file.PathUtils; +import org.apache.tsfile.external.commons.io.file.StandardDeleteOption; +import org.apache.tsfile.external.commons.io.filefilter.FileFileFilter; +import org.apache.tsfile.external.commons.io.filefilter.IOFileFilter; +import org.apache.tsfile.external.commons.io.filefilter.SuffixFileFilter; +import org.apache.tsfile.external.commons.io.function.IOConsumer; +import org.apache.tsfile.external.commons.io.function.Uncheck; import java.io.File; import java.io.FileFilter; @@ -881,4 +881,6 @@ private static File requireDirectoryIfExists(final File directory, final String } return directory; } + + } diff --git a/java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FilenameUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FilenameUtils.java index e3c152fac..fb3279445 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/FilenameUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FilenameUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.io.File; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOCase.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOCase.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/IOCase.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOCase.java index 21e3e11e0..c3e5a042c 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/IOCase.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOCase.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.util.Objects; import java.util.stream.Stream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOExceptionList.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOExceptionList.java index bc20ec085..30d8e35cd 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/IOExceptionList.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOExceptionList.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.io.IOException; import java.util.ArrayList; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOIndexedException.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOIndexedException.java index 906eec52d..64a319ea8 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/IOIndexedException.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOIndexedException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java index 51c7d0bb5..3ae2f4467 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/IOUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java @@ -17,13 +17,13 @@ * under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; -import org.apache.commons.io.function.IOTriFunction; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.commons.io.output.StringBuilderWriter; -import org.apache.commons.io.output.ThresholdingOutputStream; -import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; +import org.apache.tsfile.external.commons.io.function.IOTriFunction; +import org.apache.tsfile.external.commons.io.output.ByteArrayOutputStream; +import org.apache.tsfile.external.commons.io.output.StringBuilderWriter; +import org.apache.tsfile.external.commons.io.output.ThresholdingOutputStream; +import org.apache.tsfile.external.commons.io.output.UnsynchronizedByteArrayOutputStream; import java.io.BufferedInputStream; import java.io.BufferedReader; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/RandomAccessFileMode.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/RandomAccessFileMode.java index 991ccba36..13a1b3143 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFileMode.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/RandomAccessFileMode.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.io.File; import java.io.FileNotFoundException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/RandomAccessFiles.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/RandomAccessFiles.java index 3de254610..e69f79a1d 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/RandomAccessFiles.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/RandomAccessFiles.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io; +package org.apache.tsfile.external.commons.io; import java.io.IOException; import java.io.RandomAccessFile; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java index b7803f6c9..2ff4e7184 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOrigin.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java @@ -15,13 +15,13 @@ * limitations under the License. */ -package org.apache.commons.io.build; +package org.apache.tsfile.external.commons.io.build; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.RandomAccessFileMode; -import org.apache.commons.io.RandomAccessFiles; -import org.apache.commons.io.input.ReaderInputStream; -import org.apache.commons.io.output.WriterOutputStream; +import org.apache.tsfile.external.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.RandomAccessFileMode; +import org.apache.tsfile.external.commons.io.RandomAccessFiles; +import org.apache.tsfile.external.commons.io.input.ReaderInputStream; +import org.apache.tsfile.external.commons.io.output.WriterOutputStream; import java.io.ByteArrayInputStream; import java.io.File; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java similarity index 90% rename from java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java index ce7e18973..5ab4bca32 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java @@ -15,17 +15,17 @@ * limitations under the License. */ -package org.apache.commons.io.build; +package org.apache.tsfile.external.commons.io.build; -import org.apache.commons.io.build.AbstractOrigin.ByteArrayOrigin; -import org.apache.commons.io.build.AbstractOrigin.CharSequenceOrigin; -import org.apache.commons.io.build.AbstractOrigin.FileOrigin; -import org.apache.commons.io.build.AbstractOrigin.InputStreamOrigin; -import org.apache.commons.io.build.AbstractOrigin.OutputStreamOrigin; -import org.apache.commons.io.build.AbstractOrigin.PathOrigin; -import org.apache.commons.io.build.AbstractOrigin.ReaderOrigin; -import org.apache.commons.io.build.AbstractOrigin.URIOrigin; -import org.apache.commons.io.build.AbstractOrigin.WriterOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.ByteArrayOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.CharSequenceOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.FileOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.InputStreamOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.OutputStreamOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.PathOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.ReaderOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.URIOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin.WriterOrigin; import java.io.File; import java.io.InputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java index 23e26b4cb..c637fe1bb 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.apache.commons.io.build; +package org.apache.tsfile.external.commons.io.build; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.file.PathUtils; +import org.apache.tsfile.external.commons.io.Charsets; +import org.apache.tsfile.external.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.file.PathUtils; import java.io.IOException; import java.io.InputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractSupplier.java similarity index 91% rename from java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractSupplier.java index be2aeb148..fdb42d6a6 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/build/AbstractSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractSupplier.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.build; +package org.apache.tsfile.external.commons.io.build; -import org.apache.commons.io.function.IOSupplier; +import org.apache.tsfile.external.commons.io.function.IOSupplier; /** * Abstracts supplying an instance of {@code T}. Use to implement the builder pattern. diff --git a/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/charset/CharsetDecoders.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/charset/CharsetDecoders.java index 5d7b465cb..b7c356c50 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/charset/CharsetDecoders.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.charset; +package org.apache.tsfile.external.commons.io.charset; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/charset/CharsetEncoders.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/charset/CharsetEncoders.java index 8a37925bf..902ba2843 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/charset/CharsetEncoders.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.charset; +package org.apache.tsfile.external.commons.io.charset; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/Counters.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/Counters.java index d969eb11f..3c2fcf60e 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/Counters.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/Counters.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; import java.math.BigInteger; import java.util.Objects; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java similarity index 93% rename from java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java index d4ac0a111..5d092a652 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java @@ -15,13 +15,13 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; -import org.apache.commons.io.file.Counters.PathCounters; -import org.apache.commons.io.filefilter.IOFileFilter; -import org.apache.commons.io.filefilter.SymbolicLinkFileFilter; -import org.apache.commons.io.filefilter.TrueFileFilter; -import org.apache.commons.io.function.IOBiFunction; +import org.apache.tsfile.external.commons.io.file.Counters.PathCounters; +import org.apache.tsfile.external.commons.io.filefilter.IOFileFilter; +import org.apache.tsfile.external.commons.io.filefilter.SymbolicLinkFileFilter; +import org.apache.tsfile.external.commons.io.filefilter.TrueFileFilter; +import org.apache.tsfile.external.commons.io.function.IOBiFunction; import java.io.IOException; import java.math.BigInteger; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeleteOption.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeleteOption.java index 97e0ebcd1..ce0aee7fe 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/DeleteOption.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeleteOption.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; /** * An object that configures how to delete a file. diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java index d671d68c4..891e310bb 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; -import org.apache.commons.io.file.Counters.PathCounters; +import org.apache.tsfile.external.commons.io.file.Counters.PathCounters; import java.io.IOException; import java.nio.file.FileVisitResult; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathFilter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathFilter.java index b30c67fda..5123b846b 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/PathFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathFilter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; import java.nio.file.FileVisitResult; import java.nio.file.Path; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java index 4a1696e03..9dc837800 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java @@ -17,10 +17,10 @@ * under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; -import org.apache.commons.io.function.IOFunction; -import org.apache.commons.io.function.IOSupplier; +import org.apache.tsfile.external.commons.io.function.IOFunction; +import org.apache.tsfile.external.commons.io.function.IOSupplier; import java.io.IOException; import java.io.InputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathVisitor.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathVisitor.java index c58237df5..931d630ae 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/PathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathVisitor.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; import java.nio.file.FileVisitor; import java.nio.file.Path; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java similarity index 94% rename from java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java index ffc0ed604..578e81f7c 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/SimplePathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; -import org.apache.commons.io.function.IOBiFunction; +import org.apache.tsfile.external.commons.io.function.IOBiFunction; import java.io.IOException; import java.nio.file.FileVisitResult; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/StandardDeleteOption.java similarity index 93% rename from java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/StandardDeleteOption.java index aa6403f95..9c619d7a2 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/StandardDeleteOption.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.file; +package org.apache.tsfile.external.commons.io.file; -import org.apache.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.IOUtils; import java.util.stream.Stream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AbstractFileFilter.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AbstractFileFilter.java index 179a4ac71..9b184a914 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AbstractFileFilter.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; -import org.apache.commons.io.file.PathFilter; -import org.apache.commons.io.file.PathVisitor; -import org.apache.commons.io.function.IOSupplier; +import org.apache.tsfile.external.commons.io.file.PathFilter; +import org.apache.tsfile.external.commons.io.file.PathVisitor; +import org.apache.tsfile.external.commons.io.function.IOSupplier; import java.io.File; import java.io.FileFilter; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java index 0657aaf49..7b83f1007 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.FileFilter; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java index 52143d384..5e8d34c73 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.util.List; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java index c61203015..2801b1d18 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FileFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FileFileFilter.java index 549623175..6fa6f717e 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FileFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java index ed5fde7be..01c8ea114 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; -import org.apache.commons.io.file.PathFilter; +import org.apache.tsfile.external.commons.io.file.PathFilter; import java.io.File; import java.io.FileFilter; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/NotFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/NotFileFilter.java index 3943c2871..8a81915ea 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/NotFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java index 5de7792e0..8f1a72477 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.FileFilter; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java index 8fa74d74e..ba3c50c56 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; -import org.apache.commons.io.IOCase; +import org.apache.tsfile.external.commons.io.IOCase; import java.io.File; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SymbolicLinkFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SymbolicLinkFileFilter.java index 46c33a8c1..821aade62 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SymbolicLinkFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java index 54a8752b6..38250ec6c 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.filefilter; +package org.apache.tsfile.external.commons.io.filefilter; import java.io.File; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Constants.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Constants.java index 78f8fa2f9..1041a3286 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/Constants.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Constants.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; /** Defines package-private constants. */ final class Constants { diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Erase.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Erase.java index d19433edb..1f53d7d82 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/Erase.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Erase.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java index 6732b6d83..532f3add0 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.Closeable; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStreamAdapter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStreamAdapter.java index 7b5369217..619424ba0 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBaseStreamAdapter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStreamAdapter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.util.Objects; import java.util.stream.BaseStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java index 737bef50d..1561b0b90 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiConsumer.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java index a4e2da838..1a53c60ea 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBiFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java index fb8a57fef..595b3b46e 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOBinaryOperator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOComparator.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOComparator.java index de14d1d4d..7a6fdc0c8 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOComparator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOComparator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOConsumer.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOConsumer.java index 5e1537082..fe043875b 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOConsumer.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOConsumer.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; -import org.apache.commons.io.IOExceptionList; +import org.apache.tsfile.external.commons.io.IOExceptionList; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java index d821ae4c6..c9c153208 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java index ee028feb1..a136e7cde 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIntSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java index 0f14a66fa..24a25982f 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIteratorAdapter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIteratorAdapter.java index 2cad5ca68..36734f2cb 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOIteratorAdapter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIteratorAdapter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.util.Iterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java index cfef2a440..e3cd240c7 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOLongSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.util.function.LongSupplier; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java index 4bab3def4..9f51285f8 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOPredicate.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOQuadFunction.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOQuadFunction.java index a09d438e3..c98abee06 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOQuadFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOQuadFunction.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.util.function.Function; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IORunnable.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IORunnable.java index f991e1463..a7c863795 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IORunnable.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IORunnable.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java index c066fdf5c..4f06caa37 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliteratorAdapter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliteratorAdapter.java index 9874206d9..06463b3eb 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliteratorAdapter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.util.Objects; import java.util.Spliterator; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStream.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStream.java index 2318b1d85..75804cddf 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStream.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; -import org.apache.commons.io.IOExceptionList; +import org.apache.tsfile.external.commons.io.IOExceptionList; import java.io.IOException; import java.util.ArrayList; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStreamAdapter.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStreamAdapter.java index c5aeb62fd..9029d304e 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreamAdapter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStreamAdapter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.util.stream.Stream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStreams.java similarity index 94% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStreams.java index 32583e804..26e35dde9 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOStreams.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOStreams.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; -import org.apache.commons.io.IOExceptionList; -import org.apache.commons.io.IOIndexedException; +import org.apache.tsfile.external.commons.io.IOExceptionList; +import org.apache.tsfile.external.commons.io.IOIndexedException; import java.io.IOException; import java.util.function.BiFunction; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java index 8dac7856e..1641072d3 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java index 3088d7e32..4af5dcd58 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriConsumer.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.util.Objects; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java index 8cd850070..e1aae3f26 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOTriFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.util.Objects; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java index 30660a9c4..e11fea3fa 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/IOUnaryOperator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Uncheck.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Uncheck.java index 244c340c3..45e8c1595 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/Uncheck.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/Uncheck.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java index cfa4e12dc..c74f3e26a 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOBaseStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOIterator.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOIterator.java index e88c445fd..48f560958 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOIterator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java index 2f1875747..cd3e310ef 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/function/UncheckedIOSpliterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.io.function; +package org.apache.tsfile.external.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ClosedInputStream.java similarity index 90% rename from java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ClosedInputStream.java index e5f2dd665..69ce063e6 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/input/ClosedInputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ClosedInputStream.java @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.input; +package org.apache.tsfile.external.commons.io.input; -import org.apache.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.IOUtils; import java.io.InputStream; -import static org.apache.commons.io.IOUtils.EOF; +import static org.apache.tsfile.external.commons.io.IOUtils.EOF; /** * Always returns {@link IOUtils#EOF} to all attempts to read something from the stream. diff --git a/java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java index e164c55a0..0cfd018c6 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/input/ReaderInputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.input; +package org.apache.tsfile.external.commons.io.input; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.build.AbstractOrigin; -import org.apache.commons.io.build.AbstractStreamBuilder; -import org.apache.commons.io.charset.CharsetEncoders; +import org.apache.tsfile.external.commons.io.Charsets; +import org.apache.tsfile.external.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractStreamBuilder; +import org.apache.tsfile.external.commons.io.charset.CharsetEncoders; import java.io.IOException; import java.io.InputStream; @@ -33,7 +33,7 @@ import java.nio.charset.CodingErrorAction; import java.util.Objects; -import static org.apache.commons.io.IOUtils.EOF; +import static org.apache.tsfile.external.commons.io.IOUtils.EOF; /** * {@link InputStream} implementation that reads a character stream from a {@link Reader} and @@ -84,7 +84,7 @@ * *

Instances of {@link ReaderInputStream} are not thread safe. * - * @see org.apache.commons.io.output.WriterOutputStream + * @see org.apache.tsfile.external.commons.io.output.WriterOutputStream * @since 2.0 */ public class ReaderInputStream extends InputStream { diff --git a/java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/UnsynchronizedByteArrayInputStream.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/UnsynchronizedByteArrayInputStream.java index 7d54e2dd1..72dd1b02f 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/UnsynchronizedByteArrayInputStream.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.input; +package org.apache.tsfile.external.commons.io.input; -import org.apache.commons.io.build.AbstractOrigin; -import org.apache.commons.io.build.AbstractStreamBuilder; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractStreamBuilder; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/AbstractByteArrayOutputStream.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/AbstractByteArrayOutputStream.java index e3b789e8c..a75302bcc 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/AbstractByteArrayOutputStream.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.input.ClosedInputStream; +import org.apache.tsfile.external.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.input.ClosedInputStream; import java.io.IOException; import java.io.InputStream; @@ -29,7 +29,7 @@ import java.util.Collections; import java.util.List; -import static org.apache.commons.io.IOUtils.EOF; +import static org.apache.tsfile.external.commons.io.IOUtils.EOF; /** * This is the base class for implementing an output stream in which the data is written into a byte diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java index 662506e13..e33d69b98 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; import java.io.BufferedInputStream; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/NullOutputStream.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/NullOutputStream.java index 6adfeafe6..0c9467948 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/NullOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/NullOutputStream.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; import java.io.IOException; import java.io.OutputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java index ab5210a90..627f90ee1 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; import java.io.Serializable; import java.io.Writer; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java index 56e7c5b5a..4c2c6f717 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; -import org.apache.commons.io.function.IOConsumer; -import org.apache.commons.io.function.IOFunction; +import org.apache.tsfile.external.commons.io.function.IOConsumer; +import org.apache.tsfile.external.commons.io.function.IOFunction; import java.io.IOException; import java.io.OutputStream; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java similarity index 95% rename from java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java index 56afbc6ab..1f770ad49 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; -import org.apache.commons.io.build.AbstractOrigin; -import org.apache.commons.io.build.AbstractStreamBuilder; -import org.apache.commons.io.function.Uncheck; -import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; +import org.apache.tsfile.external.commons.io.build.AbstractOrigin; +import org.apache.tsfile.external.commons.io.build.AbstractStreamBuilder; +import org.apache.tsfile.external.commons.io.function.Uncheck; +import org.apache.tsfile.external.commons.io.input.UnsynchronizedByteArrayInputStream; import java.io.BufferedInputStream; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/WriterOutputStream.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/WriterOutputStream.java index 02b624f6d..5eaa86979 100644 --- a/java/tsfile/src/main/java/org/apache/commons/io/output/WriterOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/WriterOutputStream.java @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.io.output; +package org.apache.tsfile.external.commons.io.output; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.build.AbstractStreamBuilder; -import org.apache.commons.io.charset.CharsetDecoders; +import org.apache.tsfile.external.commons.io.Charsets; +import org.apache.tsfile.external.commons.io.IOUtils; +import org.apache.tsfile.external.commons.io.build.AbstractStreamBuilder; +import org.apache.tsfile.external.commons.io.charset.CharsetDecoders; import java.io.IOException; import java.io.OutputStream; @@ -77,7 +77,7 @@ * *

Instances of {@link WriterOutputStream} are not thread safe. * - * @see org.apache.commons.io.input.ReaderInputStream + * @see org.apache.tsfile.external.commons.io.input.ReaderInputStream * @since 2.0 */ public class WriterOutputStream extends OutputStream { diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayFill.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayFill.java index f45168c94..ec9d66df5 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayFill.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayFill.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; import java.util.Arrays; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java index d787649bd..fdb38bab1 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/ArrayUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; import java.lang.reflect.Array; import java.util.function.Supplier; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/CharSequenceUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/CharSequenceUtils.java index 9d1d5332e..c91fa58b4 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/CharSequenceUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; public class CharSequenceUtils { diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ClassUtils.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ClassUtils.java index 63663f99f..adfbc0a4c 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/ClassUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ClassUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; public class ClassUtils { /** diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/NotImplementedException.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/NotImplementedException.java index 2eb8bfef0..9179a85e7 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/NotImplementedException.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/NotImplementedException.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; ///////////////////////////////////////////////////////////////////////////////////////////////// // IoTDB diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java index 58c04fe98..483c4fb0c 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/ObjectUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; import java.lang.reflect.Array; import java.util.Collection; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java index 7ea1d5743..3f94d24ed 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/StringUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java @@ -17,9 +17,9 @@ * under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; -import org.apache.commons.lang3.function.Suppliers; +import org.apache.tsfile.external.commons.lang3.function.Suppliers; import java.util.ArrayList; import java.util.List; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Strings.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Strings.java index f435e0c57..4426be50b 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/Strings.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Strings.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; public abstract class Strings { /** The Case-Insensitive singleton instance. */ diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/SystemProperties.java similarity index 96% rename from java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/SystemProperties.java index 1993a2da2..2fd7939da 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/SystemProperties.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/SystemProperties.java @@ -15,13 +15,13 @@ * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; ///////////////////////////////////////////////////////////////////////////////////////////////// // IoTDB ///////////////////////////////////////////////////////////////////////////////////////////////// -import org.apache.commons.lang3.function.Suppliers; +import org.apache.tsfile.external.commons.lang3.function.Suppliers; import java.util.function.Supplier; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/SystemUtils.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/SystemUtils.java index 060d6be17..b10530821 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/SystemUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/SystemUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; ///////////////////////////////////////////////////////////////////////////////////////////////// // IoTDB diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java index b3a41e717..9ecbce034 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/Validate.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.commons.lang3; +package org.apache.tsfile.external.commons.lang3; import java.util.Objects; import java.util.function.Supplier; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/exception/ExceptionUtils.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/exception/ExceptionUtils.java index d7c8a616c..db62a7d20 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/exception/ExceptionUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.exception; +package org.apache.tsfile.external.commons.lang3.exception; import java.util.ArrayList; import java.util.List; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableBiConsumer.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableBiConsumer.java index 2d49cd8f6..36351642e 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiConsumer.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableBiConsumer.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.function; +package org.apache.tsfile.external.commons.lang3.function; import java.util.Objects; import java.util.function.BiConsumer; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableBiFunction.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableBiFunction.java index 02872d5c3..587d2a069 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableBiFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableBiFunction.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.function; +package org.apache.tsfile.external.commons.lang3.function; import java.util.Objects; import java.util.function.BiFunction; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableFunction.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableFunction.java index a6cd1fd85..1e065403b 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/function/FailableFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/FailableFunction.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.function; +package org.apache.tsfile.external.commons.lang3.function; import java.util.Objects; import java.util.function.Function; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/Suppliers.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/Suppliers.java index e92a8fb1c..b4b87a35d 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/function/Suppliers.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/Suppliers.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.function; +package org.apache.tsfile.external.commons.lang3.function; import java.util.function.Supplier; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/TriFunction.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/TriFunction.java index b1c69b0ca..a8e70361d 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/function/TriFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/function/TriFunction.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.function; +package org.apache.tsfile.external.commons.lang3.function; import java.util.Objects; import java.util.function.Function; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/math/NumberUtils.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/math/NumberUtils.java index 804b9e38c..a3ead2edf 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/math/NumberUtils.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package org.apache.commons.lang3.math; +package org.apache.tsfile.external.commons.lang3.math; -import org.apache.commons.lang3.StringUtils; +import org.apache.tsfile.external.commons.lang3.StringUtils; public class NumberUtils { /** diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/ImmutablePair.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/ImmutablePair.java index 05b8fdd16..d42c045ee 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutablePair.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/ImmutablePair.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.tuple; +package org.apache.tsfile.external.commons.lang3.tuple; import java.util.Map; import java.util.Objects; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/ImmutableTriple.java similarity index 98% rename from java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/ImmutableTriple.java index b5b4e8e64..4d8dde3a9 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/ImmutableTriple.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/ImmutableTriple.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.tuple; +package org.apache.tsfile.external.commons.lang3.tuple; import java.util.Objects; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/Pair.java similarity index 97% rename from java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/Pair.java index 12a767c19..020d764ba 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Pair.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/Pair.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package org.apache.commons.lang3.tuple; +package org.apache.tsfile.external.commons.lang3.tuple; -import org.apache.commons.lang3.function.FailableBiConsumer; -import org.apache.commons.lang3.function.FailableBiFunction; +import org.apache.tsfile.external.commons.lang3.function.FailableBiConsumer; +import org.apache.tsfile.external.commons.lang3.function.FailableBiFunction; import java.io.Serializable; import java.util.Map; diff --git a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/Triple.java similarity index 99% rename from java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java rename to java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/Triple.java index cfb13da5a..d2d5ba65d 100644 --- a/java/tsfile/src/main/java/org/apache/commons/lang3/tuple/Triple.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/tuple/Triple.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.tuple; +package org.apache.tsfile.external.commons.lang3.tuple; import java.io.Serializable; import java.util.Objects; diff --git a/java/tsfile/src/main/java/org/apache/tsfile/fileSystem/fsFactory/LocalFSFactory.java b/java/tsfile/src/main/java/org/apache/tsfile/fileSystem/fsFactory/LocalFSFactory.java index d64a85347..e277b3660 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/fileSystem/fsFactory/LocalFSFactory.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/fileSystem/fsFactory/LocalFSFactory.java @@ -19,10 +19,10 @@ package org.apache.tsfile.fileSystem.fsFactory; +import org.apache.tsfile.external.commons.io.FileUtils; import org.apache.tsfile.utils.NoSyncBufferedInputStream; import org.apache.tsfile.utils.NoSyncBufferedOutputStream; -import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/java/tsfile/src/main/java/org/apache/tsfile/read/common/Path.java b/java/tsfile/src/main/java/org/apache/tsfile/read/common/Path.java index b7a0a144d..75648d145 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/read/common/Path.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/read/common/Path.java @@ -21,15 +21,14 @@ import org.apache.tsfile.common.constant.TsFileConstant; import org.apache.tsfile.exception.PathParseException; +import org.apache.tsfile.external.commons.lang3.StringUtils; +import org.apache.tsfile.external.commons.lang3.Validate; import org.apache.tsfile.file.metadata.IDeviceID; import org.apache.tsfile.file.metadata.IDeviceID.Deserializer; import org.apache.tsfile.file.metadata.IDeviceID.Factory; import org.apache.tsfile.read.common.parser.PathNodesGenerator; import org.apache.tsfile.utils.ReadWriteIOUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Validate; - import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; diff --git a/java/tsfile/src/main/java/org/apache/tsfile/read/common/parser/PathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/read/common/parser/PathVisitor.java index 69ca31746..bf374d3e6 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/read/common/parser/PathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/read/common/parser/PathVisitor.java @@ -20,12 +20,11 @@ package org.apache.tsfile.read.common.parser; import org.apache.tsfile.common.constant.TsFileConstant; +import org.apache.tsfile.external.commons.lang3.math.NumberUtils; import org.apache.tsfile.parser.PathParser; import org.apache.tsfile.parser.PathParser.NodeNameContext; import org.apache.tsfile.parser.PathParserBaseVisitor; -import org.apache.commons.lang3.math.NumberUtils; - import java.util.List; public class PathVisitor extends PathParserBaseVisitor { diff --git a/java/tsfile/src/main/java/org/apache/tsfile/write/v4/TsFileWriterBuilder.java b/java/tsfile/src/main/java/org/apache/tsfile/write/v4/TsFileWriterBuilder.java index 08f96c5f5..8da122130 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/write/v4/TsFileWriterBuilder.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/write/v4/TsFileWriterBuilder.java @@ -20,11 +20,10 @@ package org.apache.tsfile.write.v4; import org.apache.tsfile.annotations.TsFileApi; +import org.apache.tsfile.external.commons.lang3.StringUtils; import org.apache.tsfile.file.metadata.TableSchema; import org.apache.tsfile.write.schema.IMeasurementSchema; -import org.apache.commons.lang3.StringUtils; - import java.io.File; import java.io.IOException; diff --git a/java/tsfile/src/main/java/org/apache/tsfile/write/writer/TsFileIOWriter.java b/java/tsfile/src/main/java/org/apache/tsfile/write/writer/TsFileIOWriter.java index 8ac5eb2b6..96cc383e6 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/write/writer/TsFileIOWriter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/write/writer/TsFileIOWriter.java @@ -25,6 +25,7 @@ import org.apache.tsfile.encrypt.EncryptUtils; import org.apache.tsfile.encrypt.IEncryptor; import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.external.commons.io.FileUtils; import org.apache.tsfile.file.MetaMarker; import org.apache.tsfile.file.header.ChunkGroupHeader; import org.apache.tsfile.file.header.ChunkHeader; @@ -51,7 +52,6 @@ import org.apache.tsfile.write.schema.Schema; import org.apache.tsfile.write.writer.tsmiterator.TSMIterator; -import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/java/tsfile/src/test/java/org/apache/tsfile/read/reader/chunk/TableChunkReaderTest.java b/java/tsfile/src/test/java/org/apache/tsfile/read/reader/chunk/TableChunkReaderTest.java index f8b3f57b5..10167bd7a 100644 --- a/java/tsfile/src/test/java/org/apache/tsfile/read/reader/chunk/TableChunkReaderTest.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/read/reader/chunk/TableChunkReaderTest.java @@ -19,6 +19,7 @@ package org.apache.tsfile.read.reader.chunk; import org.apache.tsfile.exception.write.WriteProcessException; +import org.apache.tsfile.external.commons.io.FileUtils; import org.apache.tsfile.file.metadata.AlignedChunkMetadata; import org.apache.tsfile.file.metadata.ChunkMetadata; import org.apache.tsfile.file.metadata.IChunkMetadata; @@ -30,7 +31,6 @@ import org.apache.tsfile.read.common.TimeRange; import org.apache.tsfile.read.controller.CachedChunkLoaderImpl; -import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableViewTest.java b/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableViewTest.java index 17552af1e..b55473681 100644 --- a/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableViewTest.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableViewTest.java @@ -22,6 +22,7 @@ import org.apache.tsfile.enums.ColumnCategory; import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.exception.write.WriteProcessException; +import org.apache.tsfile.external.commons.io.FileUtils; import org.apache.tsfile.file.metadata.IDeviceID; import org.apache.tsfile.file.metadata.IDeviceID.Factory; import org.apache.tsfile.file.metadata.TableSchema; @@ -53,7 +54,6 @@ import org.apache.tsfile.write.schema.IMeasurementSchema; import org.apache.tsfile.write.schema.MeasurementSchema; -import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Ignore; diff --git a/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java b/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java index 8b1abe536..71bf43240 100644 --- a/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/utils/FilePathUtilsTest.java @@ -27,7 +27,7 @@ import java.io.File; import java.io.IOException; -import static org.apache.commons.io.FileUtils.forceMkdirParent; +import static org.apache.tsfile.external.commons.io.FileUtils.forceMkdirParent; public class FilePathUtilsTest { diff --git a/java/tsfile/src/test/java/org/apache/tsfile/write/writer/TsFileIOWriterMemoryControlTest.java b/java/tsfile/src/test/java/org/apache/tsfile/write/writer/TsFileIOWriterMemoryControlTest.java index 77ffdab0c..200b30a5f 100644 --- a/java/tsfile/src/test/java/org/apache/tsfile/write/writer/TsFileIOWriterMemoryControlTest.java +++ b/java/tsfile/src/test/java/org/apache/tsfile/write/writer/TsFileIOWriterMemoryControlTest.java @@ -24,6 +24,7 @@ import org.apache.tsfile.encoding.encoder.Encoder; import org.apache.tsfile.encoding.encoder.TSEncodingBuilder; import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.external.commons.io.FileUtils; import org.apache.tsfile.file.metadata.ChunkMetadata; import org.apache.tsfile.file.metadata.IChunkMetadata; import org.apache.tsfile.file.metadata.IDeviceID; @@ -43,7 +44,6 @@ import org.apache.tsfile.write.schema.MeasurementSchema; import org.apache.tsfile.write.writer.tsmiterator.TSMIterator; -import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; From 915c0672a66307bd642f4cf32f0ed32d746206ad Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:00:51 +0800 Subject: [PATCH 3/8] Add --- .../tsfile/external/commons/io/FileUtils.java | 42 +++++++ .../tsfile/external/commons/io/IOUtils.java | 96 +++++++++++++++ .../external/commons/lang3/StringUtils.java | 53 ++++++++ .../external/commons/lang3/Validate.java | 53 ++++++++ .../commons/lang3/stream/LangCollectors.java | 115 ++++++++++++++++++ .../commons/lang3/stream/Streams.java | 43 +++++++ 6 files changed, 402 insertions(+) create mode 100644 java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/LangCollectors.java create mode 100644 java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java index 1f89607f0..97f227879 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileUtils.java @@ -33,6 +33,7 @@ import java.nio.file.CopyOption; import java.nio.file.FileVisitOption; import java.nio.file.Files; +import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributeView; @@ -307,6 +308,13 @@ public static boolean deleteQuietly(final File file) { // IoTDB ///////////////////////////////////////////////////////////////////////////////////////////////// + /** + * The empty String {@code ""}. + * + * @since 2.0 + */ + public static final String EMPTY = ""; + /** * Writes a CharSequence to a file creating the file if it does not exist. * @@ -882,5 +890,39 @@ private static File requireDirectoryIfExists(final File directory, final String return directory; } + /** + * Tests whether the specified {@link File} is a directory or not. Implemented as a null-safe + * delegate to {@link Files#isDirectory(Path path, LinkOption... options)}. + * + * @param file the path to the file. + * @param options options indicating how symbolic links are handled + * @return {@code true} if the file is a directory; {@code false} if the path is null, the file + * does not exist, is not a directory, or it cannot be determined if the file is a directory + * or not. + * @throws SecurityException In the case of the default provider, and a security manager is + * installed, the {@link SecurityManager#checkRead(String) checkRead} method is invoked to + * check read access to the directory. + * @since 2.9.0 + */ + public static boolean isDirectory(final File file, final LinkOption... options) { + return file != null && Files.isDirectory(file.toPath(), options); + } + /** + * Reads the contents of a file into a String. The file is always closed. + * + * @param file the file to read, must not be {@code null} + * @param charsetName the name of the requested charset, {@code null} means platform default + * @return the file contents, never {@code null} + * @throws NullPointerException if file is {@code null}. + * @throws FileNotFoundException if the file does not exist, is a directory rather than a regular + * file, or for some other reason cannot be opened for reading. + * @throws IOException if an I/O error occurs. + * @since 2.3 + */ + public static String readFileToString(final File file, final Charset charsetName) + throws IOException { + return IOUtils.toString( + () -> Files.newInputStream(file.toPath()), Charsets.toCharset(charsetName)); + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java index 3ae2f4467..1642a6523 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/IOUtils.java @@ -19,6 +19,7 @@ package org.apache.tsfile.external.commons.io; +import org.apache.tsfile.external.commons.io.function.IOSupplier; import org.apache.tsfile.external.commons.io.function.IOTriFunction; import org.apache.tsfile.external.commons.io.output.ByteArrayOutputStream; import org.apache.tsfile.external.commons.io.output.StringBuilderWriter; @@ -29,6 +30,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; @@ -459,4 +461,98 @@ public static void write(final String data, final OutputStream output, final Cha Channels.newChannel(output).write(Charsets.toCharset(charset).encode(data)); } } + + /** + * Gets the contents of an {@link InputStream} from a supplier as a String using the specified + * character encoding. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input supplies the {@link InputStream} to read + * @param charset the charset to use, null means platform default + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 2.12.0 + */ + public static String toString(final IOSupplier input, final Charset charset) + throws IOException { + return toString( + input, + charset, + () -> { + throw new NullPointerException("input"); + }); + } + + /** + * Gets the contents of an {@link InputStream} from a supplier as a String using the specified + * character encoding. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input supplies the {@link InputStream} to read + * @param charset the charset to use, null means platform default + * @param defaultString the default return value if the supplier or its value is null. + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 2.12.0 + */ + public static String toString( + final IOSupplier input, + final Charset charset, + final IOSupplier defaultString) + throws IOException { + if (input == null) { + return defaultString.get(); + } + try (InputStream inputStream = input.get()) { + return inputStream != null ? toString(inputStream, charset) : defaultString.get(); + } + } + + /** + * Gets the contents of an {@link InputStream} as a String using the specified character encoding. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + * @param input the {@link InputStream} to read + * @param charset the charset to use, null means platform default + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 2.3 + */ + public static String toString(final InputStream input, final Charset charset) throws IOException { + try (StringBuilderWriter sw = new StringBuilderWriter()) { + copy(input, sw, charset); + return sw.toString(); + } + } + + /** + * Copies bytes from an {@link InputStream} to chars on a {@link Writer} using the specified + * character encoding. + * + *

This method buffers the input internally, so there is no need to use a {@link + * BufferedInputStream}. + * + *

This method uses {@link InputStreamReader}. + * + * @param input the {@link InputStream} to read + * @param writer the {@link Writer} to write to + * @param inputCharset the charset to use for the input stream, null means platform default + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 2.3 + */ + public static void copy(final InputStream input, final Writer writer, final Charset inputCharset) + throws IOException { + final InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(inputCharset)); + copy(reader, writer); + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java index 3f94d24ed..932c159eb 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java @@ -20,9 +20,13 @@ package org.apache.tsfile.external.commons.lang3; import org.apache.tsfile.external.commons.lang3.function.Suppliers; +import org.apache.tsfile.external.commons.lang3.stream.LangCollectors; +import org.apache.tsfile.external.commons.lang3.stream.Streams; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.function.Supplier; public class StringUtils { @@ -495,4 +499,53 @@ public static T getIfEmpty( public static boolean isNotEmpty(CharSequence cs) { return !isEmpty(cs); } + + /** + * Joins the elements of the provided {@link Iterable} into a single String containing the + * provided elements. + * + *

No delimiter is added before or after the list. A {@code null} separator is the same as an + * empty String (""). + * + *

See the examples here: {@link #join(Object[],String)}. + * + * @param iterable the {@link Iterable} providing the values to join together, may be null + * @param separator the separator character to use, null treated as "" + * @return the joined String, {@code null} if null iterator input + * @since 2.3 + */ + public static String join(final Iterable iterable, final String separator) { + return iterable != null ? join(iterable.iterator(), separator) : null; + } + + /** + * Joins the elements of the provided {@link Iterator} into a single String containing the + * provided elements. + * + *

No delimiter is added before or after the list. A {@code null} separator is the same as an + * empty String (""). + * + *

See the examples here: {@link #join(Object[],String)}. + * + * @param iterator the {@link Iterator} of values to join together, may be null + * @param separator the separator character to use, null treated as "" + * @return the joined String, {@code null} if null iterator input + */ + public static String join(final Iterator iterator, final String separator) { + // handle null, zero and one elements before building a buffer + if (iterator == null) { + return null; + } + if (!iterator.hasNext()) { + return EMPTY; + } + return Streams.of(iterator) + .collect( + LangCollectors.joining( + toStringOrEmpty(separator), EMPTY, EMPTY, StringUtils::toStringOrEmpty)); + } + + private static String toStringOrEmpty(final Object obj) { + return Objects.toString(obj, EMPTY); + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java index 9ecbce034..7a423eaff 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/Validate.java @@ -94,4 +94,57 @@ private static Supplier toSupplier(final String message, final Object... private static String getMessage(final String message, final Object... values) { return ArrayUtils.isEmpty(values) ? message : String.format(message, values); } + + /** + * Validate that the argument condition is {@code true}; otherwise throwing an exception with the + * specified message. This method is useful when validating according to an arbitrary boolean + * expression, such as validating a primitive number or using your own custom validation + * expression. + * + *

Validate.isTrue(i > 0.0, "The value must be greater than zero: %d", i);
+ * + *

For performance reasons, the long value is passed as a separate parameter and appended to + * the exception message only in the case of an error. + * + * @param expression the boolean expression to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not + * null + * @param value the value to append to the message when invalid + * @throws IllegalArgumentException if expression is {@code false} + * @see #isTrue(boolean) + * @see #isTrue(boolean, String, double) + * @see #isTrue(boolean, String, Object...) + */ + public static void isTrue(final boolean expression, final String message, final long value) { + if (!expression) { + throw new IllegalArgumentException(String.format(message, Long.valueOf(value))); + } + } + + /** + * Validate that the argument condition is {@code true}; otherwise throwing an exception with the + * specified message. This method is useful when validating according to an arbitrary boolean + * expression, such as validating a primitive number or using your own custom validation + * expression. + * + *

+   * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max);
+   * 
+ * + * @param expression the boolean expression to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not + * null + * @param values the optional values for the formatted exception message, null array not + * recommended + * @throws IllegalArgumentException if expression is {@code false} + * @see #isTrue(boolean) + * @see #isTrue(boolean, String, long) + * @see #isTrue(boolean, String, double) + */ + public static void isTrue( + final boolean expression, final String message, final Object... values) { + if (!expression) { + throw new IllegalArgumentException(getMessage(message, values)); + } + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/LangCollectors.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/LangCollectors.java new file mode 100644 index 000000000..e18eb07a8 --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/LangCollectors.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tsfile.external.commons.lang3.stream; + +import java.util.Collections; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +public class LangCollectors { + + private static final Set CH_NOID = Collections.emptySet(); + + /** + * Simple implementation class for {@code Collector}. + * + * @param the type of elements to be collected + * @param the type of the result + */ + private static final class SimpleCollector implements Collector { + + private final BiConsumer accumulator; + private final Set characteristics; + private final BinaryOperator combiner; + private final Function finisher; + private final Supplier supplier; + + private SimpleCollector( + final Supplier supplier, + final BiConsumer accumulator, + final BinaryOperator combiner, + final Function finisher, + final Set characteristics) { + this.supplier = supplier; + this.accumulator = accumulator; + this.combiner = combiner; + this.finisher = finisher; + this.characteristics = characteristics; + } + + @Override + public BiConsumer accumulator() { + return accumulator; + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public BinaryOperator combiner() { + return combiner; + } + + @Override + public Function finisher() { + return finisher; + } + + @Override + public Supplier supplier() { + return supplier; + } + } + + /** + * Returns a {@code Collector} that concatenates the input elements, separated by the specified + * delimiter, with the specified prefix and suffix, in encounter order. + * + *

This is a variation of {@link Collectors#joining(CharSequence, CharSequence, CharSequence)} + * that works with any element class, not just {@code CharSequence}. + * + * @param delimiter the delimiter to be used between each element + * @param prefix the sequence of characters to be used at the beginning of the joined result + * @param suffix the sequence of characters to be used at the end of the joined result + * @param toString A function that takes an Object and returns a non-null String. + * @return A {@code Collector} which concatenates CharSequence elements, separated by the + * specified delimiter, in encounter order + */ + public static Collector joining( + final CharSequence delimiter, + final CharSequence prefix, + final CharSequence suffix, + final Function toString) { + return new SimpleCollector<>( + () -> new StringJoiner(delimiter, prefix, suffix), + (a, t) -> a.add(toString.apply(t)), + StringJoiner::merge, + StringJoiner::toString, + CH_NOID); + } +} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java new file mode 100644 index 000000000..2de94cc7c --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tsfile.external.commons.lang3.stream; + +import java.util.Iterator; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class Streams { + /** + * Creates a stream on the given Iterator. + * + * @param the type of elements in the Iterator. + * @param iterator the Iterator to stream or null. + * @return a new Stream or {@link Stream#empty()} if the Iterator is null. + * @since 3.13.0 + */ + public static Stream of(final Iterator iterator) { + return iterator == null + ? Stream.empty() + : StreamSupport.stream( + Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false); + } +} From 3b17ed6a2908b29f25b09237eb02358484b40032 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:21:02 +0800 Subject: [PATCH 4/8] fix --- .../lang3/builder/HashCodeBuilder.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/builder/HashCodeBuilder.java diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/builder/HashCodeBuilder.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/builder/HashCodeBuilder.java new file mode 100644 index 000000000..bfac1c76d --- /dev/null +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/builder/HashCodeBuilder.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tsfile.external.commons.lang3.builder; + +import org.apache.tsfile.external.commons.lang3.ObjectUtils; +import org.apache.tsfile.external.commons.lang3.Validate; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + +public class HashCodeBuilder { + /** Constant to use in building the hashCode. */ + private final int iConstant; + + /** Running total of the hashCode. */ + private int iTotal; + + /** + * Two randomly chosen, odd numbers must be passed in. Ideally these should be different for each + * class, however this is not vital. + * + *

Prime numbers are preferred, especially for the multiplier. + * + * @param initialOddNumber an odd number used as the initial value + * @param multiplierOddNumber an odd number used as the multiplier + * @throws IllegalArgumentException if the number is even + */ + public HashCodeBuilder(final int initialOddNumber, final int multiplierOddNumber) { + Validate.isTrue(initialOddNumber % 2 != 0, "HashCodeBuilder requires an odd initial value"); + Validate.isTrue(multiplierOddNumber % 2 != 0, "HashCodeBuilder requires an odd multiplier"); + iConstant = multiplierOddNumber; + iTotal = initialOddNumber; + } + + /** + * Append a {@code hashCode} for an {@link Object}. + * + * @param object the Object to add to the {@code hashCode} + * @return {@code this} instance. + */ + public HashCodeBuilder append(final Object object) { + if (object == null) { + iTotal = iTotal * iConstant; + + } else if (ObjectUtils.isArray(object)) { + // factor out array case in order to keep method small enough + // to be inlined + appendArray(object); + } else { + iTotal = iTotal * iConstant + object.hashCode(); + } + return this; + } + + /** + * Append a {@code hashCode} for an array. + * + * @param object the array to add to the {@code hashCode} + */ + private void appendArray(final Object object) { + // 'Switch' on type of array, to dispatch to the correct handler + // This handles multidimensional arrays + if (object instanceof long[]) { + append((long[]) object); + } else if (object instanceof int[]) { + append((int[]) object); + } else if (object instanceof short[]) { + append((short[]) object); + } else if (object instanceof char[]) { + append((char[]) object); + } else if (object instanceof byte[]) { + append((byte[]) object); + } else if (object instanceof double[]) { + append((double[]) object); + } else if (object instanceof float[]) { + append((float[]) object); + } else if (object instanceof boolean[]) { + append((boolean[]) object); + } else { + // Not an array of primitives + append((Object[]) object); + } + } + + /** + * Returns the computed {@code hashCode}. + * + * @return {@code hashCode} based on the fields appended + */ + public int toHashCode() { + return iTotal; + } +} From 6faa2af206e5d1be39377540cc01a4279bf1aeab Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:34:42 +0800 Subject: [PATCH 5/8] Fix --- .../commons/codec/digest/DigestUtils.java | 20 +++ .../external/commons/lang3/ArrayUtils.java | 122 +++++++++++++++++ .../external/commons/lang3/ObjectUtils.java | 24 ++++ .../external/commons/lang3/StringUtils.java | 128 ++++++++++++++++++ .../commons/lang3/stream/Streams.java | 13 ++ 5 files changed, 307 insertions(+) diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java index d2dfa6c50..8f3fc1272 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/digest/DigestUtils.java @@ -86,6 +86,26 @@ public static byte[] md5(InputStream data) throws IOException { return digest(getMd5Digest(), data); } + /** + * Calculates the MD5 digest and returns the value as a 32 character hexadecimal string. + * + * @param data Data to digest + * @return MD5 digest as a hexadecimal string + */ + public static String md5Hex(final byte[] data) { + return Hex.encodeHexString(md5(data)); + } + + /** + * Calculates the MD5 digest and returns the value as a 16 element {@code byte[]}. + * + * @param data Data to digest + * @return MD5 digest + */ + public static byte[] md5(final byte[] data) { + return getMd5Digest().digest(data); + } + public static byte[] digest(MessageDigest messageDigest, InputStream data) throws IOException { return updateDigest(messageDigest, data).digest(); } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java index fdb38bab1..5fbf6e672 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ArrayUtils.java @@ -28,11 +28,23 @@ public class ArrayUtils { // IoTDB ///////////////////////////////////////////////////////////////////////////////////////////////// + /** An empty immutable {@code boolean} array. */ + public static final boolean[] EMPTY_BOOLEAN_ARRAY = {}; + + /** An empty immutable {@code float} array. */ + public static final float[] EMPTY_FLOAT_ARRAY = {}; + + /** An empty immutable {@code int} array. */ + public static final int[] EMPTY_INT_ARRAY = {}; + /** An empty immutable {@code long} array. */ public static final long[] EMPTY_LONG_ARRAY = {}; public static final String[] EMPTY_STRING_ARRAY = {}; + /** An empty immutable {@code double} array. */ + public static final double[] EMPTY_DOUBLE_ARRAY = {}; + /** * Converts an array of object Longs to primitives. * @@ -352,4 +364,114 @@ public static T arraycopy( public static T[] newInstance(final Class componentType, final int length) { return (T[]) Array.newInstance(componentType, length); } + + /** + * Converts an array of object Integers to primitives. + * + *

This method returns {@code null} for a {@code null} input array. + * + * @param array a {@link Integer} array, may be {@code null} + * @return an {@code int} array, {@code null} if null array input + * @throws NullPointerException if an array element is {@code null} + */ + public static int[] toPrimitive(final Integer[] array) { + if (array == null) { + return null; + } + if (array.length == 0) { + return EMPTY_INT_ARRAY; + } + final int[] result = new int[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = array[i].intValue(); + } + return result; + } + + /** + * Converts an array of object Booleans to primitives. + * + *

This method returns {@code null} for a {@code null} input array. + * + *

Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers + * return false. + * + * @param array a {@link Boolean} array, may be {@code null} + * @return a {@code boolean} array, {@code null} if null array input + */ + public static boolean[] toPrimitive(final Boolean[] array) { + return toPrimitive(array, false); + } + + /** + * Converts an array of object Booleans to primitives handling {@code null}. + * + *

This method returns {@code null} for a {@code null} input array. + * + * @param array a {@link Boolean} array, may be {@code null} + * @param valueForNull the value to insert if {@code null} found + * @return a {@code boolean} array, {@code null} if null array input + */ + public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) { + if (array == null) { + return null; + } + if (array.length == 0) { + return EMPTY_BOOLEAN_ARRAY; + } + final boolean[] result = new boolean[array.length]; + for (int i = 0; i < array.length; i++) { + final Boolean b = array[i]; + result[i] = b == null ? valueForNull : b.booleanValue(); + } + return result; + } + + /** + * Converts an array of object Floats to primitives handling {@code null}. + * + *

This method returns {@code null} for a {@code null} input array. + * + * @param array a {@link Float} array, may be {@code null} + * @param valueForNull the value to insert if {@code null} found + * @return a {@code float} array, {@code null} if null array input + */ + public static float[] toPrimitive(final Float[] array, final float valueForNull) { + if (array == null) { + return null; + } + if (array.length == 0) { + return EMPTY_FLOAT_ARRAY; + } + final float[] result = new float[array.length]; + for (int i = 0; i < array.length; i++) { + final Float b = array[i]; + result[i] = b == null ? valueForNull : b.floatValue(); + } + return result; + } + + /** + * Converts an array of object Doubles to primitives handling {@code null}. + * + *

This method returns {@code null} for a {@code null} input array. + * + * @param array a {@link Double} array, may be {@code null} + * @param valueForNull the value to insert if {@code null} found + * @return a {@code double} array, {@code null} if null array input + */ + public static double[] toPrimitive(final Double[] array, final double valueForNull) { + if (array == null) { + return null; + } + if (array.length == 0) { + return EMPTY_DOUBLE_ARRAY; + } + final double[] result = new double[array.length]; + for (int i = 0; i < array.length; i++) { + final Double b = array[i]; + result[i] = b == null ? valueForNull : b.doubleValue(); + } + return result; + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java index 483c4fb0c..957c76b3b 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/ObjectUtils.java @@ -20,6 +20,7 @@ import java.lang.reflect.Array; import java.util.Collection; import java.util.Map; +import java.util.Objects; import java.util.Optional; public class ObjectUtils { @@ -145,4 +146,27 @@ public static boolean isEmpty(final Object object) { public static boolean isArray(final Object object) { return object != null && object.getClass().isArray(); } + + /** + * Gets the {@code toString()} of an {@link Object} or the empty string ({@code ""}) if the input + * is {@code null}. + * + *

+   * ObjectUtils.toString(null)         = ""
+   * ObjectUtils.toString("")           = ""
+   * ObjectUtils.toString("bat")        = "bat"
+   * ObjectUtils.toString(Boolean.TRUE) = "true"
+   * 
+ * + * @see Objects#toString(Object) + * @see Objects#toString(Object, String) + * @see StringUtils#defaultString(String) + * @see String#valueOf(Object) + * @param obj the Object to {@code toString()}, may be {@code null}. + * @return the input's {@code toString()}, or {@code ""} if the input is {@code null}. + * @since 2.0 + */ + public static String toString(final Object obj) { + return Objects.toString(obj, StringUtils.EMPTY); + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java index 932c159eb..761884e7d 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/StringUtils.java @@ -548,4 +548,132 @@ public static String join(final Iterator iterator, final String separator) { private static String toStringOrEmpty(final Object obj) { return Objects.toString(obj, EMPTY); } + + /** + * Joins the elements of the provided array into a single String containing the provided list of + * elements. + * + *

No delimiter is added before or after the list. A {@code null} separator is the same as an + * empty String (""). Null objects or empty strings within the array are represented by empty + * strings. + * + *

+   * StringUtils.join(null, *)                = null
+   * StringUtils.join([], *)                  = ""
+   * StringUtils.join([null], *)              = ""
+   * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
+   * StringUtils.join(["a", "b", "c"], null)  = "abc"
+   * StringUtils.join(["a", "b", "c"], "")    = "abc"
+   * StringUtils.join([null, "", "a"], ',')   = ",,a"
+   * 
+ * + * @param array the array of values to join together, may be null + * @param delimiter the separator character to use, null treated as "" + * @return the joined String, {@code null} if null array input + */ + public static String join(final Object[] array, final String delimiter) { + return array != null ? join(array, ObjectUtils.toString(delimiter), 0, array.length) : null; + } + + /** + * Joins the elements of the provided array into a single String containing the provided list of + * elements. + * + *

No delimiter is added before or after the list. A {@code null} separator is the same as an + * empty String (""). Null objects or empty strings within the array are represented by empty + * strings. + * + *

+   * StringUtils.join(null, *, *, *)                = null
+   * StringUtils.join([], *, *, *)                  = ""
+   * StringUtils.join([null], *, *, *)              = ""
+   * StringUtils.join(["a", "b", "c"], "--", 0, 3)  = "a--b--c"
+   * StringUtils.join(["a", "b", "c"], "--", 1, 3)  = "b--c"
+   * StringUtils.join(["a", "b", "c"], "--", 2, 3)  = "c"
+   * StringUtils.join(["a", "b", "c"], "--", 2, 2)  = ""
+   * StringUtils.join(["a", "b", "c"], null, 0, 3)  = "abc"
+   * StringUtils.join(["a", "b", "c"], "", 0, 3)    = "abc"
+   * StringUtils.join([null, "", "a"], ',', 0, 3)   = ",,a"
+   * 
+ * + * @param array the array of values to join together, may be null + * @param delimiter the separator character to use, null treated as "" + * @param startIndex the first index to start joining from. + * @param endIndex the index to stop joining from (exclusive). + * @return the joined String, {@code null} if null array input; or the empty string if {@code + * endIndex - startIndex <= 0}. The number of joined entries is given by {@code endIndex - + * startIndex} + * @throws ArrayIndexOutOfBoundsException ife
+ * {@code startIndex < 0} or
+ * {@code startIndex >= array.length()} or
+ * {@code endIndex < 0} or
+ * {@code endIndex > array.length()} + */ + public static String join( + final Object[] array, final String delimiter, final int startIndex, final int endIndex) { + return array != null + ? Streams.of(array) + .skip(startIndex) + .limit(Math.max(0, endIndex - startIndex)) + .collect(LangCollectors.joining(delimiter, EMPTY, EMPTY, ObjectUtils::toString)) + : null; + } + + /** + * Joins the elements of the provided array into a single String containing the provided list of + * elements. + * + *

No delimiter is added before or after the list. Null objects or empty strings within the + * array are represented by empty strings. + * + *

+   * StringUtils.join(null, *)               = null
+   * StringUtils.join([], *)                 = ""
+   * StringUtils.join([null], *)             = ""
+   * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
+   * StringUtils.join(["a", "b", "c"], null) = "abc"
+   * StringUtils.join([null, "", "a"], ';')  = ";;a"
+   * 
+ * + * @param array the array of values to join together, may be null + * @param delimiter the separator character to use + * @return the joined String, {@code null} if null array input + * @since 2.0 + */ + public static String join(final Object[] array, final char delimiter) { + if (array == null) { + return null; + } + return join(array, delimiter, 0, array.length); + } + + /** + * Joins the elements of the provided array into a single String containing the provided list of + * elements. + * + *

No delimiter is added before or after the list. Null objects or empty strings within the + * array are represented by empty strings. + * + *

+   * StringUtils.join(null, *)               = null
+   * StringUtils.join([], *)                 = ""
+   * StringUtils.join([null], *)             = ""
+   * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
+   * StringUtils.join(["a", "b", "c"], null) = "abc"
+   * StringUtils.join([null, "", "a"], ';')  = ";;a"
+   * 
+ * + * @param array the array of values to join together, may be null + * @param delimiter the separator character to use + * @param startIndex the first index to start joining from. It is an error to pass in a start + * index past the end of the array + * @param endIndex the index to stop joining from (exclusive). It is an error to pass in an end + * index past the end of the array + * @return the joined String, {@code null} if null array input + * @since 2.0 + */ + public static String join( + final Object[] array, final char delimiter, final int startIndex, final int endIndex) { + return join(array, String.valueOf(delimiter), startIndex, endIndex); + } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java index 2de94cc7c..5f28310b1 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/stream/Streams.java @@ -40,4 +40,17 @@ public static Stream of(final Iterator iterator) { : StreamSupport.stream( Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false); } + + /** + * Null-safe version of {@link Stream#of(Object[])}. + * + * @param the type of stream elements. + * @param values the elements of the new stream, may be {@code null}. + * @return the new stream on {@code values} or {@link Stream#empty()}. + * @since 3.13.0 + */ + @SafeVarargs // Creating a stream from an array is safe + public static Stream of(final T... values) { + return values == null ? Stream.empty() : Stream.of(values); + } } From 0624608fcad93e1826c49042297f5dca61841b81 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:02:35 +0800 Subject: [PATCH 6/8] fix --- LICENSE | 42 +++++ .../comparators/ComparatorChain.java | 146 +----------------- .../iterators/AbstractEmptyIterator.java | 20 --- 3 files changed, 46 insertions(+), 162 deletions(-) diff --git a/LICENSE b/LICENSE index 7b741bb59..014d343fd 100644 --- a/LICENSE +++ b/LICENSE @@ -295,3 +295,45 @@ The following files include code is copied from lzokay project. Copyright: (c) 2018 Jack Andersen Project page: https://github.com/AxioDL/lzokay License: https://github.com/AxioDL/lzokay/blob/master/LICENSE + +-------------------------------------------------------------------------------- + +The following files include code modified from Apache Commons Lang project. + +./java/tsfile/src/main/java/org/apache/tsfile/external/commons/lang3/* + +Apache Commons Lang is open source software licensed under the Apache License 2.0 and supported by the Apache Software Foundation. +Project page: https://github.com/apache/commons-lang +License: https://github.com/apache/commons-lang/blob/master/LICENSE.txt + +-------------------------------------------------------------------------------- + +The following files include code modified from Apache Commons IO project. + +./java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/* + +Apache Commons IO is open source software licensed under the Apache License 2.0 and supported by the Apache Software Foundation. +Project page: https://github.com/apache/commons-io +License: https://github.com/apache/commons-io/blob/master/LICENSE.txt + +-------------------------------------------------------------------------------- + +The following files include code modified from Apache Commons CodeC project. + +./java/tsfile/src/main/java/org/apache/tsfile/external/commons/codec/* + +Apache Commons CodeC is open source software licensed under the Apache License 2.0 and supported by the Apache Software Foundation. +Project page: https://github.com/apache/commons-codec +License: https://github.com/apache/commons-codec/blob/master/LICENSE.txt + +-------------------------------------------------------------------------------- + +The following files include code modified from Apache Commons Collections project. + +./java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/* + +Apache Commons Collections is open source software licensed under the Apache License 2.0 and supported by the Apache Software Foundation. +Project page: https://github.com/apache/commons-collections +License: https://github.com/apache/commons-collections/blob/master/LICENSE.txt + +-------------------------------------------------------------------------------- diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java index 7edc25538..2acefe077 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/comparators/ComparatorChain.java @@ -17,12 +17,15 @@ package org.apache.tsfile.external.commons.collections4.comparators; import java.io.Serializable; -import java.util.ArrayList; import java.util.BitSet; import java.util.Comparator; import java.util.Iterator; import java.util.List; +///////////////////////////////////////////////////////////////////////////////////////////////// +// IoTDB +///////////////////////////////////////////////////////////////////////////////////////////////// + /** * A ComparatorChain is a Comparator that wraps one or more Comparators in sequence. The * ComparatorChain calls each Comparator in sequence until either 1) any single Comparator returns a @@ -59,39 +62,6 @@ public class ComparatorChain implements Comparator, Serializable { /** Whether the chain has been "locked". */ private boolean isLocked = false; - // ----------------------------------------------------------------------- - /** - * Construct a ComparatorChain with no Comparators. You must add at least one Comparator before - * calling the compare(Object,Object) method, or an UnsupportedOperationException is thrown - */ - public ComparatorChain() { - this(new ArrayList>(), new BitSet()); - } - - /** - * Construct a ComparatorChain with a single Comparator, sorting in the forward order - * - * @param comparator First comparator in the Comparator chain - */ - public ComparatorChain(final Comparator comparator) { - this(comparator, false); - } - - /** - * Construct a Comparator chain with a single Comparator, sorting in the given order - * - * @param comparator First Comparator in the ComparatorChain - * @param reverse false = forward sort; true = reverse sort - */ - public ComparatorChain(final Comparator comparator, final boolean reverse) { - comparatorChain = new ArrayList<>(1); - comparatorChain.add(comparator); - orderingBits = new BitSet(1); - if (reverse == true) { - orderingBits.set(0); - } - } - /** * Construct a ComparatorChain from the Comparators in the List. All Comparators will default to * the forward sort order. @@ -120,114 +90,6 @@ public ComparatorChain(final List> list, final BitSet bits) { orderingBits = bits; } - // ----------------------------------------------------------------------- - /** - * Add a Comparator to the end of the chain using the forward sort order - * - * @param comparator Comparator with the forward sort order - */ - public void addComparator(final Comparator comparator) { - addComparator(comparator, false); - } - - /** - * Add a Comparator to the end of the chain using the given sort order - * - * @param comparator Comparator to add to the end of the chain - * @param reverse false = forward sort order; true = reverse sort order - */ - public void addComparator(final Comparator comparator, final boolean reverse) { - checkLocked(); - - comparatorChain.add(comparator); - if (reverse == true) { - orderingBits.set(comparatorChain.size() - 1); - } - } - - /** - * Replace the Comparator at the given index, maintaining the existing sort order. - * - * @param index index of the Comparator to replace - * @param comparator Comparator to place at the given index - * @throws IndexOutOfBoundsException if index < 0 or index >= size() - */ - public void setComparator(final int index, final Comparator comparator) - throws IndexOutOfBoundsException { - setComparator(index, comparator, false); - } - - /** - * Replace the Comparator at the given index in the ComparatorChain, using the given sort order - * - * @param index index of the Comparator to replace - * @param comparator Comparator to set - * @param reverse false = forward sort order; true = reverse sort order - */ - public void setComparator( - final int index, final Comparator comparator, final boolean reverse) { - checkLocked(); - - comparatorChain.set(index, comparator); - if (reverse == true) { - orderingBits.set(index); - } else { - orderingBits.clear(index); - } - } - - /** - * Change the sort order at the given index in the ComparatorChain to a forward sort. - * - * @param index Index of the ComparatorChain - */ - public void setForwardSort(final int index) { - checkLocked(); - orderingBits.clear(index); - } - - /** - * Change the sort order at the given index in the ComparatorChain to a reverse sort. - * - * @param index Index of the ComparatorChain - */ - public void setReverseSort(final int index) { - checkLocked(); - orderingBits.set(index); - } - - /** - * Number of Comparators in the current ComparatorChain. - * - * @return Comparator count - */ - public int size() { - return comparatorChain.size(); - } - - /** - * Determine if modifications can still be made to the ComparatorChain. ComparatorChains cannot be - * modified once they have performed a comparison. - * - * @return true = ComparatorChain cannot be modified; false = ComparatorChain can still be - * modified. - */ - public boolean isLocked() { - return isLocked; - } - - /** - * Throws an exception if the {@link ComparatorChain} is locked. - * - * @throws UnsupportedOperationException if the {@link ComparatorChain} is locked - */ - private void checkLocked() { - if (isLocked == true) { - throw new UnsupportedOperationException( - "Comparator ordering cannot be changed after the first comparison is performed"); - } - } - /** * Throws an exception if the {@link ComparatorChain} is empty. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java index 95ae7b159..db9bb9c9e 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java @@ -46,27 +46,7 @@ public E previous() { throw new NoSuchElementException("Iterator contains no elements"); } - public int nextIndex() { - return 0; - } - - public int previousIndex() { - return -1; - } - - public void add(final E obj) { - throw new UnsupportedOperationException("add() not supported for empty Iterator"); - } - - public void set(final E obj) { - throw new IllegalStateException("Iterator contains no elements"); - } - public void remove() { throw new IllegalStateException("Iterator contains no elements"); } - - public void reset() { - // do nothing - } } From 069b3bfa89526de1522d4fd68cde63fb4bebc7e1 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:03:30 +0800 Subject: [PATCH 7/8] fix --- .../commons/collections4/iterators/AbstractEmptyIterator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java index db9bb9c9e..010857690 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/collections4/iterators/AbstractEmptyIterator.java @@ -49,4 +49,8 @@ public E previous() { public void remove() { throw new IllegalStateException("Iterator contains no elements"); } + + public void reset() { + // do nothing + } } From 26a0b5320b4614dd8d51b654008ee1a26f0a1319 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:23:39 +0800 Subject: [PATCH 8/8] deletion --- .../commons/io/FileExistsException.java | 13 -- .../commons/io/build/AbstractOrigin.java | 46 ----- .../io/build/AbstractOriginSupplier.java | 39 ----- .../io/build/AbstractStreamBuilder.java | 152 ----------------- .../commons/io/file/CountingPathVisitor.java | 40 ----- .../commons/io/file/DeletingPathVisitor.java | 31 ---- .../external/commons/io/file/PathUtils.java | 7 - .../commons/io/file/SimplePathVisitor.java | 11 -- .../commons/io/filefilter/AndFileFilter.java | 61 ------- .../io/filefilter/ConditionalFileFilter.java | 27 --- .../io/filefilter/FalseFileFilter.java | 5 - .../commons/io/filefilter/IOFileFilter.java | 10 -- .../commons/io/filefilter/OrFileFilter.java | 20 --- .../io/filefilter/SuffixFileFilter.java | 51 ------ .../commons/io/filefilter/TrueFileFilter.java | 5 - .../commons/io/function/IOBaseStream.java | 12 -- .../commons/io/function/IOBiConsumer.java | 32 ---- .../commons/io/function/IOBiFunction.java | 11 -- .../commons/io/function/IOBinaryOperator.java | 45 +---- .../commons/io/function/IOFunction.java | 158 ------------------ .../commons/io/function/IOIntSupplier.java | 12 -- .../commons/io/function/IOIterator.java | 38 ----- .../commons/io/function/IOLongSupplier.java | 37 ---- .../commons/io/function/IOPredicate.java | 55 ------ .../commons/io/function/IOSpliterator.java | 11 -- .../commons/io/function/IOSupplier.java | 11 -- .../commons/io/function/IOTriConsumer.java | 34 ---- .../commons/io/function/IOTriFunction.java | 17 -- .../commons/io/function/IOUnaryOperator.java | 24 +-- .../io/function/UncheckedIOBaseStream.java | 88 ---------- .../io/function/UncheckedIOSpliterator.java | 82 --------- .../commons/io/input/ReaderInputStream.java | 26 --- .../io/output/ByteArrayOutputStream.java | 58 ------- .../io/output/StringBuilderWriter.java | 20 --- .../io/output/ThresholdingOutputStream.java | 47 ------ .../UnsynchronizedByteArrayOutputStream.java | 57 ------- 36 files changed, 2 insertions(+), 1391 deletions(-) delete mode 100644 java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java delete mode 100644 java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java delete mode 100644 java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java index e441a782a..b1cb25370 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/FileExistsException.java @@ -17,7 +17,6 @@ package org.apache.tsfile.external.commons.io; -import java.io.File; import java.io.IOException; /** @@ -30,18 +29,6 @@ public class FileExistsException extends IOException { /** Defines the serial version UID. */ private static final long serialVersionUID = 1L; - /** Default Constructor. */ - public FileExistsException() {} - - /** - * Constructs an instance with the specified file. - * - * @param file The file that exists - */ - public FileExistsException(final File file) { - super("File " + file + " exists"); - } - /** * Constructs an instance with the specified message. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java index 2ff4e7184..5189dfa81 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOrigin.java @@ -18,8 +18,6 @@ package org.apache.tsfile.external.commons.io.build; import org.apache.tsfile.external.commons.io.IOUtils; -import org.apache.tsfile.external.commons.io.RandomAccessFileMode; -import org.apache.tsfile.external.commons.io.RandomAccessFiles; import org.apache.tsfile.external.commons.io.input.ReaderInputStream; import org.apache.tsfile.external.commons.io.output.WriterOutputStream; @@ -30,7 +28,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.RandomAccessFile; import java.io.Reader; import java.io.Writer; import java.net.URI; @@ -39,7 +36,6 @@ import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Objects; /** @@ -151,13 +147,6 @@ public FileOrigin(final File origin) { super(origin); } - @Override - public byte[] getByteArray(final long position, final int length) throws IOException { - try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) { - return RandomAccessFiles.read(raf, position, length); - } - } - @Override public File getFile() { // No conversion @@ -248,13 +237,6 @@ public PathOrigin(final Path origin) { super(origin); } - @Override - public byte[] getByteArray(final long position, final int length) throws IOException { - try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) { - return RandomAccessFiles.read(raf, position, length); - } - } - @Override public File getFile() { return get().toFile(); @@ -398,34 +380,6 @@ public byte[] getByteArray() throws IOException { return Files.readAllBytes(getPath()); } - /** - * Gets this origin as a byte array, if possible. - * - * @param position the initial index of the range to be copied, inclusive. - * @param length How many bytes to copy. - * @return this origin as a byte array, if possible. - * @throws UnsupportedOperationException if the origin cannot be converted to a Path. - * @throws ArithmeticException if the {@code position} overflows an int - * @throws IOException if an I/O error occurs. - * @since 2.13.0 - */ - public byte[] getByteArray(final long position, final int length) throws IOException { - final byte[] bytes = getByteArray(); - // Checks for int overflow. - final int start = Math.toIntExact(position); - if (start < 0 || length < 0 || start + length < 0 || start + length > bytes.length) { - throw new IllegalArgumentException( - "Couldn't read array (start: " - + start - + ", length: " - + length - + ", data length: " - + bytes.length - + ")."); - } - return Arrays.copyOfRange(bytes, start, start + length); - } - /** * Gets this origin as a byte array, if possible. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java index 5ab4bca32..60ff55691 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractOriginSupplier.java @@ -173,24 +173,6 @@ protected static WriterOrigin newWriterOrigin(final Writer origin) { return origin; } - /** - * Gets the origin. - * - * @return the origin. - */ - protected AbstractOrigin getOrigin() { - return origin; - } - - /** - * Tests whether the origin is null. - * - * @return whether the origin is null. - */ - protected boolean hasOrigin() { - return origin != null; - } - /** * Sets a new origin. * @@ -201,17 +183,6 @@ public B setByteArray(final byte[] origin) { return setOrigin(newByteArrayOrigin(origin)); } - /** - * Sets a new origin. - * - * @param origin the new origin. - * @return this - * @since 2.13.0 - */ - public B setCharSequence(final CharSequence origin) { - return setOrigin(newCharSequenceOrigin(origin)); - } - /** * Sets a new origin. * @@ -293,16 +264,6 @@ public B setReader(final Reader origin) { return setOrigin(newReaderOrigin(origin)); } - /** - * Sets a new origin. - * - * @param origin the new origin. - * @return this - */ - public B setURI(final URI origin) { - return setOrigin(newURIOrigin(origin)); - } - /** * Sets a new origin. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java index c637fe1bb..cd5d75133 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/build/AbstractStreamBuilder.java @@ -22,8 +22,6 @@ import org.apache.tsfile.external.commons.io.file.PathUtils; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.io.Writer; import java.nio.charset.Charset; import java.nio.file.OpenOption; @@ -99,31 +97,6 @@ protected int getBufferSize() { return bufferSize; } - /** - * Gets the buffer size default, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value - * IOUtils#DEFAULT_BUFFER_SIZE}). - * - * @return the buffer size default, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value - * IOUtils#DEFAULT_BUFFER_SIZE}). - */ - protected int getBufferSizeDefault() { - return bufferSizeDefault; - } - - /** - * Gets a CharSequence from the origin with a Charset. - * - * @return An input stream - * @throws IOException if an I/O error occurs. - * @throws UnsupportedOperationException if the origin cannot be converted to a CharSequence. - * @throws IllegalStateException if the {@code origin} is {@code null}. - * @see AbstractOrigin#getCharSequence(Charset) - * @since 2.13.0 - */ - protected CharSequence getCharSequence() throws IOException { - return checkOrigin().getCharSequence(getCharset()); - } - /** * Gets the Charset, defaults to {@link Charset#defaultCharset()}. * @@ -142,38 +115,10 @@ protected Charset getCharsetDefault() { return charsetDefault; } - /** - * Gets an input stream from the origin with open options. - * - * @return An input stream - * @throws IOException if an I/O error occurs. - * @throws UnsupportedOperationException if the origin cannot be converted to an InputStream. - * @see AbstractOrigin#getInputStream(OpenOption...) - * @throws IllegalStateException if the {@code origin} is {@code null}. - * @since 2.13.0 - */ - protected InputStream getInputStream() throws IOException { - return checkOrigin().getInputStream(getOpenOptions()); - } - protected OpenOption[] getOpenOptions() { return openOptions; } - /** - * Gets an OutputStream from the origin with open options. - * - * @return An OutputStream - * @throws IOException if an I/O error occurs. - * @throws UnsupportedOperationException if the origin cannot be converted to an OutputStream. - * @throws IllegalStateException if the {@code origin} is {@code null}. - * @see AbstractOrigin#getOutputStream(OpenOption...) - * @since 2.13.0 - */ - protected OutputStream getOutputStream() throws IOException { - return checkOrigin().getOutputStream(getOpenOptions()); - } - /** * Gets a Path from the origin. * @@ -201,71 +146,6 @@ protected Writer getWriter() throws IOException { return checkOrigin().getWriter(getCharset(), getOpenOptions()); } - /** - * Sets the buffer size. Invalid input (bufferSize <= 0) resets the value to its default. - * - *

Subclasses may ignore this setting. - * - * @param bufferSize the buffer size. - * @return this. - */ - public B setBufferSize(final int bufferSize) { - this.bufferSize = checkBufferSize(bufferSize > 0 ? bufferSize : bufferSizeDefault); - return asThis(); - } - - /** - * Sets the buffer size. - * - *

Subclasses may ignore this setting. - * - * @param bufferSize the buffer size, null resets to the default. - * @return this. - */ - public B setBufferSize(final Integer bufferSize) { - setBufferSize(bufferSize != null ? bufferSize : bufferSizeDefault); - return asThis(); - } - - /** - * Sets the buffer size checker function. Throws a {@link IllegalArgumentException} by default. - * - * @param bufferSizeChecker the buffer size checker function. null resets to the default behavior. - * @return this - * @since 2.14.0 - */ - public B setBufferSizeChecker(final IntUnaryOperator bufferSizeChecker) { - this.bufferSizeChecker = bufferSizeChecker != null ? bufferSizeChecker : defaultSizeChecker; - return asThis(); - } - - /** - * Sets the buffer size for subclasses to initialize. - * - *

Subclasses may ignore this setting. - * - * @param bufferSizeDefault the buffer size, null resets to the default. - * @return this. - */ - protected B setBufferSizeDefault(final int bufferSizeDefault) { - this.bufferSizeDefault = bufferSizeDefault; - return asThis(); - } - - /** - * The maximum buffer size checked by the buffer size checker. Values less or equal to 0, resets - * to the int max value. By default, if this value is exceeded, this methods throws an {@link - * IllegalArgumentException}. - * - * @param bufferSizeMax maximum buffer size checked by the buffer size checker. - * @return this. - * @since 2.14.0 - */ - public B setBufferSizeMax(final int bufferSizeMax) { - this.bufferSizeMax = bufferSizeMax > 0 ? bufferSizeMax : DEFAULT_MAX_VALUE; - return asThis(); - } - /** * Sets the Charset. * @@ -291,38 +171,6 @@ public B setCharset(final String charset) { return setCharset(Charsets.toCharset(charset, charsetDefault)); } - /** - * Sets the Charset default for subclasses to initialize. - * - *

Subclasses may ignore this setting. - * - * @param defaultCharset the Charset name, null resets to the default. - * @return this. - */ - protected B setCharsetDefault(final Charset defaultCharset) { - this.charsetDefault = defaultCharset; - return asThis(); - } - - /** - * Sets the OpenOption[]. - * - *

Normally used with InputStream, OutputStream, and Writer. - * - *

Subclasses may ignore this setting. - * - * @param openOptions the OpenOption[] name, null resets to the default. - * @return this. - * @since 2.13.0 - * @see #setInputStream(InputStream) - * @see #setOutputStream(OutputStream) - * @see #setWriter(Writer) - */ - public B setOpenOptions(final OpenOption... openOptions) { - this.openOptions = openOptions != null ? openOptions : DEFAULT_OPEN_OPTIONS; - return asThis(); - } - private int throwIae(final int size, final int max) { throw new IllegalArgumentException(String.format("Request %,d exceeds maximum %,d", size, max)); } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java index 5d092a652..2caba2935 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/CountingPathVisitor.java @@ -21,10 +21,8 @@ import org.apache.tsfile.external.commons.io.filefilter.IOFileFilter; import org.apache.tsfile.external.commons.io.filefilter.SymbolicLinkFileFilter; import org.apache.tsfile.external.commons.io.filefilter.TrueFileFilter; -import org.apache.tsfile.external.commons.io.function.IOBiFunction; import java.io.IOException; -import java.math.BigInteger; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; @@ -48,24 +46,6 @@ static IOFileFilter defaultFileFilter() { return new SymbolicLinkFileFilter(FileVisitResult.TERMINATE, FileVisitResult.CONTINUE); } - /** - * Constructs a new instance configured with a {@link BigInteger} {@link PathCounters}. - * - * @return a new instance configured with a {@link BigInteger} {@link PathCounters}. - */ - public static CountingPathVisitor withBigIntegerCounters() { - return new CountingPathVisitor(Counters.bigIntegerPathCounters()); - } - - /** - * Constructs a new instance configured with a {@code long} {@link PathCounters}. - * - * @return a new instance configured with a {@code long} {@link PathCounters}. - */ - public static CountingPathVisitor withLongCounters() { - return new CountingPathVisitor(Counters.longPathCounters()); - } - private final PathCounters pathCounters; private final PathFilter fileFilter; private final PathFilter dirFilter; @@ -94,26 +74,6 @@ public CountingPathVisitor( this.dirFilter = Objects.requireNonNull(dirFilter, "dirFilter"); } - /** - * Constructs a new instance. - * - * @param pathCounter How to count path visits. - * @param fileFilter Filters which files to count. - * @param dirFilter Filters which directories to count. - * @param visitFileFailed Called on {@link #visitFileFailed(Path, IOException)}. - * @since 2.12.0 - */ - public CountingPathVisitor( - final PathCounters pathCounter, - final PathFilter fileFilter, - final PathFilter dirFilter, - final IOBiFunction visitFileFailed) { - super(visitFileFailed); - this.pathCounters = Objects.requireNonNull(pathCounter, "pathCounter"); - this.fileFilter = Objects.requireNonNull(fileFilter, "fileFilter"); - this.dirFilter = Objects.requireNonNull(dirFilter, "dirFilter"); - } - @Override public boolean equals(final Object obj) { if (this == obj) { diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java index 891e310bb..dcf56933a 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/DeletingPathVisitor.java @@ -17,8 +17,6 @@ package org.apache.tsfile.external.commons.io.file; -import org.apache.tsfile.external.commons.io.file.Counters.PathCounters; - import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; @@ -36,24 +34,6 @@ */ public class DeletingPathVisitor extends CountingPathVisitor { - /** - * Constructs a new instance configured with a BigInteger {@link PathCounters}. - * - * @return a new instance configured with a BigInteger {@link PathCounters}. - */ - public static DeletingPathVisitor withBigIntegerCounters() { - return new DeletingPathVisitor(Counters.bigIntegerPathCounters()); - } - - /** - * Constructs a new instance configured with a long {@link PathCounters}. - * - * @return a new instance configured with a long {@link PathCounters}. - */ - public static DeletingPathVisitor withLongCounters() { - return new DeletingPathVisitor(Counters.longPathCounters()); - } - private final String[] skip; private final boolean overrideReadOnly; private final LinkOption[] linkOptions; @@ -100,17 +80,6 @@ public DeletingPathVisitor( linkOptions == null ? PathUtils.noFollowLinkOptionArray() : linkOptions.clone(); } - /** - * Constructs a new visitor that deletes files except for the files and directories explicitly - * given. - * - * @param pathCounter How to count visits. - * @param skip The files to skip deleting. - */ - public DeletingPathVisitor(final Counters.PathCounters pathCounter, final String... skip) { - this(pathCounter, PathUtils.EMPTY_DELETE_OPTION_ARRAY, skip); - } - /** * Returns true to process the given path, false if not. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java index 9dc837800..59d3356d2 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/PathUtils.java @@ -69,13 +69,6 @@ public static Counters.PathCounters delete( : deleteFile(path, linkOptions, deleteOptions); } - public static Counters.PathCounters deleteFile( - final Path file, final DeleteOption... deleteOptions) throws IOException { - // Files.deleteIfExists() never follows links, so use LinkOption.NOFOLLOW_LINKS in other calls - // to Files. - return deleteFile(file, noFollowLinkOptionArray(), deleteOptions); - } - public static LinkOption[] noFollowLinkOptionArray() { return NOFOLLOW_LINK_OPTION_ARRAY.clone(); } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java index 578e81f7c..46a1ad666 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/file/SimplePathVisitor.java @@ -23,7 +23,6 @@ import java.nio.file.FileVisitResult; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; -import java.util.Objects; /** * A {@link SimpleFileVisitor} typed to a {@link Path}. @@ -39,16 +38,6 @@ protected SimplePathVisitor() { this.visitFileFailedFunction = super::visitFileFailed; } - /** - * Constructs a new instance. - * - * @param visitFileFailed Called on {@link #visitFileFailed(Path, IOException)}. - */ - protected SimplePathVisitor( - final IOBiFunction visitFileFailed) { - this.visitFileFailedFunction = Objects.requireNonNull(visitFileFailed, "visitFileFailed"); - } - @Override public FileVisitResult visitFileFailed(final Path file, final IOException exc) throws IOException { diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java index 7b83f1007..2f2e69e8c 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/AndFileFilter.java @@ -23,10 +23,8 @@ import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.stream.Stream; /** * A {@link FileFilter} providing conditional AND logic across a list of file filters. This filter @@ -48,15 +46,6 @@ public class AndFileFilter extends AbstractFileFilter /** The list of file filters. */ private final List fileFilters; - /** - * Constructs a new empty instance. - * - * @since 1.1 - */ - public AndFileFilter() { - this(0); - } - /** * Constructs a new instance with the given initial list. * @@ -75,17 +64,6 @@ private AndFileFilter(final int initialCapacity) { this(new ArrayList<>(initialCapacity)); } - /** - * Constructs a new instance for the give filters. - * - * @param fileFilters filters to OR. - * @since 2.9.0 - */ - public AndFileFilter(final IOFileFilter... fileFilters) { - this(Objects.requireNonNull(fileFilters, "fileFilters").length); - addFileFilter(fileFilters); - } - /** * Constructs a new file filter that ANDs the result of other filters. * @@ -99,16 +77,6 @@ public AndFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { addFileFilter(filter2); } - /** - * Constructs a new instance of {@link AndFileFilter} with the specified list of filters. - * - * @param fileFilters a List of IOFileFilter instances, copied. - * @since 1.1 - */ - public AndFileFilter(final List fileFilters) { - this(new ArrayList<>(Objects.requireNonNull(fileFilters, "fileFilters"))); - } - /** {@inheritDoc} */ @Override public boolean accept(final File file) { @@ -142,39 +110,10 @@ public void addFileFilter(final IOFileFilter fileFilter) { fileFilters.add(Objects.requireNonNull(fileFilter, "fileFilter")); } - /** - * Adds the given file filters. - * - * @param fileFilters the filters to add. - * @since 2.9.0 - */ - public void addFileFilter(final IOFileFilter... fileFilters) { - Stream.of(Objects.requireNonNull(fileFilters, "fileFilters")).forEach(this::addFileFilter); - } - - /** {@inheritDoc} */ - @Override - public List getFileFilters() { - return Collections.unmodifiableList(fileFilters); - } - private boolean isEmpty() { return fileFilters.isEmpty(); } - /** {@inheritDoc} */ - @Override - public boolean removeFileFilter(final IOFileFilter ioFileFilter) { - return fileFilters.remove(ioFileFilter); - } - - /** {@inheritDoc} */ - @Override - public void setFileFilters(final List fileFilters) { - this.fileFilters.clear(); - this.fileFilters.addAll(fileFilters); - } - /** * Builds a String representation of this file filter. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java index 5e8d34c73..94d1fa7b5 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/ConditionalFileFilter.java @@ -16,8 +16,6 @@ */ package org.apache.tsfile.external.commons.io.filefilter; -import java.util.List; - /** * Defines operations for conditional file filters. * @@ -32,29 +30,4 @@ public interface ConditionalFileFilter { * @since 1.1 */ void addFileFilter(IOFileFilter ioFileFilter); - - /** - * Gets this conditional file filter's list of file filters. - * - * @return the file filter list - * @since 1.1 - */ - List getFileFilters(); - - /** - * Removes the specified file filter. - * - * @param ioFileFilter filter to be removed - * @return {@code true} if the filter was found in the list, {@code false} otherwise - * @since 1.1 - */ - boolean removeFileFilter(IOFileFilter ioFileFilter); - - /** - * Sets the list of file filters, replacing any previously configured file filters on this filter. - * - * @param fileFilters the list of filters - * @since 1.1 - */ - void setFileFilters(List fileFilters); } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java index 2801b1d18..94864427e 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/FalseFileFilter.java @@ -96,11 +96,6 @@ public IOFileFilter and(final IOFileFilter fileFilter) { return INSTANCE; } - @Override - public IOFileFilter negate() { - return TrueFileFilter.INSTANCE; - } - @Override public IOFileFilter or(final IOFileFilter fileFilter) { // FALSE OR expression <=> expression diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java index 01c8ea114..3dea15de3 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/IOFileFilter.java @@ -96,16 +96,6 @@ default boolean matches(final Path path) { return accept(path, null) != FileVisitResult.TERMINATE; } - /** - * Constructs a new "not" filter with this filter. - * - * @return a new filter. - * @since 2.9.0 - */ - default IOFileFilter negate() { - return new NotFileFilter(this); - } - /** * Constructs a new "or" filter with this filter. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java index 8f1a72477..3061c31ba 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/OrFileFilter.java @@ -23,7 +23,6 @@ import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Stream; @@ -146,25 +145,6 @@ public void addFileFilter(final IOFileFilter... fileFilters) { Stream.of(Objects.requireNonNull(fileFilters, "fileFilters")).forEach(this::addFileFilter); } - /** {@inheritDoc} */ - @Override - public List getFileFilters() { - return Collections.unmodifiableList(this.fileFilters); - } - - /** {@inheritDoc} */ - @Override - public boolean removeFileFilter(final IOFileFilter fileFilter) { - return this.fileFilters.remove(fileFilter); - } - - /** {@inheritDoc} */ - @Override - public void setFileFilters(final List fileFilters) { - this.fileFilters.clear(); - this.fileFilters.addAll(Objects.requireNonNull(fileFilters, "fileFilters")); - } - /** * Provide a String representation of this file filter. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java index ba3c50c56..2139c3300 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/SuffixFileFilter.java @@ -23,7 +23,6 @@ import java.nio.file.FileVisitResult; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; -import java.util.List; import java.util.Objects; import java.util.stream.Stream; @@ -81,42 +80,6 @@ public class SuffixFileFilter extends AbstractFileFilter implements Serializable /** Whether the comparison is case-sensitive. */ private final IOCase ioCase; - /** - * Constructs a new Suffix file filter for a list of suffixes. - * - * @param suffixes the suffixes to allow, must not be null - * @throws IllegalArgumentException if the suffix list is null - * @throws ClassCastException if the list does not contain Strings - */ - public SuffixFileFilter(final List suffixes) { - this(suffixes, IOCase.SENSITIVE); - } - - /** - * Constructs a new Suffix file filter for a list of suffixes specifying case-sensitivity. - * - * @param suffixes the suffixes to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws IllegalArgumentException if the suffix list is null - * @throws ClassCastException if the list does not contain Strings - * @since 1.4 - */ - public SuffixFileFilter(final List suffixes, final IOCase ioCase) { - Objects.requireNonNull(suffixes, "suffixes"); - this.suffixes = suffixes.toArray(EMPTY_STRING_ARRAY); - this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); - } - - /** - * Constructs a new Suffix file filter for a single extension. - * - * @param suffix the suffix to allow, must not be null - * @throws IllegalArgumentException if the suffix is null - */ - public SuffixFileFilter(final String suffix) { - this(suffix, IOCase.SENSITIVE); - } - /** * Constructs a new Suffix file filter for an array of suffixes. * @@ -130,20 +93,6 @@ public SuffixFileFilter(final String... suffixes) { this(suffixes, IOCase.SENSITIVE); } - /** - * Constructs a new Suffix file filter for a single extension specifying case-sensitivity. - * - * @param suffix the suffix to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the suffix is null - * @since 1.4 - */ - public SuffixFileFilter(final String suffix, final IOCase ioCase) { - Objects.requireNonNull(suffix, "suffix"); - this.suffixes = new String[] {suffix}; - this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); - } - /** * Constructs a new Suffix file filter for an array of suffixes specifying case-sensitivity. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java index 38250ec6c..f7a8a2b05 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/filefilter/TrueFileFilter.java @@ -96,11 +96,6 @@ public IOFileFilter and(final IOFileFilter fileFilter) { return fileFilter; } - @Override - public IOFileFilter negate() { - return FalseFileFilter.INSTANCE; - } - @Override public IOFileFilter or(final IOFileFilter fileFilter) { // TRUE OR expression <=> true diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java index 532f3add0..9de5dd8c4 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBaseStream.java @@ -19,7 +19,6 @@ import java.io.Closeable; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.stream.BaseStream; import java.util.stream.Stream; @@ -34,17 +33,6 @@ public interface IOBaseStream, B extends BaseStream> extends Closeable { - /** - * Constructs a {@link BaseStream} for this instance that throws {@link UncheckedIOException} - * instead of {@link IOException}. - * - * @return an {@link UncheckedIOException} {@link BaseStream}. - */ - @SuppressWarnings("unchecked") - default BaseStream asBaseStream() { - return new UncheckedIOBaseStream<>((S) this); - } - /** * Like {@link BaseStream#close()}. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java index 1561b0b90..90b8cc879 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiConsumer.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.UncheckedIOException; -import java.util.Objects; import java.util.function.BiConsumer; /** @@ -33,18 +32,6 @@ @FunctionalInterface public interface IOBiConsumer { - /** - * Returns the no-op singleton. - * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation - * @return The no-op singleton. - */ - @SuppressWarnings("unchecked") - static IOBiConsumer noop() { - return Constants.IO_BI_CONSUMER; - } - /** * Performs this operation on the given arguments. * @@ -54,25 +41,6 @@ static IOBiConsumer noop() { */ void accept(T t, U u) throws IOException; - /** - * Creates a composed {@link IOBiConsumer} that performs, in sequence, this operation followed by - * the {@code after} operation. If performing either operation throws an exception, it is relayed - * to the caller of the composed operation. If performing this operation throws an exception, the - * {@code after} operation will not be performed. - * - * @param after the operation to perform after this operation - * @return a composed {@link IOBiConsumer} that performs in sequence this operation followed by - * the {@code after} operation - * @throws NullPointerException if {@code after} is null - */ - default IOBiConsumer andThen(final IOBiConsumer after) { - Objects.requireNonNull(after); - return (t, u) -> { - accept(t, u); - after.accept(t, u); - }; - } - /** * Creates a {@link BiConsumer} for this instance that throws {@link UncheckedIOException} instead * of {@link IOException}. diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java index 1a53c60ea..bd1dad52a 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBiFunction.java @@ -18,7 +18,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; @@ -63,14 +62,4 @@ default IOBiFunction andThen(final IOFunction asBiFunction() { - return (t, u) -> Uncheck.apply(this, t, u); - } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java index 595b3b46e..309a4c769 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOBinaryOperator.java @@ -18,8 +18,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Objects; import java.util.function.BinaryOperator; /** @@ -31,45 +29,4 @@ * @since 2.12.0 */ @FunctionalInterface -public interface IOBinaryOperator extends IOBiFunction { - - /** - * Creates a {@link IOBinaryOperator} which returns the greater of two elements according to the - * specified {@code Comparator}. - * - * @param the type of the input arguments of the comparator - * @param comparator a {@code Comparator} for comparing the two values - * @return a {@code BinaryOperator} which returns the greater of its operands, according to the - * supplied {@code Comparator} - * @throws NullPointerException if the argument is null - */ - static IOBinaryOperator maxBy(final IOComparator comparator) { - Objects.requireNonNull(comparator); - return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; - } - - /** - * Creates a {@link IOBinaryOperator} which returns the lesser of two elements according to the - * specified {@code Comparator}. - * - * @param the type of the input arguments of the comparator - * @param comparator a {@code Comparator} for comparing the two values - * @return a {@code BinaryOperator} which returns the lesser of its operands, according to the - * supplied {@code Comparator} - * @throws NullPointerException if the argument is null - */ - static IOBinaryOperator minBy(final IOComparator comparator) { - Objects.requireNonNull(comparator); - return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; - } - - /** - * Creates a {@link BinaryOperator} for this instance that throws {@link UncheckedIOException} - * instead of {@link IOException}. - * - * @return an unchecked BiFunction. - */ - default BinaryOperator asBinaryOperator() { - return (t, u) -> Uncheck.apply(this, t, u); - } -} +public interface IOBinaryOperator extends IOBiFunction {} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java index c9c153208..6beb29bf3 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOFunction.java @@ -18,11 +18,7 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Objects; -import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Supplier; /** * Like {@link Function} but throws {@link IOException}. @@ -34,83 +30,6 @@ @FunctionalInterface public interface IOFunction { - /** - * Returns a {@link IOFunction} that always returns its input argument. - * - * @param the type of the input and output objects to the function - * @return a function that always returns its input argument - */ - @SuppressWarnings("unchecked") - static IOFunction identity() { - return Constants.IO_FUNCTION_ID; - } - - /** - * Returns a composed {@link IOFunction} that first applies this function to its input, and then - * applies the {@code after} consumer to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param after the consumer to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} - * consumer - * @throws NullPointerException if after is null - * @see #compose(IOFunction) - */ - default IOConsumer andThen(final Consumer after) { - Objects.requireNonNull(after, "after"); - return (final T t) -> after.accept(apply(t)); - } - - /** - * Returns a composed {@link IOFunction} that first applies this function to its input, and then - * applies the {@code after} function to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} - * function - * @throws NullPointerException if after is null - * @see #compose(IOFunction) - */ - default IOFunction andThen(final Function after) { - Objects.requireNonNull(after, "after"); - return (final T t) -> after.apply(apply(t)); - } - - /** - * Returns a composed {@link IOFunction} that first applies this function to its input, and then - * applies the {@code after} consumer to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param after the consumer to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} - * consumer - * @throws NullPointerException if after is null - * @see #compose(IOFunction) - */ - default IOConsumer andThen(final IOConsumer after) { - Objects.requireNonNull(after, "after"); - return (final T t) -> after.accept(apply(t)); - } - - /** - * Returns a composed {@link IOFunction} that first applies this function to its input, and then - * applies the {@code after} function to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} - * function - * @throws NullPointerException if after is null - * @see #compose(IOFunction) - */ - default IOFunction andThen(final IOFunction after) { - Objects.requireNonNull(after, "after"); - return (final T t) -> after.apply(apply(t)); - } - /** * Applies this function to the given argument. * @@ -119,81 +38,4 @@ default IOFunction andThen(final IOFunction af * @throws IOException if an I/O error occurs. */ R apply(final T t) throws IOException; - - /** - * Creates a {@link Function} for this instance that throws {@link UncheckedIOException} instead - * of {@link IOException}. - * - * @return an UncheckedIOException Function. - * @since 2.12.0 - */ - default Function asFunction() { - return t -> Uncheck.apply(this, t); - } - - /** - * Returns a composed {@link IOFunction} that first applies the {@code before} function to its - * input, and then applies this function to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param the type of input to the {@code before} function, and to the composed function - * @param before the function to apply before this function is applied - * @return a composed function that first applies the {@code before} function and then applies - * this function - * @throws NullPointerException if before is null - * @see #andThen(IOFunction) - */ - default IOFunction compose(final Function before) { - Objects.requireNonNull(before, "before"); - return (final V v) -> apply(before.apply(v)); - } - - /** - * Returns a composed {@link IOFunction} that first applies the {@code before} function to its - * input, and then applies this function to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param the type of input to the {@code before} function, and to the composed function - * @param before the function to apply before this function is applied - * @return a composed function that first applies the {@code before} function and then applies - * this function - * @throws NullPointerException if before is null - * @see #andThen(IOFunction) - */ - default IOFunction compose(final IOFunction before) { - Objects.requireNonNull(before, "before"); - return (final V v) -> apply(before.apply(v)); - } - - /** - * Returns a composed {@link IOFunction} that first applies the {@code before} function to its - * input, and then applies this function to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param before the supplier which feeds the application of this function - * @return a composed function that first applies the {@code before} function and then applies - * this function - * @throws NullPointerException if before is null - * @see #andThen(IOFunction) - */ - default IOSupplier compose(final IOSupplier before) { - Objects.requireNonNull(before, "before"); - return () -> apply(before.get()); - } - - /** - * Returns a composed {@link IOFunction} that first applies the {@code before} function to its - * input, and then applies this function to the result. If evaluation of either function throws an - * exception, it is relayed to the caller of the composed function. - * - * @param before the supplier which feeds the application of this function - * @return a composed function that first applies the {@code before} function and then applies - * this function - * @throws NullPointerException if before is null - * @see #andThen(IOFunction) - */ - default IOSupplier compose(final Supplier before) { - Objects.requireNonNull(before, "before"); - return () -> apply(before.get()); - } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java index a136e7cde..b286ca0de 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIntSupplier.java @@ -18,9 +18,7 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.function.IntSupplier; -import java.util.function.Supplier; /** * Like {@link IntSupplier} but throws {@link IOException}. @@ -30,16 +28,6 @@ @FunctionalInterface public interface IOIntSupplier { - /** - * Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead - * of {@link IOException}. - * - * @return an UncheckedIOException Supplier. - */ - default IntSupplier asIntSupplier() { - return () -> Uncheck.getAsInt(this); - } - /** * Gets a result. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java index 24a25982f..fc1de6f82 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOIterator.java @@ -21,8 +21,6 @@ import java.io.UncheckedIOException; import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.function.Consumer; /** * Like {@link Iterator} but throws {@link IOException}. @@ -32,29 +30,6 @@ */ public interface IOIterator { - /** - * Adapts the given Iterable as an IOIterator. - * - * @param the type of the stream elements. - * @param iterable The iterable to adapt - * @return A new IOIterator - * @since 2.17.0 - */ - static IOIterator adapt(final Iterable iterable) { - return IOIteratorAdapter.adapt(iterable.iterator()); - } - - /** - * Adapts the given Iterator as an IOIterator. - * - * @param the type of the stream elements. - * @param iterator The iterator to adapt - * @return A new IOIterator - */ - static IOIterator adapt(final Iterator iterator) { - return IOIteratorAdapter.adapt(iterator); - } - /** * Creates an {@link Iterator} for this instance that throws {@link UncheckedIOException} instead * of {@link IOException}. @@ -65,19 +40,6 @@ default Iterator asIterator() { return new UncheckedIOIterator<>(this); } - /** - * Like {@link Iterator#forEachRemaining(Consumer)}. - * - * @param action See delegate. - * @throws IOException if an I/O error occurs. - */ - default void forEachRemaining(final IOConsumer action) throws IOException { - Objects.requireNonNull(action); - while (hasNext()) { - action.accept(next()); - } - } - /** * Like {@link Iterator#hasNext()}. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java deleted file mode 100644 index e3cd240c7..000000000 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOLongSupplier.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.tsfile.external.commons.io.function; - -import java.io.IOException; -import java.util.function.LongSupplier; - -/** - * Like {@link LongSupplier} but throws {@link IOException}. - * - * @since 2.14.0 - */ -@FunctionalInterface -public interface IOLongSupplier { - /** - * Gets a result. - * - * @return a result - * @throws IOException if an I/O error occurs. - */ - long getAsLong() throws IOException; -} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java index 9f51285f8..aab172e08 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOPredicate.java @@ -18,7 +18,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.Objects; import java.util.function.Predicate; @@ -31,41 +30,6 @@ @FunctionalInterface public interface IOPredicate { - /** - * Always false. - * - * @param the type of the input to the predicate - * @return a constant predicate that tests always false. - */ - @SuppressWarnings("unchecked") - static IOPredicate alwaysFalse() { - return (IOPredicate) Constants.IO_PREDICATE_FALSE; - } - - /** - * Always true. - * - * @param the type of the input to the predicate - * @return a constant predicate that tests always true. - */ - @SuppressWarnings("unchecked") - static IOPredicate alwaysTrue() { - return (IOPredicate) Constants.IO_PREDICATE_TRUE; - } - - /** - * Creates a predicate that tests if two arguments are equal using {@link Objects#equals(Object, - * Object)}. - * - * @param the type of arguments to the predicate - * @param target the object to compare for equality, may be {@code null} - * @return a predicate that tests if two arguments are equal using {@link Objects#equals(Object, - * Object)} - */ - static IOPredicate isEqual(final Object target) { - return null == target ? Objects::isNull : object -> target.equals(object); - } - /** * Creates a composed predicate that represents a short-circuiting logical AND of this predicate * and another. When evaluating the composed predicate, if this predicate is {@code false}, then @@ -85,25 +49,6 @@ default IOPredicate and(final IOPredicate other) { return t -> test(t) && other.test(t); } - /** - * Creates a {@link Predicate} for this instance that throws {@link UncheckedIOException} instead - * of {@link IOException}. - * - * @return an UncheckedIOException Predicate. - */ - default Predicate asPredicate() { - return t -> Uncheck.test(this, t); - } - - /** - * Creates a predicate that represents the logical negation of this predicate. - * - * @return a predicate that represents the logical negation of this predicate - */ - default IOPredicate negate() { - return t -> !test(t); - } - /** * Creates a composed predicate that represents a short-circuiting logical OR of this predicate * and another. When evaluating the composed predicate, if this predicate is {@code true}, then diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java index 4f06caa37..3b77590de 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSpliterator.java @@ -18,7 +18,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.Objects; import java.util.Spliterator; import java.util.function.Consumer; @@ -42,16 +41,6 @@ static IOSpliterator adapt(final Spliterator iterator) { return IOSpliteratorAdapter.adapt(iterator); } - /** - * Constructs a {@link Spliterator} for this instance that throws {@link UncheckedIOException} - * instead of {@link IOException}. - * - * @return an {@link UncheckedIOException} {@link Spliterator}. - */ - default Spliterator asSpliterator() { - return new UncheckedIOSpliterator<>(this); - } - /** * Like {@link Spliterator#characteristics()}. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java index 1641072d3..d971f6f67 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOSupplier.java @@ -33,17 +33,6 @@ @FunctionalInterface public interface IOSupplier { - /** - * Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead - * of {@link IOException}. - * - * @return an UncheckedIOException Supplier. - * @since 2.12.0 - */ - default Supplier asSupplier() { - return this::getUnchecked; - } - /** * Gets a result. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java index 4af5dcd58..a49067c2b 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriConsumer.java @@ -18,7 +18,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.util.Objects; import java.util.function.BiConsumer; /** @@ -33,19 +32,6 @@ @FunctionalInterface public interface IOTriConsumer { - /** - * Returns the no-op singleton. - * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation - * @param the type of the third argument to the operation - * @return The no-op singleton. - */ - @SuppressWarnings("unchecked") - static IOTriConsumer noop() { - return Constants.IO_TRI_CONSUMER; - } - /** * Performs this operation on the given arguments. * @@ -55,24 +41,4 @@ static IOTriConsumer noop() { * @throws IOException if an I/O error occurs. */ void accept(T t, U u, V v) throws IOException; - - /** - * Creates a composed {@link IOTriConsumer} that performs, in sequence, this operation followed by - * the {@code after} operation. If performing either operation throws an exception, it is relayed - * to the caller of the composed operation. If performing this operation throws an exception, the - * {@code after} operation will not be performed. - * - * @param after the operation to perform after this operation - * @return a composed {@link IOTriConsumer} that performs in sequence this operation followed by - * the {@code after} operation - * @throws NullPointerException if {@code after} is null - */ - default IOTriConsumer andThen( - final IOTriConsumer after) { - Objects.requireNonNull(after); - return (t, u, v) -> { - accept(t, u, v); - after.accept(t, u, v); - }; - } } diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java index e1aae3f26..33a4c009a 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOTriFunction.java @@ -17,7 +17,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.util.Objects; import java.util.function.Function; /** @@ -37,22 +36,6 @@ @FunctionalInterface public interface IOTriFunction { - /** - * Creates a composed function that first applies this function to its input, and then applies the - * {@code after} function to the result. If evaluation of either function throws an exception, it - * is relayed to the caller of the composed function. - * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} - * function - * @throws NullPointerException if after is null - */ - default IOTriFunction andThen(final IOFunction after) { - Objects.requireNonNull(after); - return (final T t, final U u, final V v) -> after.apply(apply(t, u, v)); - } - /** * Applies this function to the given arguments. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java index e11fea3fa..901308b26 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/IOUnaryOperator.java @@ -18,7 +18,6 @@ package org.apache.tsfile.external.commons.io.function; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.function.UnaryOperator; /** @@ -30,25 +29,4 @@ * @since 2.12.0 */ @FunctionalInterface -public interface IOUnaryOperator extends IOFunction { - - /** - * Creates a unary operator that always returns its input argument. - * - * @param the type of the input and output of the operator. - * @return a unary operator that always returns its input argument. - */ - static IOUnaryOperator identity() { - return t -> t; - } - - /** - * Creates a {@link UnaryOperator} for this instance that throws {@link UncheckedIOException} - * instead of {@link IOException}. - * - * @return an unchecked BiFunction. - */ - default UnaryOperator asUnaryOperator() { - return t -> Uncheck.apply(this, t); - } -} +public interface IOUnaryOperator extends IOFunction {} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java deleted file mode 100644 index c74f3e26a..000000000 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOBaseStream.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.tsfile.external.commons.io.function; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Iterator; -import java.util.Spliterator; -import java.util.stream.BaseStream; - -/** - * An {@link BaseStream} for a {@link IOBaseStream} that throws {@link UncheckedIOException} instead - * of {@link IOException}. - * - *

Keep package-private for now. - * - * @param the type of the stream elements. - * @param the type of the IO stream extending {@code IOBaseStream}. - * @param the type of the stream extending {@code BaseStream}. - */ -final class UncheckedIOBaseStream, B extends BaseStream> - implements BaseStream { - - private final S delegate; - - UncheckedIOBaseStream(final S delegate) { - this.delegate = delegate; - } - - @Override - public void close() { - delegate.close(); - } - - @Override - public boolean isParallel() { - return delegate.isParallel(); - } - - @Override - public Iterator iterator() { - return delegate.iterator().asIterator(); - } - - @SuppressWarnings("resource") - @Override - public B onClose(final Runnable closeHandler) { - return Uncheck.apply(delegate::onClose, () -> closeHandler.run()).unwrap(); - } - - @SuppressWarnings("resource") - @Override - public B parallel() { - return delegate.parallel().unwrap(); - } - - @SuppressWarnings("resource") - @Override - public B sequential() { - return delegate.sequential().unwrap(); - } - - @Override - public Spliterator spliterator() { - return delegate.spliterator().unwrap(); - } - - @SuppressWarnings("resource") - @Override - public B unordered() { - return delegate.unordered().unwrap(); - } -} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java deleted file mode 100644 index cd3e310ef..000000000 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/function/UncheckedIOSpliterator.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.tsfile.external.commons.io.function; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Comparator; -import java.util.Objects; -import java.util.Spliterator; -import java.util.function.Consumer; - -/** - * A {@link Spliterator} for an {@link IOSpliterator} that throws {@link UncheckedIOException} - * instead of {@link IOException}. - * - *

Keep package-private for now. - * - * @param the type of elements returned by this iterator. - */ -final class UncheckedIOSpliterator implements Spliterator { - - private final IOSpliterator delegate; - - UncheckedIOSpliterator(final IOSpliterator delegate) { - this.delegate = Objects.requireNonNull(delegate, "delegate"); - } - - @Override - public int characteristics() { - return delegate.characteristics(); - } - - @Override - public long estimateSize() { - return delegate.estimateSize(); - } - - @Override - public void forEachRemaining(final Consumer action) { - Uncheck.accept(delegate::forEachRemaining, action::accept); - } - - @Override - public Comparator getComparator() { - return delegate.getComparator().asComparator(); - } - - @Override - public long getExactSizeIfKnown() { - return delegate.getExactSizeIfKnown(); - } - - @Override - public boolean hasCharacteristics(final int characteristics) { - return delegate.hasCharacteristics(characteristics); - } - - @Override - public boolean tryAdvance(final Consumer action) { - return Uncheck.apply(delegate::tryAdvance, action::accept); - } - - @Override - public Spliterator trySplit() { - return Uncheck.get(delegate::trySplit).unwrap(); - } -} diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java index 0cfd018c6..93ce8c909 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/input/ReaderInputStream.java @@ -127,29 +127,12 @@ public ReaderInputStream get() throws IOException { checkOrigin().getReader(getCharset()), charsetEncoder, getBufferSize()); } - CharsetEncoder getCharsetEncoder() { - return charsetEncoder; - } - @Override public Builder setCharset(final Charset charset) { super.setCharset(charset); charsetEncoder = newEncoder(getCharset()); return this; } - - /** - * Sets the charset encoder. Assumes that the caller has configured the encoder. - * - * @param newEncoder the charset encoder, null resets to a default encoder. - * @return this - */ - public Builder setCharsetEncoder(final CharsetEncoder newEncoder) { - charsetEncoder = - CharsetEncoders.toCharsetEncoder(newEncoder, () -> newEncoder(getCharsetDefault())); - super.setCharset(charsetEncoder.charset()); - return this; - } } /** @@ -375,15 +358,6 @@ private void fillBuffer() throws IOException { encoderOut.flip(); } - /** - * Gets the CharsetEncoder. - * - * @return the CharsetEncoder. - */ - CharsetEncoder getCharsetEncoder() { - return charsetEncoder; - } - /** * Reads a single byte. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java index e33d69b98..9d3f014bd 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ByteArrayOutputStream.java @@ -16,7 +16,6 @@ */ package org.apache.tsfile.external.commons.io.output; -import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -28,63 +27,6 @@ // @ThreadSafe public class ByteArrayOutputStream extends AbstractByteArrayOutputStream { - /** - * Fetches entire contents of an {@link InputStream} and represent same data as result - * InputStream. - * - *

This method is useful where, - * - *

    - *
  • Source InputStream is slow. - *
  • It has network resources associated, so we cannot keep it open for long time. - *
  • It has network timeout associated. - *
- * - * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and - * copy of byte[].
- * This method buffers the input internally, so there is no need to use a {@link - * BufferedInputStream}. - * - * @param input Stream to be fully buffered. - * @return A fully buffered stream. - * @throws IOException if an I/O error occurs. - * @since 2.0 - */ - public static InputStream toBufferedInputStream(final InputStream input) throws IOException { - return toBufferedInputStream(input, DEFAULT_SIZE); - } - - /** - * Fetches entire contents of an {@link InputStream} and represent same data as result - * InputStream. - * - *

This method is useful where, - * - *

    - *
  • Source InputStream is slow. - *
  • It has network resources associated, so we cannot keep it open for long time. - *
  • It has network timeout associated. - *
- * - * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and - * copy of byte[].
- * This method buffers the input internally, so there is no need to use a {@link - * BufferedInputStream}. - * - * @param input Stream to be fully buffered. - * @param size the initial buffer size - * @return A fully buffered stream. - * @throws IOException if an I/O error occurs. - * @since 2.5 - */ - public static InputStream toBufferedInputStream(final InputStream input, final int size) - throws IOException { - try (ByteArrayOutputStream output = new ByteArrayOutputStream(size)) { - output.write(input); - return output.toInputStream(); - } - } - /** * Constructs a new byte array output stream. The buffer capacity is initially {@value * AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary. diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java index 627f90ee1..2545ac043 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/StringBuilderWriter.java @@ -43,26 +43,6 @@ public StringBuilderWriter() { this.builder = new StringBuilder(); } - /** - * Constructs a new {@link StringBuilder} instance with the specified capacity. - * - * @param capacity The initial capacity of the underlying {@link StringBuilder} - */ - public StringBuilderWriter(final int capacity) { - this.builder = new StringBuilder(capacity); - } - - /** - * Constructs a new instance with the specified {@link StringBuilder}. - * - *

If {@code builder} is null a new instance with default capacity will be created. - * - * @param builder The String builder. May be null. - */ - public StringBuilderWriter(final StringBuilder builder) { - this.builder = builder != null ? builder : new StringBuilder(); - } - /** * Appends a single character to this Writer. * diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java index 4c2c6f717..ffff4401f 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/ThresholdingOutputStream.java @@ -55,15 +55,6 @@ public class ThresholdingOutputStream extends OutputStream { /** Whether or not the configured threshold has been exceeded. */ private boolean thresholdExceeded; - /** - * Constructs an instance of this class which will trigger an event at the specified threshold. - * - * @param threshold The number of bytes at which to trigger an event. - */ - public ThresholdingOutputStream(final int threshold) { - this(threshold, IOConsumer.noop(), NOOP_OS_GETTER); - } - /** * Constructs an instance of this class which will trigger an event at the specified threshold. * @@ -124,15 +115,6 @@ public void flush() throws IOException { getStream().flush(); } - /** - * Gets the number of bytes that have been written to this output stream. - * - * @return The number of bytes written. - */ - public long getByteCount() { - return written; - } - /** * Gets the underlying output stream, to which the corresponding {@link OutputStream} methods in * this class will ultimately delegate. @@ -167,35 +149,6 @@ public int getThreshold() { return threshold; } - /** - * Tests whether or not the configured threshold has been exceeded for this output stream. - * - * @return {@code true} if the threshold has been reached; {@code false} otherwise. - */ - public boolean isThresholdExceeded() { - return written > threshold; - } - - /** - * Resets the byteCount to zero. You can call this from {@link #thresholdReached()} if you want - * the event to be triggered again. - */ - protected void resetByteCount() { - this.thresholdExceeded = false; - this.written = 0; - } - - /** - * Sets the byteCount to count. Useful for re-opening an output stream that has previously been - * written to. - * - * @param count The number of bytes that have already been written to the output stream - * @since 2.5 - */ - protected void setByteCount(final long count) { - this.written = count; - } - /** * Indicates that the configured threshold has been reached, and that a subclass should take * whatever action necessary on this event. This may include changing the underlying output diff --git a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java index 1f770ad49..ee4e767ef 100644 --- a/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java +++ b/java/tsfile/src/main/java/org/apache/tsfile/external/commons/io/output/UnsynchronizedByteArrayOutputStream.java @@ -21,7 +21,6 @@ import org.apache.tsfile.external.commons.io.function.Uncheck; import org.apache.tsfile.external.commons.io.input.UnsynchronizedByteArrayInputStream; -import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -82,62 +81,6 @@ public static Builder builder() { return new Builder(); } - /** - * Fetches entire contents of an {@link InputStream} and represent same data as result - * InputStream. - * - *

This method is useful where, - * - *

    - *
  • Source InputStream is slow. - *
  • It has network resources associated, so we cannot keep it open for long time. - *
  • It has network timeout associated. - *
- * - * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and - * copy of byte[].
- * This method buffers the input internally, so there is no need to use a {@link - * BufferedInputStream}. - * - * @param input Stream to be fully buffered. - * @return A fully buffered stream. - * @throws IOException if an I/O error occurs. - */ - public static InputStream toBufferedInputStream(final InputStream input) throws IOException { - return toBufferedInputStream(input, DEFAULT_SIZE); - } - - /** - * Fetches entire contents of an {@link InputStream} and represent same data as result - * InputStream. - * - *

This method is useful where, - * - *

    - *
  • Source InputStream is slow. - *
  • It has network resources associated, so we cannot keep it open for long time. - *
  • It has network timeout associated. - *
- * - * It can be used in favor of {@link #toByteArray()}, since it avoids unnecessary allocation and - * copy of byte[].
- * This method buffers the input internally, so there is no need to use a {@link - * BufferedInputStream}. - * - * @param input Stream to be fully buffered. - * @param size the initial buffer size - * @return A fully buffered stream. - * @throws IOException if an I/O error occurs. - */ - public static InputStream toBufferedInputStream(final InputStream input, final int size) - throws IOException { - // It does not matter if a ByteArrayOutputStream is not closed as close() is a no-op - try (UnsynchronizedByteArrayOutputStream output = builder().setBufferSize(size).get()) { - output.write(input); - return output.toInputStream(); - } - } - /** * Constructs a new byte array output stream. The buffer capacity is initially *