├── .appveyor.yml ├── .checkstyle ├── .classpath ├── .factorypath.template ├── .gitignore ├── .gitlab-ci.yml ├── .idea ├── SoSy-Lab Common.iml ├── ant.xml ├── checkstyle-idea.xml ├── codeStyleSettings.xml ├── compiler.xml ├── copyright │ ├── commons.xml │ └── profiles_settings.xml ├── encodings.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── junitgenerator-prj-settings.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── .project ├── .reuse └── templates │ └── header.jinja2 ├── .settings ├── Ant Builder.launch ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.apt.core.prefs ├── org.eclipse.jdt.core.prefs └── org.eclipse.jdt.ui.prefs ├── Development.md ├── LICENSE ├── LICENSES ├── Apache-2.0.txt └── LGPL-2.1-only.txt ├── README.md ├── build.xml ├── build ├── SpotBugs.exclude.xml ├── build-checkstyle.xml ├── build-compile.xml ├── build-documentation.xml ├── build-format-source.xml ├── build-ivy.xml ├── build-jar.xml ├── build-junit.xml ├── build-maven-publish.xml ├── build-publish.xml ├── build-spotbugs.xml ├── build-version.xml ├── checkstyle.test.xml ├── checkstyle.xml ├── checkstyle.xsl ├── deploy-gh-pages.sh ├── gitlab-ci.Dockerfile.jdk-11 ├── gitlab-ci.Dockerfile.jdk-17 ├── gitlab-ci.Dockerfile.jdk-21 ├── gitlab-ci.Dockerfile.jdk-23 ├── gitlab-ci.yml └── ivysettings.xml ├── doc └── javadoc_overview.html ├── lib └── ivy.xml ├── pom_template.xml ├── src └── org │ └── sosy_lab │ └── common │ ├── AbstractMBean.java │ ├── Appender.java │ ├── Appenders.java │ ├── AppendersTest.java │ ├── ChildFirstPatternClassLoader.java │ ├── Classes.java │ ├── ClassesFactoryTest.java │ ├── ClassesTest.java │ ├── Concurrency.java │ ├── ConcurrencyTest.java │ ├── ExtendedUrlClassLoader.java │ ├── ExtendedUrlClassLoaderTest.java │ ├── JSON.java │ ├── LazyFutureTask.java │ ├── LazyFutureTaskTest.java │ ├── MoreStrings.java │ ├── MoreStringsTest.java │ ├── NativeLibraries.java │ ├── OptionalComparators.java │ ├── OptionalComparatorsTest.java │ ├── Optionals.java │ ├── PackageSanityTest.java │ ├── ProcessExecutor.java │ ├── ProcessExecutorTest.java │ ├── ShutdownManager.java │ ├── ShutdownNotifier.java │ ├── ShutdownNotifierTest.java │ ├── UniqueIdGenerator.java │ ├── annotations │ ├── FieldsAreNonnullByDefault.java │ ├── ReturnValuesAreNonnullByDefault.java │ ├── SuppressForbidden.java │ ├── Unmaintained.java │ └── package-info.java │ ├── collect │ ├── AbstractImmutableMap.java │ ├── AbstractImmutableSortedMap.java │ ├── Collections3.java │ ├── Collections3Test.java │ ├── CollectionsAllElementsEqualTest.java │ ├── CollectionsTransformationTest.java │ ├── CopyOnWriteSortedMap.java │ ├── CopyOnWriteSortedMapTest.java │ ├── DescendingSortedMap.java │ ├── MapValues.java │ ├── MapsDifference.java │ ├── MoreCollectors.java │ ├── NaiveOrderStatisticMap.java │ ├── NaiveOrderStatisticMapTest.java │ ├── NaiveOrderStatisticSet.java │ ├── NaiveOrderStatisticSetTest.java │ ├── OrderStatisticMap.java │ ├── OrderStatisticMapTestSuite.java │ ├── OrderStatisticSet.java │ ├── OrderStatisticSetTestSuite.java │ ├── OurSortedMap.java │ ├── PackageSanityTest.java │ ├── PathCopyingPersistentTreeMap.java │ ├── PathCopyingPersistentTreeMapTest.java │ ├── PersistentLinkedList.java │ ├── PersistentLinkedListTest.java │ ├── PersistentList.java │ ├── PersistentMap.java │ ├── PersistentSortedMap.java │ ├── PersistentSortedMapBridge.java │ ├── PersistentSortedMaps.java │ ├── PersistentSortedMapsTest.java │ ├── SortedMapEntrySet.java │ ├── SortedMapKeySet.java │ ├── SortedMapKeySetTest.java │ └── package-info.java │ ├── configuration │ ├── AnnotatedValue.java │ ├── ClassOption.java │ ├── Configuration.java │ ├── ConfigurationBuilder.java │ ├── ConfigurationBuilderTest.java │ ├── ConfigurationTest.java │ ├── FileOption.java │ ├── IntegerOption.java │ ├── InvalidConfigurationException.java │ ├── Option.java │ ├── OptionAnnotationProcessor.java │ ├── OptionCollector.java │ ├── OptionDetailAnnotation.java │ ├── OptionPlainTextWriter.java │ ├── Options.java │ ├── PackageSanityTest.java │ ├── Parser.java │ ├── ParserTest.java │ ├── TimeSpanOption.java │ ├── converters │ │ ├── BaseTypeConverter.java │ │ ├── ClassTypeConverter.java │ │ ├── FileTypeConverter.java │ │ ├── FileTypeConverterTest.java │ │ ├── IntegerTypeConverter.java │ │ ├── TimeSpanTypeConverter.java │ │ ├── TimeSpanTypeConverterTest.java │ │ ├── TypeConverter.java │ │ └── package-info.java │ └── package-info.java │ ├── io │ ├── DuplicateOutputStream.java │ ├── IO.java │ ├── MoreFiles.java │ ├── PackageSanityTest.java │ ├── PathCounterTemplate.java │ ├── PathTemplate.java │ ├── TempFile.java │ └── package-info.java │ ├── log │ ├── AbstractColoredLogFormatter.java │ ├── BasicLogManager.java │ ├── BasicLogManagerTest.java │ ├── ConsoleLogFormatter.java │ ├── ExtendedLogRecord.java │ ├── FileLogFormatter.java │ ├── ForwardingLogManager.java │ ├── ForwardingLogManagerTest.java │ ├── LogFormatterTest.java │ ├── LogLevelFilter.java │ ├── LogManager.java │ ├── LogManagerWithoutDuplicates.java │ ├── LogUtils.java │ ├── LoggingOptions.java │ ├── NullLogManager.java │ ├── PackageSanityTest.java │ ├── StringBuildingLogHandler.java │ ├── TestLogManager.java │ ├── TimestampedLogFormatter.java │ └── package-info.java │ ├── package-info.java │ ├── rationals │ ├── ExtendedRational.java │ ├── LinearExpression.java │ ├── PackageSanityTest.java │ ├── Rational.java │ ├── package-info.java │ └── tests │ │ ├── ExtendedRationalTest.java │ │ ├── LinearExpressionTest.java │ │ ├── RationalTest.java │ │ └── package-info.java │ └── time │ ├── NestedTimer.java │ ├── PackageSanityTest.java │ ├── Tickers.java │ ├── TimeSpan.java │ ├── TimeSpanTest.java │ ├── Timer.java │ ├── TimerTest.java │ └── package-info.java └── website └── index.html /.appveyor.yml: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | version: build {build} {branch} 10 | 11 | os: Visual Studio 2019 12 | 13 | clone_depth: 1 14 | 15 | install: 16 | - ps: | 17 | Add-Type -AssemblyName System.IO.Compression.FileSystem 18 | if (!(Test-Path -Path "C:\ant\apache-ant-1.10.12" )) { 19 | (new-object System.Net.WebClient).DownloadFile( 20 | 'https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.12-bin.zip', 21 | 'C:\ant-bin.zip' 22 | ) 23 | [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\ant-bin.zip", "C:\ant") 24 | } 25 | - cmd: SET JAVA_HOME=C:\Program Files\Java\jdk17 26 | - cmd: SET PATH=C:\ant\apache-ant-1.10.12\bin;%JAVA_HOME%\bin;%PATH% 27 | - cmd: SET IVY_CACHE_DIR=C:\ivy 28 | - cmd: echo %USERPROFILE% 29 | - cmd: echo %PATH% 30 | - cmd: java -version 31 | 32 | build_script: 33 | - ant build 34 | 35 | test_script: 36 | - ant unit-tests 37 | 38 | on_finish: 39 | - ps: | 40 | $url = "https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)" 41 | $file = '.\junit\TESTS-TestSuites.xml' 42 | $webclient = New-Object 'System.Net.WebClient' 43 | # uploads currently fail because of many tests (https://github.com/appveyor/ci/issues/2084) 44 | try { $webclient.UploadFile($url, (Resolve-Path $file)) } catch { $_ } 45 | 46 | cache: 47 | - C:\ant 48 | - C:\ivy 49 | -------------------------------------------------------------------------------- /.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /.factorypath.template: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | # / 10 | /bin 11 | /.apt-generated/ 12 | /build.properties 13 | /ivy-*.xml 14 | /common-*.jar 15 | /TEST-*.txt 16 | /junit 17 | /JUnit.html 18 | /JUnit-coverage 19 | /Checkstyle.html 20 | /Checkstyle.xml 21 | /Checkstyle.Test.html 22 | /Checkstyle.Test.xml 23 | /SpotBugs.html 24 | /SpotBugs.xml 25 | /SpotBugs.diff.html 26 | /SpotBugs.diff.xml 27 | /Javadoc 28 | /gh-pages 29 | /.factorypath 30 | /repository 31 | 32 | # /.idea/ 33 | /.idea/workspace.xml 34 | /.idea/uiDesigner.xml 35 | 36 | # /lib/ 37 | /lib/java 38 | /lib/java-contrib 39 | 40 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | include: /build/gitlab-ci.yml 10 | 11 | variables: 12 | PROJECT_PATH: "sosy-lab/software/java-common-lib" 13 | GH_REF: "github.com/sosy-lab/java-common-lib" 14 | # Version of https://gitlab.com/sosy-lab/software/refaster/ to use 15 | REFASTER_REPO_REVISION: 8b7f38e2afedf64b3cfa9592bbb8790b88f58352 16 | # Needs to be synchronized with Error Prone version in lib/ivy.xml 17 | REFASTER_VERSION: "2.31.0" 18 | -------------------------------------------------------------------------------- /.idea/ant.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 33 | 34 | -------------------------------------------------------------------------------- /.idea/copyright/commons.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 46 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 17 | -------------------------------------------------------------------------------- /.idea/junitgenerator-prj-settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 35 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | SoSy-Lab Common 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.ui.externaltools.ExternalToolBuilder 21 | auto,full,incremental, 22 | 23 | 24 | LaunchConfigHandle 25 | <project>/.settings/Ant Builder.launch 26 | 27 | 28 | 29 | 30 | org.eclipse.jdt.core.javabuilder 31 | 32 | 33 | 34 | 35 | net.sf.eclipsecs.core.CheckstyleBuilder 36 | 37 | 38 | 39 | 40 | 41 | org.eclipse.jdt.core.javanature 42 | net.sf.eclipsecs.core.CheckstyleNature 43 | 44 | 45 | -------------------------------------------------------------------------------- /.reuse/templates/header.jinja2: -------------------------------------------------------------------------------- 1 | This file is part of SoSy-Lab Common, 2 | a library of useful utilities: 3 | https://github.com/sosy-lab/java-common-lib 4 | 5 | {% for copyright_line in copyright_lines %} 6 | {{ copyright_line }} 7 | {% endfor %} 8 | 9 | {% for expression in spdx_expressions %} 10 | SPDX-License-Identifier: {{ expression }} 11 | {% endfor %} 12 | -------------------------------------------------------------------------------- /.settings/Ant Builder.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Java-Project Template, 2 | # a collection of common files and build definitions for Java projects: 3 | # https://gitlab.com/sosy-lab/software/java-project-template 4 | # 5 | # SPDX-FileCopyrightText: 2018-2020 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | #Fri Jul 29 10:23:52 CEST 2011 10 | eclipse.preferences.version=1 11 | encoding/=UTF-8 12 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Java-Project Template, 2 | # a collection of common files and build definitions for Java projects: 3 | # https://gitlab.com/sosy-lab/software/java-project-template 4 | # 5 | # SPDX-FileCopyrightText: 2018-2020 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | eclipse.preferences.version=1 10 | org.eclipse.jdt.apt.aptEnabled=true 11 | org.eclipse.jdt.apt.genSrcDir=.apt-generated 12 | org.eclipse.jdt.apt.reconcileEnabled=true 13 | -------------------------------------------------------------------------------- /Development.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | # Style Guide 12 | 13 | The style guide of this project is the 14 | [Google Java Style](https://google.github.io/styleguide/javaguide.html). 15 | 16 | IMPORTANT: We use an automatic code formatter to format all our code. 17 | Before committing, run `ant format-source` to reformat your changes 18 | according to the style guide. 19 | 20 | ## Before Committing 21 | 22 | Please run `ant all-checks` and check and clear any reported problems. 23 | 24 | ## Mailing List for Notifications 25 | 26 | There is a [mailing list](https://groups.google.com/forum/#!forum/common-java-dev) with 27 | notifications for commits and CI failures. 28 | It is recommended to subscribe to this list to get notified of failing builds. 29 | 30 | You can also use this list for discussion among developers, 31 | or use the [GitHub issue tracker](https://github.com/sosy-lab/java-common-lib/issues). 32 | 33 | ## Note for Eclipse Users 34 | 35 | This project uses [Google AutoValue](https://github.com/google/auto/tree/master/value). 36 | Eclipse does not pick up its annotation processor automatically. 37 | You need to copy the file `.factorypath.template` to `.factorypath` 38 | and adjust the path inside if your Eclipse project is not named "SoSy-Lab Common". 39 | 40 | We recommend to install the [Eclipse Checkstyle plugin](https://checkstyle.org/eclipse-cs/) 41 | and the [plugin with additional Checkstyle checks](https://github.com/sevntu-checkstyle/sevntu.checkstyle) 42 | to be able to see the Checkstyle warnings in Eclipse 43 | (the necessary configuration is included in the repository). 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | # SoSy-Lab Common 12 | 13 | [![Build Status](https://travis-ci.org/sosy-lab/java-common-lib.svg "Build Status")](https://travis-ci.org/sosy-lab/java-common-lib) 14 | [![Apache 2.0 License](https://img.shields.io/badge/license-Apache--2-brightgreen.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) 15 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.sosy-lab/common/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.sosy-lab/common) 16 | 17 | A collection of utilities for Java. 18 | 19 | ### [Java-Config](https://sosy-lab.github.io/java-common-lib/api/org/sosy_lab/common/configuration/package-summary.html) 20 | 21 | - Library for configuration options injection. 22 | 23 | ### [Java-Rationals](https://sosy-lab.github.io/java-common-lib/api/org/sosy_lab/common/rationals/package-summary.html) 24 | 25 | - Working with rationals and extended rationals, plus linear expressions. 26 | 27 | 28 | [Javadoc documentation](https://sosy-lab.github.io/java-common-lib/) for entire project. 29 | 30 | ## License and Copyright 31 | 32 | The license of this project is the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0), 33 | copyright [Dirk Beyer](https://www.sosy-lab.org/people/beyer/) and others. 34 | 35 | ## Installation 36 | 37 | ### Using ANT and Ivy 38 | 39 | If we use ANT with Ivy in your build process, you can download the latest version of 40 | SoSy-Lab Common from our repositories directly. 41 | The updates to the Ivy repository are very frequent, and the latest version can 42 | be easily found. 43 | 44 | The dependency is: 45 | 46 | ```xml 47 | 48 | ``` 49 | 50 | And the Ivy repository URL is: 51 | 52 | ```xml 53 | https://www.sosy-lab.org/ivy 54 | ``` 55 | 56 | ### From Maven Central 57 | 58 | The Common library is also published to Maven Central, however the volume of 59 | updates is less frequent. 60 | If you use Maven, the dependency is: 61 | 62 | ```xml 63 | 64 | org.sosy-lab 65 | common 66 | 0.3000 67 | 68 | ``` 69 | 70 | Or for Gradle: 71 | 72 | ``` 73 | dependencies { 74 | compile 'org.sosy-lab:common:0.3000' 75 | } 76 | ``` 77 | 78 | ### Manually 79 | 80 | The latest JAR can be downloaded directly from the Ivy repository, served at 81 | 82 | ``` 83 | https://www.sosy-lab.org/ivy/org.sosy_lab/common/ 84 | ``` 85 | 86 | This option is least recommended, as the required dependencies (namely, 87 | Guava and AutoValue) would need to be downloaded manually. 88 | Download the `.ivy` file corresponding to the obtained `jar` to see 89 | the dependencies and their location in the repository. 90 | -------------------------------------------------------------------------------- /build/SpotBugs.exclude.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /build/build-checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /build/build-documentation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ${ant.project.name}]]> 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /build/build-format-source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /build/build-jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /build/build-maven-publish.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 16 | 17 | 18 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /build/build-publish.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 28 | 30 | 37 | 38 | You now want to run 39 | cd repository/${ivy.organisation}/${ivy.module} 40 | svn add *-${version}* 41 | svn ci -m"publish version ${version} of ${ant.project.name}" 42 | cd - 43 | to make the new version publicly available. 44 | 45 | 46 | -------------------------------------------------------------------------------- /build/build-spotbugs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | SpotBugs found warnings, generating report. 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | SpotBugs found new warnings, generating report. 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /build/build-version.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /build/deploy-gh-pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This file is part of SoSy-Lab Java-Project Template, 4 | # a collection of common files and build definitions for Java projects: 5 | # https://gitlab.com/sosy-lab/software/java-project-template 6 | # 7 | # SPDX-FileCopyrightText: 2018-2020 Dirk Beyer 8 | # 9 | # SPDX-License-Identifier: Apache-2.0 10 | 11 | set -e # exit with nonzero exit code if anything fails 12 | 13 | # DO NOT EDIT LOCALLY! 14 | # Keep this file synchronized with 15 | # https://gitlab.com/sosy-lab/software/java-project-template 16 | 17 | rm -rf gh-pages || true 18 | mkdir -p gh-pages/api 19 | cp -r website/* gh-pages 20 | cp -r Javadoc/* gh-pages/api 21 | find bin -name ConfigurationOptions.txt -exec cp {} gh-pages/ \; 22 | 23 | # we need to tell git who we are 24 | git config --global user.name "${GIT_NAME}" 25 | git config --global user.email "${GIT_EMAIL}" 26 | 27 | cd gh-pages 28 | git init 29 | 30 | # The first and only commit to this new Git repo contains all the 31 | # files present with the commit message "Deploy to GitHub Pages". 32 | git add . 33 | git commit -m "Deploy to GitHub Pages" 34 | 35 | # Force push from the current repo's HEAD to the remote 36 | # repo's gh-pages branch. (All previous history on the gh-pages branch 37 | # will be lost, since we are overwriting it.) We redirect any output to 38 | # /dev/null to hide any sensitive credential data that might otherwise be exposed. 39 | git push --force --quiet "https://${GH_USER}:${GH_TOKEN}@${GH_REF}" HEAD:gh-pages > /dev/null 2>&1 40 | -------------------------------------------------------------------------------- /build/gitlab-ci.Dockerfile.jdk-11: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | # This is a container image for running the tests. 10 | # It should be pushed to registry.gitlab.com/sosy-lab/software/java-common-lib/test 11 | # and will be used by CI as declared in .gitlab-ci.yml. 12 | # 13 | # Commands for updating the image: 14 | # podman build --pull -t registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-11 - < build/gitlab-ci.Dockerfile.jdk-11 15 | # podman push registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-11 16 | 17 | FROM registry.gitlab.com/sosy-lab/software/java-project-template/test:jdk-11 18 | -------------------------------------------------------------------------------- /build/gitlab-ci.Dockerfile.jdk-17: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2022 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | # This is a container image for running the tests. 10 | # It should be pushed to registry.gitlab.com/sosy-lab/software/java-common-lib/test 11 | # and will be used by CI as declared in .gitlab-ci.yml. 12 | # 13 | # Commands for updating the image: 14 | # podman build --pull -t registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-17 - < build/gitlab-ci.Dockerfile.jdk-17 15 | # podman push registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-17 16 | 17 | FROM registry.gitlab.com/sosy-lab/software/java-project-template/test:jdk-17 18 | -------------------------------------------------------------------------------- /build/gitlab-ci.Dockerfile.jdk-21: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2023 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | # This is a container image for running the tests. 10 | # It should be pushed to registry.gitlab.com/sosy-lab/software/java-common-lib/test 11 | # and will be used by CI as declared in .gitlab-ci.yml. 12 | # 13 | # Commands for updating the image: 14 | # podman build --pull -t registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-21 - < build/gitlab-ci.Dockerfile.jdk-21 15 | # podman push registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-21 16 | 17 | FROM registry.gitlab.com/sosy-lab/software/java-project-template/test:jdk-21 18 | -------------------------------------------------------------------------------- /build/gitlab-ci.Dockerfile.jdk-23: -------------------------------------------------------------------------------- 1 | # This file is part of SoSy-Lab Common, 2 | # a library of useful utilities: 3 | # https://github.com/sosy-lab/java-common-lib 4 | # 5 | # SPDX-FileCopyrightText: 2007-2024 Dirk Beyer 6 | # 7 | # SPDX-License-Identifier: Apache-2.0 8 | 9 | # This is a container image for running the tests. 10 | # It should be pushed to registry.gitlab.com/sosy-lab/software/java-common-lib/test 11 | # and will be used by CI as declared in .gitlab-ci.yml. 12 | # 13 | # Commands for updating the image: 14 | # podman build --pull -t registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-23 - < build/gitlab-ci.Dockerfile.jdk-23 15 | # podman push registry.gitlab.com/sosy-lab/software/java-common-lib/test:jdk-23 16 | 17 | FROM registry.gitlab.com/sosy-lab/software/java-project-template/test:jdk-23 18 | -------------------------------------------------------------------------------- /build/ivysettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/javadoc_overview.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 |

SoSy-Lab Common is a library of useful utilities.

15 | 16 | 17 | -------------------------------------------------------------------------------- /pom_template.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 13 | 14 | 4.0.0 15 | ${ivy.pom.groupId} 16 | ${ivy.pom.artifactId} 17 | ${ivy.pom.packaging} 18 | ${ivy.pom.version} 19 | ${ivy.pom.name} 20 | ${ivy.pom.description} 21 | ${ivy.pom.url} 22 | 23 | 24 | 25 | Apache License, Version 2.0 26 | http://www.apache.org/licenses/LICENSE-2.0.txt 27 | 28 | 29 | 30 | 31 | Software Systems Lab 32 | https://www.sosy-lab.org/ 33 | 34 | 35 | 36 | https://github.com/sosy-lab/java-common-lib/ 37 | scm:git:git://github.com/sosy-lab/java-common-lib.git 38 | scm:git:git@github.com:sosy-lab/java-common-lib.git 39 | 40 | 41 | 42 | 43 | Philipp Wendler 44 | uni@philippwendler.de 45 | Software Systems Lab 46 | https://www.sosy-lab.org/people/wendler/ 47 | 48 | project maintainer 49 | 50 | 51 | 52 | Karlheinz Friedberger 53 | kfriedberger@gmail.com 54 | Software Systems Lab 55 | https://www.sosy-lab.org/people/friedberger/ 56 | 57 | project maintainer 58 | 59 | 60 | 61 | Dirk Beyer 62 | dirk.beyer@sosy-lab.org 63 | https://www.sosy-lab.org/people/beyer/ 64 | Software Systems Lab 65 | http://www.sosy-lab.org/ 66 | 67 | project manager 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/AbstractMBean.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import java.lang.management.ManagementFactory; 14 | import java.util.logging.Level; 15 | import javax.management.JMException; 16 | import javax.management.MBeanServer; 17 | import javax.management.MalformedObjectNameException; 18 | import javax.management.ObjectName; 19 | import javax.management.RuntimeErrorException; 20 | import org.checkerframework.checker.nullness.qual.Nullable; 21 | import org.sosy_lab.common.log.LogManager; 22 | 23 | /** 24 | * Abstract class that encapsulates the registration of an MBean with the {@link MBeanServer}. 25 | * Exceptions that occur are swallowed and logged. 26 | * 27 | *

This class is not thread-safe. 28 | */ 29 | public abstract class AbstractMBean { 30 | 31 | private static final @Nullable MBeanServer MBEAN_SERVER = getMBeanServer(); 32 | 33 | private static @Nullable MBeanServer getMBeanServer() { 34 | try { 35 | // wrap this call in method so that an exception does not prevent the 36 | // whole program from continuing 37 | return ManagementFactory.getPlatformMBeanServer(); 38 | } catch (SecurityException e) { 39 | // ignore exception because we cannot handle it here 40 | return null; 41 | } 42 | } 43 | 44 | private @Nullable ObjectName oname = null; 45 | private final LogManager logger; 46 | 47 | protected AbstractMBean(String name, LogManager logger) { 48 | this.logger = checkNotNull(logger); 49 | 50 | if (MBEAN_SERVER != null) { 51 | try { 52 | oname = new ObjectName(checkNotNull(name)); 53 | } catch (MalformedObjectNameException e) { 54 | logger.logException( 55 | Level.WARNING, e, "Invalid object name specified for management interface"); 56 | } 57 | } 58 | } 59 | 60 | protected RuntimeErrorException handleRuntimeErrorException(RuntimeErrorException e) { 61 | if (e.getTargetError() != null) { 62 | // Errors are better not hidden in an exception. 63 | throw e.getTargetError(); 64 | } 65 | throw e; 66 | } 67 | 68 | /** 69 | * Register this instance at the platform MBeanServer. Swallows all checked exceptions that might 70 | * occur and logs them. 71 | */ 72 | public void register() { 73 | if (MBEAN_SERVER != null && oname != null) { 74 | try { 75 | 76 | // if there is already an existing MBean with the same name, try to unregister it 77 | if (MBEAN_SERVER.isRegistered(oname)) { 78 | MBEAN_SERVER.unregisterMBean(oname); 79 | 80 | assert !MBEAN_SERVER.isRegistered(oname); 81 | } 82 | 83 | // now register our instance 84 | MBEAN_SERVER.registerMBean(this, oname); 85 | 86 | } catch (RuntimeErrorException e) { 87 | throw handleRuntimeErrorException(e); 88 | } catch (JMException | SecurityException e) { 89 | logger.logfUserException( 90 | Level.WARNING, 91 | e, 92 | "Error during registration of management interface %s", 93 | this.getClass().getSimpleName()); 94 | oname = null; 95 | } 96 | } else { 97 | logger.log( 98 | Level.WARNING, "Cannot register management interface ", this.getClass().getSimpleName()); 99 | } 100 | } 101 | 102 | /** 103 | * Unregister this instance. May be called even if registration was not successful (does nothing 104 | * in this case). 105 | */ 106 | public void unregister() { 107 | if (MBEAN_SERVER != null && oname != null) { 108 | try { 109 | MBEAN_SERVER.unregisterMBean(oname); 110 | } catch (RuntimeErrorException e) { 111 | throw handleRuntimeErrorException(e); 112 | } catch (JMException | SecurityException e) { 113 | logger.logException( 114 | Level.WARNING, e, "Error during unregistration of management interface"); 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/Appender.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * An interface for classes that know how to dump themselves into an {@link Appendable}. This can be 15 | * used for large string outputs, where writing into an Appendable is faster than creating a string 16 | * and then writing it in one piece. 17 | */ 18 | public interface Appender { 19 | 20 | /** 21 | * Writes a string representation of this object into the given {@link Appendable}. 22 | * 23 | *

It is strongly encouraged that this method behaves identically to 24 | * appendable.append(this.toString()), except for possibly calling append multiple times 25 | * with bits of the output. 26 | * 27 | * @param appendable The appendable, may not be null. 28 | * @throws IOException If the appendable throws an IOException 29 | */ 30 | void appendTo(Appendable appendable) throws IOException; 31 | } 32 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/AppendersTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import java.io.IOException; 14 | import org.junit.Test; 15 | import org.sosy_lab.common.Appenders.AbstractAppender; 16 | 17 | public class AppendersTest { 18 | 19 | @SuppressWarnings("UnnecessaryAnonymousClass") // easier for test 20 | private final Appender testAppender = 21 | new AbstractAppender() { 22 | @Override 23 | public void appendTo(Appendable out) throws IOException { 24 | out.append("123"); 25 | out.append("456"); 26 | out.append("7"); 27 | out.append("8"); 28 | out.append("9"); 29 | } 30 | }; 31 | 32 | @Test 33 | public void testToStringWithTruncation_NoLimit() { 34 | assertThat(Appenders.toStringWithTruncation(testAppender, 100)).isEqualTo("123456789"); 35 | assertThat(Appenders.toStringWithTruncation(testAppender, 10)).isEqualTo("123456789"); 36 | assertThat(Appenders.toStringWithTruncation(testAppender, 9)).isEqualTo("123456789"); 37 | } 38 | 39 | @Test 40 | public void testToStringWithTruncation_Limit() { 41 | assertThat(Appenders.toStringWithTruncation(testAppender, 8)).isEqualTo("12345678"); 42 | assertThat(Appenders.toStringWithTruncation(testAppender, 7)).isEqualTo("1234567"); 43 | assertThat(Appenders.toStringWithTruncation(testAppender, 6)).isEqualTo("123456"); 44 | assertThat(Appenders.toStringWithTruncation(testAppender, 5)).isEqualTo("12345"); 45 | assertThat(Appenders.toStringWithTruncation(testAppender, 4)).isEqualTo("1234"); 46 | assertThat(Appenders.toStringWithTruncation(testAppender, 3)).isEqualTo("123"); 47 | assertThat(Appenders.toStringWithTruncation(testAppender, 2)).isEqualTo("12"); 48 | assertThat(Appenders.toStringWithTruncation(testAppender, 1)).isEqualTo("1"); 49 | assertThat(Appenders.toStringWithTruncation(testAppender, 0)).isEqualTo(""); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/ChildFirstPatternClassLoader.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.errorprone.annotations.Var; 14 | import java.net.URL; 15 | import java.net.URLClassLoader; 16 | import java.util.function.Predicate; 17 | import java.util.regex.Pattern; 18 | 19 | /** 20 | * This is a {@link URLClassLoader} that behaves like a normal class loader except that it loads 21 | * some classes always by itself, even if the parent class loader would also have been available to 22 | * load them. 23 | * 24 | *

Normal class loaders follow the parent-first strategy, so they never load classes which their 25 | * parent could also load. This class loader follows the child-first strategy for a specific set of 26 | * classes (given by a pattern) and the parent-first strategy for the rest. 27 | * 28 | *

This class loader can be used if you want to load a component with its own class loader (so 29 | * that it can be garbage collected independently, for example), but the parent class loader also 30 | * sees the classes. 31 | * 32 | * @deprecated replaced with {@link Classes#makeExtendedURLClassLoader()} and {@link 33 | * Classes.ClassLoaderBuilder#setDirectLoadClasses(Predicate)}. 34 | */ 35 | @Deprecated 36 | @SuppressWarnings({ 37 | "AvoidObjectArrays", 38 | "BanClassLoader" 39 | }) // deprecated class, usage inherited from super class 40 | public class ChildFirstPatternClassLoader extends URLClassLoader { 41 | 42 | private final Predicate loadInChild; 43 | 44 | /** 45 | * Create a new class loader. 46 | * 47 | * @param pLoadInChild The predicate telling which classes should never be loaded by the parent. 48 | * @param pUrls The sources where this class loader should load classes from. 49 | * @param pParent The parent class loader. 50 | */ 51 | public ChildFirstPatternClassLoader( 52 | Predicate pLoadInChild, URL[] pUrls, ClassLoader pParent) { 53 | super(pUrls, checkNotNull(pParent)); 54 | loadInChild = checkNotNull(pLoadInChild); 55 | } 56 | 57 | /** 58 | * Create a new class loader. 59 | * 60 | * @param pClassPattern The pattern telling which classes should never be loaded by the parent. 61 | * @param pUrls The sources where this class loader should load classes from. 62 | * @param pParent The parent class loader. 63 | */ 64 | public ChildFirstPatternClassLoader(Pattern pClassPattern, URL[] pUrls, ClassLoader pParent) { 65 | super(pUrls, checkNotNull(pParent)); 66 | checkNotNull(pClassPattern); 67 | loadInChild = s -> pClassPattern.matcher(s).matches(); 68 | } 69 | 70 | @Override 71 | protected Class loadClass(String name, boolean pResolve) throws ClassNotFoundException { 72 | if (!loadInChild.test(name)) { 73 | return super.loadClass(name, pResolve); 74 | } 75 | 76 | // This is the same code as in {@link URLClassLoader#loadClass(String, boolean) 77 | // except that it never asks the parent class loader 78 | synchronized (getClassLoadingLock(name)) { 79 | // First, check if the class has already been loaded 80 | @Var Class c = findLoadedClass(name); 81 | if (c == null) { 82 | // If still not found, then invoke findClass in order 83 | // to find the class. 84 | c = findClass(name); 85 | } 86 | if (pResolve) { 87 | resolveClass(c); 88 | } 89 | return c; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/ClassesTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import com.google.common.collect.ImmutableList; 14 | import java.io.FileNotFoundException; 15 | import java.io.IOException; 16 | import org.junit.Test; 17 | 18 | public class ClassesTest { 19 | 20 | private static void assertIsAllowed( 21 | Iterable> declaredExceptionTypes, Iterable> allowedExceptionTypes) { 22 | assertThat(Classes.verifyDeclaredExceptions(declaredExceptionTypes, allowedExceptionTypes)) 23 | .isNull(); 24 | } 25 | 26 | private static void assertIsForbidden( 27 | String forbiddenException, 28 | Iterable> declaredExceptionTypes, 29 | Iterable> allowedExceptionTypes) { 30 | assertThat(Classes.verifyDeclaredExceptions(declaredExceptionTypes, allowedExceptionTypes)) 31 | .isEqualTo(forbiddenException); 32 | } 33 | 34 | @Test 35 | public void verifyDeclaredException_Error() { 36 | assertIsAllowed(ImmutableList.of(Error.class), ImmutableList.of()); 37 | } 38 | 39 | @Test 40 | public void verifyDeclaredException_RuntimeException() { 41 | assertIsAllowed(ImmutableList.of(RuntimeException.class), ImmutableList.of()); 42 | } 43 | 44 | @Test 45 | public void verifyDeclaredException_Throwable() { 46 | assertIsForbidden("Throwable", ImmutableList.of(Throwable.class), ImmutableList.of()); 47 | } 48 | 49 | @Test 50 | public void verifyDeclaredException_Exception() { 51 | assertIsForbidden("Exception", ImmutableList.of(Exception.class), ImmutableList.of()); 52 | } 53 | 54 | @Test 55 | public void verifyDeclaredException_DeclaredException() { 56 | assertIsAllowed(ImmutableList.of(Exception.class), ImmutableList.of(Exception.class)); 57 | } 58 | 59 | @Test 60 | public void verifyDeclaredException_DeclaredSuperException() { 61 | assertIsAllowed(ImmutableList.of(Exception.class), ImmutableList.of(Throwable.class)); 62 | } 63 | 64 | @Test 65 | public void verifyDeclaredException_DeclaredSubException() { 66 | assertIsForbidden( 67 | "Exception", ImmutableList.of(Exception.class), ImmutableList.of(IOException.class)); 68 | } 69 | 70 | @Test 71 | public void verifyDeclaredException_DeclaredMultipleExceptions() { 72 | assertIsAllowed( 73 | ImmutableList.of(FileNotFoundException.class), 74 | ImmutableList.of(RuntimeException.class, IOException.class)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/Concurrency.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 14 | import com.google.errorprone.annotations.Var; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Executors; 17 | import java.util.concurrent.ThreadFactory; 18 | import java.util.concurrent.TimeUnit; 19 | 20 | /** Helper methods for concurrency related things. */ 21 | public final class Concurrency { 22 | 23 | private Concurrency() {} 24 | 25 | /** 26 | * Wait uninterruptibly until an ExecutorService has shutdown. It also ensures full memory 27 | * visibility of everything that was done in the callables. 28 | * 29 | *

Interrupting the thread will have no effect, but this method will set the thread's 30 | * interrupted flag in this case. 31 | */ 32 | public static void waitForTermination(ExecutorService executor) { 33 | @Var boolean interrupted = Thread.interrupted(); 34 | 35 | while (!executor.isTerminated()) { 36 | try { 37 | executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 38 | } catch (InterruptedException ignored) { 39 | interrupted = true; 40 | } 41 | } 42 | 43 | // now all tasks have terminated 44 | 45 | // restore interrupted flag 46 | if (interrupted) { 47 | Thread.currentThread().interrupt(); 48 | } 49 | } 50 | 51 | /** 52 | * Creates a thread pool of fixed size. Size is determined by processors available to the JVM. 53 | * 54 | * @return thread pool 55 | */ 56 | public static ExecutorService createThreadPool() { 57 | int processors = Runtime.getRuntime().availableProcessors(); 58 | return Executors.newFixedThreadPool(processors); 59 | } 60 | 61 | /** 62 | * Creates a thread pool of fixed size. Size is determined by processors available to the JVM. 63 | * 64 | * @param threadFactory The thread factory to be used. 65 | * @return thread pool 66 | */ 67 | public static ExecutorService createThreadPool(ThreadFactory threadFactory) { 68 | int processors = Runtime.getRuntime().availableProcessors(); 69 | return Executors.newFixedThreadPool(processors, threadFactory); 70 | } 71 | 72 | /** 73 | * Create a new non-daemon thread with a name. Compared to creating threads manually, this has the 74 | * advantage that the thread will be created with the default settings. By default, Java lets 75 | * threads inherit some settings from the creating thread. 76 | * 77 | * @param name The name of the new thread. 78 | * @param r The {@link Runnable} to execute in the new thread. 79 | * @return A new thread, not yet started. 80 | */ 81 | public static Thread newThread(String name, Runnable r) { 82 | checkNotNull(r); 83 | return new ThreadFactoryBuilder().setNameFormat(name).build().newThread(r); 84 | } 85 | 86 | /** 87 | * Create a new daemon thread with a name. Compared to creating threads manually, this has the 88 | * advantage that the thread will be created with the default settings. By default, Java lets 89 | * threads inherit some settings from the creating thread. 90 | * 91 | * @param name The name of the new thread. 92 | * @param r The {@link Runnable} to execute in the new thread. 93 | * @return A new daemon thread, not yet started. 94 | */ 95 | public static Thread newDaemonThread(String name, Runnable r) { 96 | checkNotNull(r); 97 | return new ThreadFactoryBuilder().setNameFormat(name).setDaemon(true).build().newThread(r); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/ConcurrencyTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | import org.mockito.Mock; 16 | import org.mockito.junit.MockitoJUnit; 17 | import org.mockito.junit.MockitoRule; 18 | 19 | public class ConcurrencyTest { 20 | 21 | @Rule public MockitoRule mockito = MockitoJUnit.rule(); 22 | 23 | @Mock private Runnable mockRunnable; 24 | 25 | @Test 26 | public void shouldSetDaemon() throws Exception { 27 | Thread t = Concurrency.newDaemonThread("t", mockRunnable); 28 | assertThat(t.isDaemon()).isTrue(); 29 | } 30 | 31 | @Test 32 | public void shouldUseNameFormat() throws Exception { 33 | Thread t1 = Concurrency.newThread("test-%d", mockRunnable); 34 | assertThat(t1.getName()).isEqualTo("test-0"); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/ExtendedUrlClassLoader.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.auto.value.AutoValue; 14 | import com.google.common.collect.ImmutableList; 15 | import com.google.errorprone.annotations.Var; 16 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 17 | import java.net.URL; 18 | import java.net.URLClassLoader; 19 | import java.nio.file.Path; 20 | import java.util.Optional; 21 | import java.util.function.Predicate; 22 | 23 | /** 24 | * Extension of {@link URLClassLoader} with an optional child-first strategy and optional overriding 25 | * of the search path for native libraries. 26 | */ 27 | @SuppressWarnings("BanClassLoader") 28 | final class ExtendedUrlClassLoader extends URLClassLoader { 29 | 30 | private final ExtendedUrlClassLoaderConfiguration config; 31 | 32 | private ExtendedUrlClassLoader(ExtendedUrlClassLoaderConfiguration pConfig) { 33 | super( 34 | pConfig.urls().toArray(new URL[0]), 35 | pConfig.parent().orElseGet(ClassLoader::getSystemClassLoader)); 36 | config = pConfig; 37 | } 38 | 39 | @AutoValue 40 | @SuppressWarnings("NoFunctionalReturnType") 41 | abstract static class ExtendedUrlClassLoaderConfiguration { 42 | abstract Optional parent(); 43 | 44 | abstract ImmutableList urls(); 45 | 46 | abstract Predicate directLoadClasses(); 47 | 48 | abstract Predicate customLookupNativeLibraries(); 49 | 50 | static AutoBuilder builder() { 51 | return new AutoValue_ExtendedUrlClassLoader_ExtendedUrlClassLoaderConfiguration.Builder(); 52 | } 53 | 54 | @AutoValue.Builder 55 | abstract static class AutoBuilder extends Classes.ClassLoaderBuilder { 56 | AutoBuilder() {} 57 | 58 | @SuppressFBWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED") 59 | @Override 60 | public final URLClassLoader build() { 61 | return new ExtendedUrlClassLoader(autoBuild()); 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | protected Class loadClass(String name, boolean pResolve) throws ClassNotFoundException { 68 | if (!config.directLoadClasses().test(name)) { 69 | return super.loadClass(name, pResolve); 70 | } 71 | 72 | // This is the same code as in {@link URLClassLoader#loadClass(String, boolean) 73 | // except that it never asks the parent class loader 74 | synchronized (getClassLoadingLock(name)) { 75 | // First, check if the class has already been loaded 76 | @Var Class c = findLoadedClass(name); 77 | if (c == null) { 78 | // If still not found, then invoke findClass in order 79 | // to find the class. 80 | c = findClass(name); 81 | } 82 | if (pResolve) { 83 | resolveClass(c); 84 | } 85 | return c; 86 | } 87 | } 88 | 89 | @Override 90 | protected String findLibrary(String libname) { 91 | checkNotNull(libname); 92 | if (config.customLookupNativeLibraries().test(libname)) { 93 | @SuppressWarnings("deprecation") 94 | Optional path = NativeLibraries.findPathForLibrary(libname); 95 | if (path.isPresent()) { 96 | return path.orElseThrow().toAbsolutePath().toString(); 97 | } 98 | } 99 | return super.findLibrary(libname); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/ExtendedUrlClassLoaderTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static org.junit.Assert.assertThrows; 13 | 14 | import java.io.IOException; 15 | import java.net.URI; 16 | import java.net.URISyntaxException; 17 | import java.net.URL; 18 | import java.net.URLClassLoader; 19 | import java.util.regex.Pattern; 20 | import org.junit.Test; 21 | import org.sosy_lab.common.Classes.ClassLoaderBuilder; 22 | 23 | public class ExtendedUrlClassLoaderTest { 24 | 25 | private static final Pattern TEST_DUMMY_PATTERN = Pattern.compile("dummy pattern"); 26 | private static final Class TEST_CLASS = String.class; 27 | 28 | private static ClassLoaderBuilder newDefaultBuilder() { 29 | return Classes.makeExtendedURLClassLoader().setUrls(); 30 | } 31 | 32 | @Test 33 | public void testCreateNoParent() throws IOException { 34 | try (URLClassLoader cl = newDefaultBuilder().build()) { 35 | assertThat(cl.getParent()).isEqualTo(ClassLoader.getSystemClassLoader()); 36 | } 37 | } 38 | 39 | @Test 40 | public void testCreateWithParent() throws IOException { 41 | ClassLoader parent = new ClassLoader() {}; 42 | try (URLClassLoader cl = newDefaultBuilder().setParent(parent).build()) { 43 | assertThat(cl.getParent()).isEqualTo(parent); 44 | } 45 | } 46 | 47 | @Test 48 | public void testCreateWithURLs() throws IOException, URISyntaxException { 49 | URL testUrl = new URI("file:///").toURL(); 50 | try (URLClassLoader cl = newDefaultBuilder().setUrls(testUrl).build()) { 51 | assertThat(cl.getURLs()).asList().containsExactly(testUrl); 52 | } 53 | } 54 | 55 | @Test 56 | public void testDelegationNonMatching() throws IOException, ClassNotFoundException { 57 | try (URLClassLoader cl = newDefaultBuilder().setDirectLoadClasses(TEST_DUMMY_PATTERN).build()) { 58 | assertThat(cl.loadClass(TEST_CLASS.getName())).isEqualTo(TEST_CLASS); 59 | } 60 | } 61 | 62 | @Test 63 | public void testDelegationMatchingNotFound() throws IOException { 64 | String testClassName = TEST_CLASS.getName(); 65 | try (URLClassLoader cl = 66 | newDefaultBuilder() 67 | .setDirectLoadClasses(Pattern.compile(Pattern.quote(testClassName))) 68 | .build()) { 69 | 70 | assertThrows(ClassNotFoundException.class, () -> cl.loadClass(testClassName)); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/LazyFutureTask.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import java.util.concurrent.Callable; 12 | import java.util.concurrent.ExecutionException; 13 | import java.util.concurrent.FutureTask; 14 | import java.util.concurrent.TimeUnit; 15 | import org.checkerframework.checker.nullness.qual.Nullable; 16 | 17 | /** 18 | * Future implementation that can be used when a task should be executed only lazily at the first 19 | * time {@link #get()} is called. I.e., it is not guaranteed that the task is run at all, but it is 20 | * called at most once. 21 | * 22 | *

Execution of the task happens in the caller's thread, a little bit similar to the use of 23 | * {@link com.google.common.util.concurrent.MoreExecutors#newDirectExecutorService()}, however, it 24 | * is executed on the thread calling {@link #get()} and not on the thread calling {@link 25 | * java.util.concurrent.ExecutorService#submit(Callable)}. 26 | * 27 | *

Important: Calling {@link #get(long, TimeUnit)} is not supported and will always throw {@link 28 | * UnsupportedOperationException}. 29 | * 30 | *

Canceling this future works as expected. 31 | */ 32 | public class LazyFutureTask extends FutureTask { 33 | 34 | public LazyFutureTask(Callable pCallable) { 35 | super(pCallable); 36 | } 37 | 38 | public LazyFutureTask(Runnable pRunnable, V pResult) { 39 | super(pRunnable, pResult); 40 | } 41 | 42 | @Override 43 | public void run() { 44 | // Do nothing here, we execute the task only lazily in get(). 45 | } 46 | 47 | @Override 48 | public V get() throws InterruptedException, ExecutionException { 49 | if (!isDone()) { 50 | // Note that two threads calling this method at the same time is safe 51 | // (the task won't actually be executed twice) 52 | // because super.run() checks whether the future is currently in state 53 | // RUNNING and does nothing in this case. 54 | // (This is an advantage over using Guava's AbstractFuture, 55 | // where we would have to do this ourselves.) 56 | super.run(); 57 | } 58 | 59 | return super.get(); 60 | } 61 | 62 | /** 63 | * @throws UnsupportedOperationException Always 64 | * @deprecated Unsupported operation. 65 | */ 66 | @Deprecated 67 | @Override 68 | public V get(long pTimeout, TimeUnit pUnit) { 69 | throw new UnsupportedOperationException(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/LazyFutureTaskTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static org.junit.Assert.assertThrows; 13 | 14 | import com.google.common.util.concurrent.Callables; 15 | import com.google.common.util.concurrent.Runnables; 16 | import java.util.concurrent.CancellationException; 17 | import java.util.concurrent.ExecutionException; 18 | import java.util.concurrent.Future; 19 | import java.util.concurrent.atomic.AtomicBoolean; 20 | import org.checkerframework.checker.nullness.qual.Nullable; 21 | import org.junit.Test; 22 | 23 | public class LazyFutureTaskTest { 24 | 25 | @Test 26 | public void testRunnable() throws InterruptedException, ExecutionException { 27 | AtomicBoolean test = new AtomicBoolean(false); 28 | 29 | Future f = new LazyFutureTask<>(() -> test.set(true), true); 30 | 31 | assertThat(f.get()).isTrue(); 32 | assertThat(test.get()).isTrue(); 33 | } 34 | 35 | @Test 36 | public void testCallable() throws InterruptedException, ExecutionException { 37 | 38 | Future f = new LazyFutureTask<>(Callables.returning(true)); 39 | 40 | assertThat(f.get()).isTrue(); 41 | } 42 | 43 | @Test 44 | public void testException() { 45 | NullPointerException testException = new NullPointerException(); 46 | 47 | Future f = 48 | new LazyFutureTask<>( 49 | () -> { 50 | throw testException; 51 | }); 52 | 53 | ExecutionException thrown = assertThrows(ExecutionException.class, () -> f.get()); 54 | assertThat(thrown).hasCauseThat().isSameInstanceAs(testException); 55 | } 56 | 57 | @Test 58 | @SuppressWarnings({"unused", "CheckReturnValue"}) 59 | public void testNoExecution() { 60 | AtomicBoolean test = new AtomicBoolean(true); 61 | 62 | new LazyFutureTask<@Nullable Void>(() -> test.set(false), null); 63 | 64 | // no call to f.get() 65 | assertThat(test.get()).isTrue(); 66 | } 67 | 68 | @Test 69 | @SuppressWarnings({"unused", "CheckReturnValue"}) 70 | public void testExceptionNoExecution() { 71 | new LazyFutureTask<>( 72 | () -> { 73 | throw new NullPointerException(); 74 | }); 75 | 76 | // no call to f.get() 77 | } 78 | 79 | @Test 80 | public void testCancel() { 81 | Future<@Nullable Void> f = new LazyFutureTask<>(Runnables.doNothing(), null); 82 | 83 | f.cancel(false); 84 | 85 | assertThrows(CancellationException.class, () -> f.get()); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/MoreStrings.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.errorprone.annotations.CheckReturnValue; 14 | import com.google.errorprone.annotations.Var; 15 | import java.util.function.Supplier; 16 | 17 | /** Utility class for String-related helpers, similar to {@link com.google.common.base.Strings}. */ 18 | public final class MoreStrings { 19 | private MoreStrings() {} 20 | 21 | /** 22 | * Check whether a string starts with a given prefix similar to {@link String#startsWith(String)}, 23 | * but ignoring the case like {@link String#equalsIgnoreCase(String)}. 24 | * 25 | * @param s The string to check whether it contains the prefix. 26 | * @param prefix The prefix. 27 | * @return Whether {@code s} starts with {@code prefix} in any case. 28 | */ 29 | public static boolean startsWithIgnoreCase(@Var String s, String prefix) { 30 | int prefixLength = prefix.length(); 31 | if (prefixLength > s.length()) { 32 | return false; 33 | } 34 | s = s.substring(0, prefixLength); 35 | return s.equalsIgnoreCase(prefix); 36 | } 37 | 38 | /** 39 | * Return an {@link Object} instance whose {@link Object#toString()} method lazily delegates to 40 | * the given supplier. This can be used for logging to make a single logging argument lazy, e.g. 41 | * {@code logger.log(Level.FINE, "Some message with %s and %s args", lazyString(() -> "lazy"), 42 | * "eager"); } 43 | * 44 | * @param stringSupplier A non-null supplier that returns a non-null string. 45 | * @return A object that should only be used for {@link Object#toString()}. 46 | */ 47 | @CheckReturnValue 48 | public static Object lazyString(Supplier stringSupplier) { 49 | checkNotNull(stringSupplier); 50 | return new Object() { 51 | @Override 52 | public String toString() { 53 | return checkNotNull(stringSupplier.get()); 54 | } 55 | }; 56 | } 57 | 58 | /** 59 | * Return an {@link Object} instance whose {@link Object#toString()} method delegates to {@link 60 | * WithLongString#toLongString()}. This can be used for logging as a lazy alternative to calling 61 | * {@link WithLongString#toLongString()} directly, e.g. 62 | * logger.log(Level.FINE, longStringOf(instance)); 63 | * 64 | * 65 | * @param obj A non-null instance of {@link WithLongString} 66 | * @return A object that should only be used for {@link Object#toString()}. 67 | */ 68 | @CheckReturnValue 69 | public static Object longStringOf(WithLongString obj) { 70 | checkNotNull(obj); 71 | return new Object() { 72 | @Override 73 | public String toString() { 74 | return checkNotNull(obj.toLongString()); 75 | } 76 | }; 77 | } 78 | 79 | /** 80 | * Interface for classes that have a second, longer, string representation (with more information) 81 | * in addition to {@link Object#toString()}. 82 | */ 83 | public interface WithLongString { 84 | 85 | /** 86 | * Return a string representation of this instance that has some more details than {@link 87 | * Object#toString()}. If you want to call this method lazily, use {@link 88 | * MoreStrings#longStringOf(WithLongString)}. 89 | * 90 | * @return a non-null string 91 | */ 92 | @CheckReturnValue 93 | String toLongString(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/MoreStringsTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static com.google.common.truth.Truth.assertWithMessage; 13 | 14 | import java.util.concurrent.atomic.AtomicBoolean; 15 | import org.junit.Test; 16 | import org.sosy_lab.common.MoreStrings.WithLongString; 17 | 18 | public class MoreStringsTest { 19 | 20 | @Test 21 | public void startsWithIgnoreCase_Empty() { 22 | assertThat(MoreStrings.startsWithIgnoreCase("aB", "")).isTrue(); 23 | } 24 | 25 | @Test 26 | public void startsWithIgnoreCase_Short() { 27 | assertThat(MoreStrings.startsWithIgnoreCase("aB", "aBc")).isFalse(); 28 | } 29 | 30 | @Test 31 | public void startsWithIgnoreCase_Matching() { 32 | assertThat(MoreStrings.startsWithIgnoreCase("AbC", "aB")).isTrue(); 33 | } 34 | 35 | @Test 36 | public void startsWithIgnoreCase_NonMatching() { 37 | assertThat(MoreStrings.startsWithIgnoreCase("AbC", "Ac")).isFalse(); 38 | } 39 | 40 | @Test 41 | public void test_longStringOf() { 42 | String testString = "TEST-STRING"; 43 | WithLongString instance = () -> testString; 44 | 45 | assertThat(MoreStrings.longStringOf(instance).toString()).isEqualTo(testString); 46 | } 47 | 48 | @Test 49 | @SuppressWarnings("unused") 50 | public void test_longStringOf_lazy() { 51 | AtomicBoolean wasCalled = new AtomicBoolean(false); 52 | WithLongString instance = 53 | () -> { 54 | wasCalled.set(true); 55 | return ""; 56 | }; 57 | 58 | Object unused = MoreStrings.longStringOf(instance); 59 | 60 | assertWithMessage("toLongString() method was called").that(wasCalled.get()).isFalse(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import com.google.common.base.Joiner; 12 | import com.google.common.reflect.Invokable; 13 | import com.google.common.testing.AbstractPackageSanityTests; 14 | import java.lang.reflect.Constructor; 15 | import java.lang.reflect.Executable; 16 | import java.lang.reflect.Method; 17 | import java.net.URL; 18 | import java.net.URLClassLoader; 19 | import java.nio.file.Path; 20 | import org.sosy_lab.common.ExtendedUrlClassLoader.ExtendedUrlClassLoaderConfiguration; 21 | 22 | @SuppressWarnings({"BanClassLoader", "resource"}) 23 | public class PackageSanityTest extends AbstractPackageSanityTests { 24 | 25 | { 26 | setDefault(String[].class, new String[] {"test"}); 27 | setDefault(Joiner.MapJoiner.class, Joiner.on(",").withKeyValueSeparator("=")); 28 | setDefault(ClassLoader.class, new URLClassLoader(new URL[0])); 29 | setDefault( 30 | ExtendedUrlClassLoaderConfiguration.class, 31 | Classes.makeExtendedURLClassLoader().setUrls().autoBuild()); 32 | setDefault(Path.class, Path.of("")); 33 | try { 34 | setDefault(Constructor.class, PackageSanityTest.class.getConstructor()); 35 | setDefault(Method.class, PackageSanityTest.class.getDeclaredMethod("defaultMethod")); 36 | setDefault(Executable.class, PackageSanityTest.class.getConstructor()); 37 | setDefault(Invokable.class, Invokable.from(PackageSanityTest.class.getConstructor())); 38 | } catch (NoSuchMethodException e) { 39 | throw new AssertionError(e); 40 | } 41 | } 42 | 43 | @SuppressWarnings("unused") 44 | private static void defaultMethod() {} 45 | } 46 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/ProcessExecutorTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import org.junit.Test; 12 | 13 | /** Disables sanity tests for ProcessExecutor, which would run external commands during test. */ 14 | public class ProcessExecutorTest { 15 | 16 | @Test 17 | public void testEquals() {} 18 | 19 | @Test 20 | public void testNulls() {} 21 | 22 | @Test 23 | public void testSerializable() {} 24 | } 25 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/UniqueIdGenerator.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common; 10 | 11 | import static com.google.common.base.Preconditions.checkState; 12 | 13 | import java.util.concurrent.atomic.AtomicInteger; 14 | 15 | /** 16 | * Utility class for generating unique. This class is fully thread-safe. 17 | * 18 | *

It gives out at most MAX_INT ids, afterwards it throws an exception. 19 | */ 20 | public final class UniqueIdGenerator { 21 | 22 | private final AtomicInteger nextId = new AtomicInteger(); 23 | 24 | public int getFreshId() { 25 | int id = nextId.getAndIncrement(); 26 | checkState(id >= 0, "Overflow for unique ID"); 27 | return id; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/annotations/FieldsAreNonnullByDefault.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.annotations; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Retention; 14 | import java.lang.annotation.RetentionPolicy; 15 | import javax.annotation.meta.TypeQualifierDefault; 16 | 17 | /** 18 | * An annotation similar to {@link javax.annotation.ParametersAreNonnullByDefault} that defines that 19 | * all fields inside the annotated element are never null, unless this is overridden with another 20 | * method. 21 | */ 22 | @SuppressWarnings("UnnecessarilyFullyQualified") 23 | @Documented 24 | @javax.annotation.Nonnull 25 | @org.checkerframework.checker.nullness.qual.NonNull 26 | @TypeQualifierDefault(ElementType.FIELD) 27 | @Retention(RetentionPolicy.RUNTIME) 28 | public @interface FieldsAreNonnullByDefault {} 29 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/annotations/ReturnValuesAreNonnullByDefault.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.annotations; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Retention; 14 | import java.lang.annotation.RetentionPolicy; 15 | import javax.annotation.meta.TypeQualifierDefault; 16 | 17 | /** 18 | * An annotation similar to {@link javax.annotation.ParametersAreNonnullByDefault} that defines that 19 | * all methods inside the annotated element do not return null, unless this is overridden with 20 | * another annotation. 21 | * 22 | *

It is defined here because the annotation supplied by FindBugs is deprecated: {@link 23 | * edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault}. 24 | */ 25 | @SuppressWarnings("UnnecessarilyFullyQualified") 26 | @Documented 27 | @javax.annotation.Nonnull 28 | @org.checkerframework.checker.nullness.qual.NonNull 29 | @TypeQualifierDefault(ElementType.METHOD) 30 | @Retention(RetentionPolicy.RUNTIME) 31 | public @interface ReturnValuesAreNonnullByDefault {} 32 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/annotations/SuppressForbidden.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.annotations; 10 | 11 | import java.lang.annotation.ElementType; 12 | import java.lang.annotation.Retention; 13 | import java.lang.annotation.RetentionPolicy; 14 | import java.lang.annotation.Target; 15 | 16 | /** 17 | * Annotation similar to {@link SuppressWarnings}, but intended to be used with 18 | * https://github.com/policeman-tools/forbidden-apis. 19 | */ 20 | @Retention(RetentionPolicy.CLASS) 21 | @Target({ 22 | ElementType.CONSTRUCTOR, 23 | ElementType.FIELD, 24 | ElementType.METHOD, 25 | ElementType.TYPE, 26 | }) 27 | public @interface SuppressForbidden { 28 | 29 | /** Description and explanation of what and why is suppressed. */ 30 | String value(); 31 | } 32 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/annotations/Unmaintained.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.annotations; 10 | 11 | import static java.lang.annotation.ElementType.PACKAGE; 12 | import static java.lang.annotation.ElementType.TYPE; 13 | 14 | import java.lang.annotation.Documented; 15 | import java.lang.annotation.Retention; 16 | import java.lang.annotation.RetentionPolicy; 17 | import java.lang.annotation.Target; 18 | 19 | /** 20 | * Annotation for component that are considered unmaintained, and might have inferior quality. 21 | * 22 | *

Effects of this annotation may include hiding warnings produced by static-analysis tools, and 23 | * a warning given to the user when this component is used. 24 | */ 25 | @Documented 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target(value = {PACKAGE, TYPE}) 28 | public @interface Unmaintained {} 29 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/annotations/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** This package contains several general-purpose annotations. */ 10 | @com.google.errorprone.annotations.CheckReturnValue 11 | @javax.annotation.ParametersAreNonnullByDefault 12 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 13 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 14 | package org.sosy_lab.common.annotations; 15 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/AbstractImmutableMap.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import com.google.common.base.Joiner; 12 | import com.google.errorprone.annotations.DoNotCall; 13 | import com.google.errorprone.annotations.Immutable; 14 | import java.util.Collection; 15 | import java.util.Map; 16 | import java.util.function.BiFunction; 17 | import java.util.function.Function; 18 | import org.checkerframework.checker.nullness.qual.Nullable; 19 | 20 | @Immutable(containerOf = {"K", "V"}) 21 | abstract class AbstractImmutableMap implements Map { 22 | 23 | @Deprecated 24 | @Override 25 | @DoNotCall 26 | public final void clear() { 27 | throw new UnsupportedOperationException(); 28 | } 29 | 30 | @Deprecated 31 | @Override 32 | @DoNotCall 33 | public final V put(K key, V value) { 34 | throw new UnsupportedOperationException(); 35 | } 36 | 37 | @Deprecated 38 | @Override 39 | @DoNotCall 40 | public final V putIfAbsent(K pKey, V pValue) { 41 | throw new UnsupportedOperationException(); 42 | } 43 | 44 | @Deprecated 45 | @Override 46 | @DoNotCall 47 | public final void putAll(Map pM) { 48 | throw new UnsupportedOperationException(); 49 | } 50 | 51 | @Deprecated 52 | @Override 53 | @DoNotCall 54 | public final V remove(Object pKey) { 55 | throw new UnsupportedOperationException(); 56 | } 57 | 58 | @Deprecated 59 | @Override 60 | @DoNotCall 61 | public final boolean remove(Object pKey, Object pValue) { 62 | throw new UnsupportedOperationException(); 63 | } 64 | 65 | @Deprecated 66 | @Override 67 | @DoNotCall 68 | public final V replace(K pKey, V pValue) { 69 | throw new UnsupportedOperationException(); 70 | } 71 | 72 | @Deprecated 73 | @Override 74 | @DoNotCall 75 | public final boolean replace(K pKey, V pOldValue, V pNewValue) { 76 | throw new UnsupportedOperationException(); 77 | } 78 | 79 | @Deprecated 80 | @Override 81 | @DoNotCall 82 | public final V compute(K pKey, BiFunction pRemappingFunction) { 83 | throw new UnsupportedOperationException(); 84 | } 85 | 86 | @Deprecated 87 | @Override 88 | @DoNotCall 89 | public final V computeIfAbsent(K pKey, Function pMappingFunction) { 90 | throw new UnsupportedOperationException(); 91 | } 92 | 93 | @Deprecated 94 | @Override 95 | @DoNotCall 96 | public final V computeIfPresent( 97 | K pKey, BiFunction pRemappingFunction) { 98 | throw new UnsupportedOperationException(); 99 | } 100 | 101 | @Deprecated 102 | @Override 103 | @DoNotCall 104 | public final V merge( 105 | K pKey, V pValue, BiFunction pRemappingFunction) { 106 | throw new UnsupportedOperationException(); 107 | } 108 | 109 | @Deprecated 110 | @Override 111 | @DoNotCall 112 | public final void replaceAll(BiFunction pFunction) { 113 | throw new UnsupportedOperationException(); 114 | } 115 | 116 | @Override 117 | public boolean containsValue(Object pValue) { 118 | return values().contains(pValue); 119 | } 120 | 121 | @Override 122 | public Collection values() { 123 | return new MapValues<>(this); 124 | } 125 | 126 | @Override 127 | public String toString() { 128 | if (isEmpty()) { 129 | return "{}"; 130 | } 131 | StringBuilder sb = new StringBuilder(); 132 | sb.append('{'); 133 | Joiner.on(", ").withKeyValueSeparator("=").useForNull("null").appendTo(sb, this); 134 | sb.append('}'); 135 | return sb.toString(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/Collections3Test.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static org.junit.Assert.assertThrows; 13 | 14 | import com.google.common.collect.ImmutableList; 15 | import java.io.IOException; 16 | import java.util.NavigableMap; 17 | import java.util.NavigableSet; 18 | import java.util.SortedMap; 19 | import java.util.SortedSet; 20 | import java.util.TreeMap; 21 | import java.util.TreeSet; 22 | import java.util.stream.Stream; 23 | import org.checkerframework.checker.nullness.qual.Nullable; 24 | import org.junit.Test; 25 | 26 | public class Collections3Test { 27 | 28 | private static final ImmutableList MIXED_OBJECTS_LIST = ImmutableList.of("1", 1, 1L, 1); 29 | 30 | @Test 31 | public void testAllElementsEqual_emptyArray() { 32 | assertThrows( 33 | IllegalArgumentException.class, () -> Collections3.allElementsEqual(ImmutableList.of())); 34 | } 35 | 36 | @Test 37 | public void testAllElementsEqual_emptyList() { 38 | assertThrows( 39 | IllegalArgumentException.class, () -> Collections3.allElementsEqual(new String[0])); 40 | } 41 | 42 | @Test 43 | public void testAllElementsEqual_emptyStream() { 44 | assertThrows(IllegalArgumentException.class, () -> Collections3.allElementsEqual(Stream.of())); 45 | } 46 | 47 | @Test 48 | public void testFilterByClass() { 49 | assertThat(Collections3.filterByClass(MIXED_OBJECTS_LIST, Integer.class)).containsExactly(1, 1); 50 | } 51 | 52 | @Test 53 | public void testFilterByClass_NoMatch() { 54 | assertThat(Collections3.filterByClass(MIXED_OBJECTS_LIST, IOException.class)).isEmpty(); 55 | } 56 | 57 | @Test 58 | public void testFilterByClass_AllMatch() { 59 | assertThat(Collections3.filterByClass(MIXED_OBJECTS_LIST, Object.class)) 60 | .containsExactlyElementsIn(MIXED_OBJECTS_LIST) 61 | .inOrder(); 62 | } 63 | 64 | @Test 65 | @SuppressWarnings("JdkObsolete") // we want to test that method 66 | public void testSubMapWithPrefix() { 67 | NavigableMap resultMap = new TreeMap<>(); 68 | resultMap.put("b", null); 69 | resultMap.put("b" + 0, null); 70 | resultMap.put("b1", null); 71 | resultMap.put("b2", null); 72 | resultMap.put("b" + Character.MAX_VALUE, null); 73 | 74 | NavigableMap testMap = new TreeMap<>(); 75 | testMap.putAll(resultMap); 76 | testMap.put("", null); 77 | testMap.put("a", null); 78 | testMap.put("a" + Character.MAX_VALUE, null); 79 | testMap.put("c", null); 80 | testMap.put("c" + 0, null); 81 | testMap.put("ca", null); 82 | 83 | assertThat(Collections3.subMapWithPrefix(testMap, "b")).isEqualTo(resultMap); 84 | assertThat(Collections3.subMapWithPrefix((SortedMap) testMap, "b")) 85 | .isEqualTo(resultMap); 86 | } 87 | 88 | @Test 89 | @SuppressWarnings("JdkObsolete") // we want to test that method 90 | public void testSubSetWithPrefix() { 91 | NavigableSet resultSet = new TreeSet<>(); 92 | resultSet.add("b"); 93 | resultSet.add("b" + 0); 94 | resultSet.add("b1"); 95 | resultSet.add("b2"); 96 | resultSet.add("b" + Character.MAX_VALUE); 97 | 98 | NavigableSet testSet = new TreeSet<>(); 99 | testSet.addAll(resultSet); 100 | testSet.add(""); 101 | testSet.add("a"); 102 | testSet.add("a" + Character.MAX_VALUE); 103 | testSet.add("c"); 104 | testSet.add("c" + 0); 105 | testSet.add("ca"); 106 | 107 | assertThat(Collections3.subSetWithPrefix(testSet, "b")).isEqualTo(resultSet); 108 | assertThat(Collections3.subSetWithPrefix((SortedSet) testSet, "b")) 109 | .isEqualTo(resultSet); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/CollectionsAllElementsEqualTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import com.google.common.collect.ImmutableList; 14 | import com.google.common.collect.Lists; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import org.junit.Test; 18 | import org.junit.runner.RunWith; 19 | import org.junit.runners.Parameterized; 20 | import org.junit.runners.Parameterized.Parameter; 21 | import org.junit.runners.Parameterized.Parameters; 22 | 23 | @RunWith(Parameterized.class) 24 | public class CollectionsAllElementsEqualTest { 25 | 26 | @Parameters(name = "{0}: {1}") 27 | public static ImmutableList parameters() { 28 | return ImmutableList.of( 29 | new Object[] {Lists.newArrayList(""), true}, 30 | new Object[] {Lists.newArrayList("", ""), true}, 31 | new Object[] {Lists.newArrayList("", "a"), false}, 32 | new Object[] {Lists.newArrayList("a", "a", "a"), true}, 33 | new Object[] {Lists.newArrayList("a", "a", ""), false}, 34 | new Object[] {Lists.newArrayList((String) null), true}, 35 | new Object[] {Lists.newArrayList(null, null), true}, 36 | new Object[] {Lists.newArrayList("", null), false}, 37 | new Object[] {Lists.newArrayList(null, ""), false}, 38 | new Object[] {Lists.newArrayList(null, null, null), true}); 39 | } 40 | 41 | @Parameter(0) 42 | public List inputs; 43 | 44 | @Parameter(1) 45 | public boolean expectedResult; 46 | 47 | @Test 48 | public void testArray() { 49 | assertThat(Collections3.allElementsEqual(inputs.toArray())).isEqualTo(expectedResult); 50 | } 51 | 52 | @Test 53 | public void testList() { 54 | assertThat(Collections3.allElementsEqual(new ArrayList<>(inputs))).isEqualTo(expectedResult); 55 | } 56 | 57 | @Test 58 | public void testStream() { 59 | assertThat(Collections3.allElementsEqual(inputs.stream())).isEqualTo(expectedResult); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/MapValues.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.common.collect.Iterators; 14 | import java.io.Serializable; 15 | import java.util.AbstractCollection; 16 | import java.util.Iterator; 17 | import java.util.Map; 18 | import org.checkerframework.checker.nullness.qual.Nullable; 19 | 20 | final class MapValues extends AbstractCollection 21 | implements Serializable { 22 | 23 | private static final long serialVersionUID = 9122264612662000623L; 24 | 25 | @SuppressWarnings("serial") // This class only needs to be serializable if delegate is. 26 | private final Map delegate; 27 | 28 | MapValues(Map pDelegate) { 29 | delegate = checkNotNull(pDelegate); 30 | } 31 | 32 | @Override 33 | public Iterator iterator() { 34 | return Iterators.transform(delegate.entrySet().iterator(), Map.Entry::getValue); 35 | } 36 | 37 | @Override 38 | public void clear() { 39 | delegate.clear(); 40 | } 41 | 42 | @Override 43 | public boolean isEmpty() { 44 | return delegate.isEmpty(); 45 | } 46 | 47 | @Override 48 | public int size() { 49 | return delegate.size(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/MoreCollectors.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import com.google.common.collect.ImmutableList; 12 | import com.google.common.collect.ImmutableSet; 13 | import com.google.errorprone.annotations.InlineMe; 14 | import java.util.stream.Collector; 15 | import java.util.stream.Collectors; 16 | 17 | /** Additional {@link Collector} implementation, similar to {@link Collectors}. */ 18 | public final class MoreCollectors { 19 | 20 | private MoreCollectors() {} 21 | 22 | /** 23 | * Return a {@link Collector} that produces {@link PersistentLinkedList}s. 24 | * 25 | * @deprecated use {@link PersistentLinkedList#toPersistentLinkedList()} 26 | */ 27 | @Deprecated 28 | @InlineMe( 29 | replacement = "PersistentLinkedList.toPersistentLinkedList()", 30 | imports = "org.sosy_lab.common.collect.PersistentLinkedList") 31 | public static Collector> toPersistentLinkedList() { 32 | return PersistentLinkedList.toPersistentLinkedList(); 33 | } 34 | 35 | /** 36 | * Return a {@link Collector} that produces {@link ImmutableList}s. 37 | * 38 | *

Prefer to use this over {@link Collectors#toList()}! The latter does neither guarantee 39 | * mutability nor immutability, so if you want immutability, use this method, and if you need 40 | * mutability, use {@code Collectors.toCollection(ArrayList::new)}. 41 | * 42 | * @deprecated use {@link ImmutableList#toImmutableList()} 43 | */ 44 | @Deprecated 45 | @InlineMe( 46 | replacement = "ImmutableList.toImmutableList()", 47 | imports = "com.google.common.collect.ImmutableList") 48 | public static Collector> toImmutableList() { 49 | return ImmutableList.toImmutableList(); 50 | } 51 | 52 | /** 53 | * Return a {@link Collector} that produces {@link ImmutableSet}s. Just like the usual methods for 54 | * ImmutableSets, this collector guarantees to keep the order. 55 | * 56 | *

Prefer to use this over {@link Collectors#toSet()}! The latter does neither guarantee 57 | * mutability nor immutability, so if you want immutability, use this method, and if you need 58 | * mutability, use {@code Collectors.toCollection(HashSet::new)}. 59 | * 60 | * @deprecated use {@link ImmutableList#toImmutableList()} 61 | */ 62 | @Deprecated 63 | @InlineMe( 64 | replacement = "ImmutableSet.toImmutableSet()", 65 | imports = "com.google.common.collect.ImmutableSet") 66 | public static Collector> toImmutableSet() { 67 | return ImmutableSet.toImmutableSet(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/NaiveOrderStatisticMapTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import com.google.common.collect.ImmutableMap; 14 | import com.google.common.collect.testing.NavigableMapTestSuiteBuilder; 15 | import com.google.common.collect.testing.TestSortedMapGenerator; 16 | import com.google.common.collect.testing.features.CollectionFeature; 17 | import com.google.common.collect.testing.features.CollectionSize; 18 | import com.google.common.collect.testing.features.MapFeature; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.NavigableMap; 23 | import java.util.TreeMap; 24 | import junit.framework.JUnit4TestAdapter; 25 | import junit.framework.TestSuite; 26 | import org.junit.Test; 27 | 28 | public class NaiveOrderStatisticMapTest extends OrderStatisticMapTestSuite { 29 | 30 | private static class OrderStatisticMapProxyFactory extends OrderStatisticMapFactory { 31 | 32 | @Override 33 | protected OrderStatisticMap create(Map.Entry[] pEntries) { 34 | return create(Arrays.asList(pEntries)); 35 | } 36 | 37 | @Override 38 | protected OrderStatisticMap create(List> pEntries) { 39 | NaiveOrderStatisticMap map = createMap(); 40 | for (Map.Entry e : pEntries) { 41 | map.put(e.getKey(), e.getValue()); 42 | } 43 | return map; 44 | } 45 | 46 | private static NaiveOrderStatisticMap createMap() { 47 | return NaiveOrderStatisticMap.createMap(); 48 | } 49 | } 50 | 51 | public NaiveOrderStatisticMapTest() { 52 | super(new OrderStatisticMapProxyFactory()); 53 | } 54 | 55 | public static junit.framework.Test suite() { 56 | TestSortedMapGenerator testSetGenerator = new OrderStatisticMapProxyFactory(); 57 | 58 | TestSuite suite = 59 | NavigableMapTestSuiteBuilder.using(testSetGenerator) 60 | .named("NaiveOrderStatisticMap") 61 | .withFeatures( 62 | CollectionSize.ANY, 63 | CollectionFeature.KNOWN_ORDER, 64 | CollectionFeature.SERIALIZABLE, 65 | CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 66 | MapFeature.GENERAL_PURPOSE, 67 | MapFeature.ALLOWS_NULL_VALUES) 68 | .createTestSuite(); 69 | 70 | suite.addTest(new JUnit4TestAdapter(NaiveOrderStatisticMapTest.class)); 71 | 72 | return suite; 73 | } 74 | 75 | @Test 76 | public void testNoReference() { 77 | NavigableMap testMap = 78 | new TreeMap<>(ImmutableMap.of("a", "Va", "b", "Vb", "bc", "Vbc", "d", "Vd")); 79 | OrderStatisticMap map = NaiveOrderStatisticMap.createMapWithSameOrder(testMap); 80 | 81 | testMap.remove("a"); 82 | assertThat(testMap).doesNotContainKey("a"); 83 | assertThat(map).containsKey("a"); 84 | map.remove("bc"); 85 | assertThat(testMap).containsKey("bc"); 86 | assertThat(map).doesNotContainKey("bc"); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/NaiveOrderStatisticSetTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import com.google.common.collect.ImmutableList; 14 | import com.google.common.collect.testing.NavigableSetTestSuiteBuilder; 15 | import com.google.common.collect.testing.TestSortedSetGenerator; 16 | import com.google.common.collect.testing.features.CollectionFeature; 17 | import com.google.common.collect.testing.features.CollectionSize; 18 | import com.google.common.collect.testing.features.SetFeature; 19 | import java.util.Arrays; 20 | import java.util.NavigableSet; 21 | import java.util.TreeSet; 22 | import junit.framework.JUnit4TestAdapter; 23 | import junit.framework.TestSuite; 24 | import org.junit.Test; 25 | 26 | public final class NaiveOrderStatisticSetTest extends OrderStatisticSetTestSuite { 27 | 28 | private static class OrderStatisticsSetProxyFactory extends OrderStatisticSetFactory { 29 | 30 | @Override 31 | protected OrderStatisticSet create(String[] pStrings) { 32 | NaiveOrderStatisticSet list = createSet(); 33 | boolean changed = list.addAll(Arrays.asList(pStrings)); 34 | assert list.isEmpty() || changed; 35 | 36 | return list; 37 | } 38 | 39 | private static NaiveOrderStatisticSet createSet() { 40 | return NaiveOrderStatisticSet.createSet(); 41 | } 42 | } 43 | 44 | public NaiveOrderStatisticSetTest() { 45 | super(new OrderStatisticsSetProxyFactory()); 46 | } 47 | 48 | public static junit.framework.Test suite() { 49 | TestSortedSetGenerator testSetGenerator = new OrderStatisticsSetProxyFactory(); 50 | 51 | TestSuite suite = 52 | NavigableSetTestSuiteBuilder.using(testSetGenerator) 53 | .named("NaiveOrderStatisticSet") 54 | .withFeatures( 55 | CollectionSize.ANY, 56 | SetFeature.GENERAL_PURPOSE, 57 | CollectionFeature.KNOWN_ORDER, 58 | CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS) 59 | .createTestSuite(); 60 | 61 | suite.addTest(new JUnit4TestAdapter(NaiveOrderStatisticSetTest.class)); 62 | 63 | return suite; 64 | } 65 | 66 | @Test 67 | public void testNoReference() { 68 | NavigableSet testCollection = new TreeSet<>(ImmutableList.of("a", "b", "bc", "d")); 69 | OrderStatisticSet set = NaiveOrderStatisticSet.createSetWithSameOrder(testCollection); 70 | 71 | testCollection.remove("a"); 72 | assertThat(testCollection).doesNotContain("a"); 73 | assertThat(set).contains("a"); 74 | set.remove("bc"); 75 | assertThat(testCollection).contains("bc"); 76 | assertThat(set).doesNotContain("bc"); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import com.google.common.testing.AbstractPackageSanityTests; 12 | import org.sosy_lab.common.Classes; 13 | 14 | public class PackageSanityTest extends AbstractPackageSanityTests { 15 | 16 | { 17 | setDistinctValues( 18 | PersistentLinkedList.class, PersistentLinkedList.of(), PersistentLinkedList.of("test")); 19 | @SuppressWarnings("unchecked") 20 | OurSortedMap singletonMap = 21 | (OurSortedMap) 22 | PathCopyingPersistentTreeMap.of().putAndCopy("test", "test"); 23 | setDistinctValues( 24 | OurSortedMap.class, OurSortedMap.EmptyImmutableOurSortedMap.of(), singletonMap); 25 | ignoreClasses(Classes.IS_GENERATED); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/PersistentLinkedListTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import com.google.common.collect.testing.ListTestSuiteBuilder; 14 | import com.google.common.collect.testing.TestStringListGenerator; 15 | import com.google.common.collect.testing.features.CollectionFeature; 16 | import com.google.common.collect.testing.features.CollectionSize; 17 | import com.google.common.collect.testing.testers.ListLastIndexOfTester; 18 | import com.google.common.collect.testing.testers.ListListIteratorTester; 19 | import com.google.common.collect.testing.testers.ListSubListTester; 20 | import java.util.Arrays; 21 | import java.util.List; 22 | import junit.framework.JUnit4TestAdapter; 23 | import junit.framework.TestSuite; 24 | import org.junit.Test; 25 | 26 | public class PersistentLinkedListTest { 27 | 28 | private static final TestStringListGenerator listGenerator = 29 | new TestStringListGenerator() { 30 | 31 | @Override 32 | protected List create(String[] pElements) { 33 | return PersistentLinkedList.copyOf(pElements); 34 | } 35 | }; 36 | 37 | public static junit.framework.Test suite() throws NoSuchMethodException { 38 | TestSuite suite = new TestSuite(); 39 | suite.addTest(new JUnit4TestAdapter(PersistentLinkedListTest.class)); 40 | 41 | suite.addTest( 42 | ListTestSuiteBuilder.using(listGenerator) 43 | .named("PersistentLinkedList") 44 | .withFeatures(CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) 45 | .suppressing( 46 | // These tests all rely on a fully implemented ListIterator. 47 | ListLastIndexOfTester.class.getMethod("testFind_wrongType"), 48 | ListLastIndexOfTester.class.getMethod("testFind_no"), 49 | ListLastIndexOfTester.class.getMethod("testFind_yes"), 50 | ListLastIndexOfTester.class.getMethod("testFind_nullNotContainedAndUnsupported"), 51 | ListLastIndexOfTester.class.getMethod("testLastIndexOf_duplicate"), 52 | ListListIteratorTester.class.getMethod("testListIterator_tooLow"), 53 | ListListIteratorTester.class.getMethod("testListIterator_unmodifiable"), 54 | ListSubListTester.class.getMethod("testSubList_lastIndexOf")) 55 | .createTestSuite()); 56 | 57 | return suite; 58 | } 59 | 60 | @Test 61 | public void testOf1() { 62 | assertThat(PersistentLinkedList.of("a")).containsExactly("a").inOrder(); 63 | } 64 | 65 | @Test 66 | public void testOf2() { 67 | assertThat(PersistentLinkedList.of("a", "b")).containsExactly("a", "b").inOrder(); 68 | } 69 | 70 | @Test 71 | public void testOf3() { 72 | assertThat(PersistentLinkedList.of("a", "b", "c")).containsExactly("a", "b", "c").inOrder(); 73 | } 74 | 75 | @Test 76 | public void testOfVarArgs() { 77 | assertThat(PersistentLinkedList.of("a", "b", "c", "d")) 78 | .containsExactly("a", "b", "c", "d") 79 | .inOrder(); 80 | } 81 | 82 | @Test 83 | public void testWithAll() { 84 | assertThat(PersistentLinkedList.of("d").withAll(Arrays.asList("a", "b", "c"))) 85 | .containsExactly("a", "b", "c", "d") 86 | .inOrder(); 87 | } 88 | 89 | @Test 90 | public void testReversed() { 91 | assertThat(PersistentLinkedList.of("a", "b", "c", "d").reversed()) 92 | .containsExactly("d", "c", "b", "a") 93 | .inOrder(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/PersistentSortedMap.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import com.google.errorprone.annotations.CheckReturnValue; 12 | import com.google.errorprone.annotations.DoNotCall; 13 | import com.google.errorprone.annotations.Immutable; 14 | import java.util.NavigableMap; 15 | import java.util.NavigableSet; 16 | import org.checkerframework.checker.nullness.qual.Nullable; 17 | 18 | /** 19 | * Sub-interface of {@link PersistentMap} analog to {@link NavigableMap}. 20 | * 21 | * @param The type of keys. 22 | * @param The type of values. 23 | */ 24 | @Immutable(containerOf = {"K", "V"}) 25 | public interface PersistentSortedMap 26 | extends PersistentSortedMapBridge, NavigableMap { 27 | 28 | @Override 29 | @CheckReturnValue 30 | PersistentSortedMap putAndCopy(K key, V value); 31 | 32 | @Override 33 | @CheckReturnValue 34 | PersistentSortedMap removeAndCopy(Object pKey); 35 | 36 | @Override 37 | @CheckReturnValue 38 | PersistentSortedMap empty(); 39 | 40 | @Override 41 | NavigableSet> entrySet(); 42 | 43 | @Override 44 | NavigableSet keySet(); 45 | 46 | @Override 47 | NavigableMap descendingMap(); 48 | 49 | @Override 50 | NavigableMap subMap(K pFromKey, K pToKey); 51 | 52 | @Override 53 | NavigableMap subMap(K pFromKey, boolean pFromInclusive, K pToKey, boolean pToInclusive); 54 | 55 | @Override 56 | NavigableMap headMap(K pToKey); 57 | 58 | @Override 59 | NavigableMap headMap(K pToKey, boolean pInclusive); 60 | 61 | @Override 62 | NavigableMap tailMap(K pFromKey); 63 | 64 | @Override 65 | NavigableMap tailMap(K pFromKey, boolean pInclusive); 66 | 67 | /** 68 | * @throws UnsupportedOperationException Always. 69 | * @deprecated Unsupported operation. 70 | */ 71 | @Deprecated 72 | @Override 73 | @DoNotCall 74 | Entry pollFirstEntry(); 75 | 76 | /** 77 | * @throws UnsupportedOperationException Always. 78 | * @deprecated Unsupported operation. 79 | */ 80 | @Deprecated 81 | @Override 82 | @DoNotCall 83 | Entry pollLastEntry(); 84 | } 85 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/PersistentSortedMapBridge.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import com.google.errorprone.annotations.Immutable; 12 | import java.util.Map; 13 | import java.util.SortedMap; 14 | import java.util.SortedSet; 15 | import org.checkerframework.checker.nullness.qual.Nullable; 16 | 17 | /** 18 | * Interface that forces generation of bridge methods that return {@link SortedSet} for binary 19 | * backwards compatibility. 20 | */ 21 | @SuppressWarnings("JdkObsolete") 22 | @Immutable(containerOf = {"K", "V"}) 23 | interface PersistentSortedMapBridge 24 | extends PersistentMap, SortedMap { 25 | @Override 26 | SortedSet keySet(); 27 | 28 | @Override 29 | SortedSet> entrySet(); 30 | } 31 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/SortedMapKeySetTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.collect; 10 | 11 | import com.google.common.collect.testing.NavigableSetTestSuiteBuilder; 12 | import com.google.common.collect.testing.TestSortedSetGenerator; 13 | import com.google.common.collect.testing.TestStringSortedSetGenerator; 14 | import com.google.common.collect.testing.features.CollectionFeature; 15 | import com.google.common.collect.testing.features.CollectionSize; 16 | import com.google.errorprone.annotations.Var; 17 | import java.util.SortedSet; 18 | import junit.framework.Test; 19 | import junit.framework.TestSuite; 20 | 21 | public class SortedMapKeySetTest { 22 | 23 | private SortedMapKeySetTest() {} 24 | 25 | private static class OrderStatisticsSetProxyFactory extends TestStringSortedSetGenerator { 26 | 27 | @SuppressWarnings("unchecked") 28 | @Override 29 | protected SortedSet create(String[] pStrings) { 30 | @Var PersistentSortedMap map = PathCopyingPersistentTreeMap.of(); 31 | for (String s : pStrings) { 32 | map = map.putAndCopy(s, Boolean.TRUE); 33 | } 34 | return new SortedMapKeySet<>((OurSortedMap) map); 35 | } 36 | } 37 | 38 | public static Test suite() { 39 | TestSortedSetGenerator testSetGenerator = new OrderStatisticsSetProxyFactory(); 40 | 41 | TestSuite suite = 42 | NavigableSetTestSuiteBuilder.using(testSetGenerator) 43 | .named("SortedMapKeySet") 44 | .withFeatures( 45 | CollectionFeature.KNOWN_ORDER, 46 | CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, 47 | CollectionSize.ANY) 48 | .createTestSuite(); 49 | 50 | return suite; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/collect/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** 10 | * This package contains additional interfaces and implementations for collections, as well as 11 | * further collection utilities. 12 | */ 13 | @com.google.errorprone.annotations.CheckReturnValue 14 | @javax.annotation.ParametersAreNonnullByDefault 15 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 16 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 17 | package org.sosy_lab.common.collect; 18 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/AnnotatedValue.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import com.google.auto.value.AutoValue; 12 | import com.google.errorprone.annotations.Immutable; 13 | import java.util.Optional; 14 | 15 | /** Immutable container that stores a value and an optional string. */ 16 | @Immutable(containerOf = "T") 17 | @AutoValue 18 | public abstract class AnnotatedValue { 19 | 20 | AnnotatedValue() {} 21 | 22 | public static AnnotatedValue create(T value) { 23 | return new AutoValue_AnnotatedValue<>(value, Optional.empty()); 24 | } 25 | 26 | public static AnnotatedValue create(T value, String annotation) { 27 | return new AutoValue_AnnotatedValue<>(value, Optional.of(annotation)); 28 | } 29 | 30 | public static AnnotatedValue create(T value, Optional annotation) { 31 | return new AutoValue_AnnotatedValue<>(value, annotation); 32 | } 33 | 34 | public abstract T value(); 35 | 36 | public abstract Optional annotation(); 37 | } 38 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/ClassOption.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Retention; 14 | import java.lang.annotation.RetentionPolicy; 15 | import java.lang.annotation.Target; 16 | 17 | /** 18 | * This is an optional annotation for all configuration options (i.e., elements that are annotated 19 | * with {@link Option}) whose type is {@link Class}. 20 | * 21 | *

It serves to specify additional information which is required for class options. 22 | */ 23 | @OptionDetailAnnotation(applicableTo = {}) 24 | @Documented 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Target({ElementType.FIELD, ElementType.METHOD}) 27 | public @interface ClassOption { 28 | 29 | /** 30 | * This field provides optional package prefixes that can be added to the specified class name. 31 | * First the specified class name is tried without any prefix, and then with each prefix in the 32 | * given order. The result is the first class that is found. 33 | */ 34 | String[] packagePrefix() default ""; 35 | } 36 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/ConfigurationBuilderTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static org.mockito.ArgumentMatchers.any; 13 | import static org.mockito.Mockito.mock; 14 | import static org.mockito.Mockito.verify; 15 | import static org.mockito.Mockito.verifyNoInteractions; 16 | import static org.mockito.Mockito.verifyNoMoreInteractions; 17 | 18 | import com.google.common.collect.ImmutableMap; 19 | import org.junit.Test; 20 | import org.mockito.Mockito; 21 | import org.sosy_lab.common.configuration.converters.TypeConverter; 22 | 23 | public class ConfigurationBuilderTest { 24 | 25 | @Test 26 | public void copyFrom_getInstanceForNewConfiguration() throws InvalidConfigurationException { 27 | TypeConverter conv = mock(TypeConverter.class); 28 | Mockito.when(conv.getInstanceForNewConfiguration(any())).thenReturn(conv); 29 | 30 | Configuration config = new ConfigurationBuilder().addConverter(String.class, conv).build(); 31 | 32 | Configuration config2 = new ConfigurationBuilder().copyFrom(config).build(); 33 | 34 | verify(conv).getInstanceForNewConfiguration(any()); 35 | verifyNoMoreInteractions(conv); 36 | assertThat(config2.converters).containsEntry(String.class, conv); 37 | assertThat(config2.converters.entrySet()) 38 | .containsAtLeastElementsIn(Configuration.getDefaultConverters().entrySet()); 39 | } 40 | 41 | @Test 42 | public void copyFrom_keepPrefix() throws InvalidConfigurationException { 43 | Configuration base = Configuration.builder().setPrefix("base").build(); 44 | Configuration child = Configuration.copyWithNewPrefix(base, "child"); 45 | Configuration grandchild = 46 | Configuration.builder().copyFrom(child).setOption("dummy", "test").build(); 47 | Configuration grandgrandchild = 48 | Configuration.builder().copyFrom(grandchild).setOption("dummy2", "test").build(); 49 | 50 | assertThat(grandchild.prefix).isEqualTo("child."); 51 | assertThat(grandgrandchild.prefix).isEqualTo("child."); 52 | } 53 | 54 | @Test 55 | public void addConverter_NoGetInstanceForNewConfiguration() throws InvalidConfigurationException { 56 | TypeConverter conv1 = mock(TypeConverter.class); 57 | TypeConverter conv2 = mock(TypeConverter.class); 58 | 59 | Configuration config = new ConfigurationBuilder().addConverter(String.class, conv1).build(); 60 | 61 | // Because conv2 explicitly overrides conv1, getInstanceForNewConfiguration should not be called 62 | Configuration config2 = 63 | new ConfigurationBuilder().copyFrom(config).addConverter(String.class, conv2).build(); 64 | 65 | verifyNoInteractions(conv1, conv2); 66 | assertThat(config2.converters).containsEntry(String.class, conv2); 67 | assertThat(config2.converters.entrySet()) 68 | .containsAtLeastElementsIn(Configuration.getDefaultConverters().entrySet()); 69 | } 70 | 71 | @Test 72 | public void defaultConverters_getInstanceForNewConfiguration() 73 | throws InvalidConfigurationException { 74 | TypeConverter conv = mock(TypeConverter.class); 75 | Mockito.when(conv.getInstanceForNewConfiguration(any())).thenReturn(conv); 76 | 77 | Configuration config; 78 | ImmutableMap, TypeConverter> backup = 79 | ImmutableMap.copyOf(Configuration.getDefaultConverters()); 80 | try { 81 | Configuration.getDefaultConverters().put(String.class, conv); 82 | 83 | config = new ConfigurationBuilder().build(); 84 | } finally { 85 | Configuration.getDefaultConverters().clear(); 86 | Configuration.getDefaultConverters().putAll(backup); 87 | } 88 | 89 | verify(conv).getInstanceForNewConfiguration(any()); 90 | verifyNoMoreInteractions(conv); 91 | assertThat(config.converters).containsEntry(String.class, conv); 92 | assertThat(config.converters.entrySet()) 93 | .containsAtLeastElementsIn(Configuration.getDefaultConverters().entrySet()); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/FileOption.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import java.io.File; 12 | import java.lang.annotation.Documented; 13 | import java.lang.annotation.ElementType; 14 | import java.lang.annotation.Retention; 15 | import java.lang.annotation.RetentionPolicy; 16 | import java.lang.annotation.Target; 17 | import java.nio.file.Path; 18 | import org.sosy_lab.common.configuration.converters.FileTypeConverter; 19 | import org.sosy_lab.common.io.PathCounterTemplate; 20 | import org.sosy_lab.common.io.PathTemplate; 21 | 22 | /** 23 | * This is an annotation providing more features for options of types {@link File} and {@link Path}. 24 | * In order to use it, you need to register an instance of {@link FileTypeConverter} as a converter 25 | * for {@link FileOption}. 26 | */ 27 | @OptionDetailAnnotation( 28 | applicableTo = {File.class, Path.class, PathTemplate.class, PathCounterTemplate.class}) 29 | @Documented 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target({ElementType.FIELD, ElementType.METHOD}) 32 | public @interface FileOption { 33 | 34 | /** More details for file options. */ 35 | Type value(); 36 | 37 | enum Type { 38 | /** 39 | * The file specified with this option is a required input file (a non-existing file will be 40 | * considered an invalid configuration). 41 | */ 42 | REQUIRED_INPUT_FILE, 43 | 44 | /** 45 | * The file specified with this option is a file (i.e., no directory), but it needs not exist. 46 | */ 47 | OPTIONAL_INPUT_FILE, 48 | 49 | /** 50 | * The file specified with this option will be created by the tool. I doesn't matter whether 51 | * this file already exists, but it may not be a directory. 52 | */ 53 | OUTPUT_FILE, 54 | 55 | /** 56 | * The directory specified with this option will be created by the tool. I doesn't matter 57 | * whether this directory already exists, but it may not be a file. 58 | */ 59 | OUTPUT_DIRECTORY, 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/IntegerOption.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Retention; 14 | import java.lang.annotation.RetentionPolicy; 15 | import java.lang.annotation.Target; 16 | 17 | /** 18 | * This is an optional annotation for all configuration options (i.e., elements that are annotated 19 | * with {@link Option}) whose type is an integer number (i.e., int, long, Integer and Long): 20 | * 21 | *

It serves to specify minimal and/or maximal values. 22 | */ 23 | @OptionDetailAnnotation(applicableTo = {Integer.class, Long.class}) 24 | @Documented 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Target({ElementType.FIELD, ElementType.METHOD}) 27 | public @interface IntegerOption { 28 | 29 | /** An optional minimum value for this option. */ 30 | long min() default Long.MIN_VALUE; 31 | 32 | /** An optional maximum value for this option. */ 33 | long max() default Long.MAX_VALUE; 34 | } 35 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/InvalidConfigurationException.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | /** Exception class to signal that something is wrong in the user-specified configuration. */ 14 | public class InvalidConfigurationException extends Exception { 15 | 16 | private static final long serialVersionUID = -2482555561027049741L; 17 | 18 | public InvalidConfigurationException(String msg) { 19 | super(checkNotNull(msg)); 20 | } 21 | 22 | public InvalidConfigurationException(String msg, Throwable source) { 23 | super(checkNotNull(msg), checkNotNull(source)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/OptionDetailAnnotation.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Retention; 14 | import java.lang.annotation.RetentionPolicy; 15 | import java.lang.annotation.Target; 16 | 17 | /** 18 | * This is a meta annotation that marks other annotation which may be used in conjunction with 19 | * {@link Option} to provide more information for a specific option type. 20 | */ 21 | @Documented 22 | @Target(ElementType.ANNOTATION_TYPE) 23 | @Retention(RetentionPolicy.RUNTIME) 24 | public @interface OptionDetailAnnotation { 25 | 26 | /** 27 | * The annotation is applicable to configuration of these types. If a wrapper class of a primitive 28 | * type is added here, the annotation automatically is also applicable to the corresponding 29 | * primitive type. Otherwise types have to match exactly, i.e., no sub-types and super types. 30 | */ 31 | Class[] applicableTo(); 32 | } 33 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/Options.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import java.lang.annotation.ElementType; 12 | import java.lang.annotation.Retention; 13 | import java.lang.annotation.RetentionPolicy; 14 | import java.lang.annotation.Target; 15 | 16 | /** Annotation for a class which has fields or methods with an {@link Option} annotation. */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | public @interface Options { 20 | 21 | /** 22 | * An optional prefix for all configuration options of the class annotated with this type. Prefix 23 | * and name of the option will be separated by a dot. 24 | */ 25 | String prefix() default ""; 26 | 27 | /** 28 | * When the prefix needs to be renamed, often it is desirable to maintain the backwards 29 | * compatibility with the previous config. In that case, the previous prefix can be moved to the 30 | * field {@code deprecatedPrefix}. Both normal and deprecated prefixes would work, with latter 31 | * printing the deprecation warning. 32 | * 33 | *

However, note that if a {@link Option#deprecatedName()} is defined for an option, then the 34 | * deprecated prefix works only in combination with that deprecated name. 35 | * 36 | *

Summary what works if a deprecated prefix is set: 37 | * 38 | *

    39 | *
  • If {@link Option#deprecatedName()} is set, then "current prefix + current option name" 40 | * and "deprecated prefix + deprecated option name" work. 41 | *
  • If d{@link Option#deprecatedName()} is not set, then "current prefix + current option 42 | * name" and "deprecated prefix + current option name" work. 43 | *
44 | */ 45 | String deprecatedPrefix() default Configuration.NO_DEPRECATED_PREFIX; 46 | 47 | /** An optional text, that describes the current options. */ 48 | String description() default ""; 49 | } 50 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import com.google.common.io.CharSource; 12 | import com.google.common.testing.AbstractPackageSanityTests; 13 | import java.nio.file.Path; 14 | import java.util.Optional; 15 | import org.sosy_lab.common.Classes; 16 | 17 | public class PackageSanityTest extends AbstractPackageSanityTests { 18 | 19 | { 20 | ignoreClasses(Classes.IS_GENERATED); 21 | 22 | setDefault(String[].class, new String[] {"test"}); 23 | setDefault(Path.class, Path.of("test")); 24 | setDefault(Configuration.class, Configuration.defaultConfiguration()); 25 | setDefault(CharSource.class, CharSource.wrap("key=value")); 26 | setDefault(Optional.class, Optional.empty()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/TimeSpanOption.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration; 10 | 11 | import java.lang.annotation.Documented; 12 | import java.lang.annotation.ElementType; 13 | import java.lang.annotation.Retention; 14 | import java.lang.annotation.RetentionPolicy; 15 | import java.lang.annotation.Target; 16 | import java.util.concurrent.TimeUnit; 17 | import org.sosy_lab.common.time.TimeSpan; 18 | 19 | /** 20 | * This is an annotation for all integer options that specify some sort of time duration (e.g., a 21 | * timeout). Values for options with this annotation can be given with units. Examples: 10s 5min 3h 22 | * Supported units are "ns", "ms", "s", "min", and "h". Microseconds are not supported. 23 | */ 24 | @OptionDetailAnnotation(applicableTo = {Integer.class, Long.class, TimeSpan.class}) 25 | @Documented 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target({ElementType.FIELD, ElementType.METHOD}) 28 | public @interface TimeSpanOption { 29 | 30 | /** The unit which should be assumed when the user does not explicitly specify a unit. */ 31 | TimeUnit defaultUserUnit() default TimeUnit.SECONDS; 32 | 33 | /** 34 | * The unit which will be used to write the value from the user into the annotated field if the 35 | * field is of type int or long. This is also the unit of the default value of this option (if one 36 | * is given), and of the minimum and maximum value! 37 | */ 38 | TimeUnit codeUnit(); 39 | 40 | /** An optional minimum value for this option. The unit of the minimum is {@link #codeUnit()}. */ 41 | long min() default Long.MIN_VALUE; 42 | 43 | /** An optional maximum value for this option. The unit of the maximum is {@link #codeUnit()}. */ 44 | long max() default Long.MAX_VALUE; 45 | } 46 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/converters/ClassTypeConverter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration.converters; 10 | 11 | import com.google.common.collect.FluentIterable; 12 | import com.google.common.reflect.TypeToken; 13 | import com.google.errorprone.annotations.Var; 14 | import java.lang.annotation.Annotation; 15 | import java.nio.file.Path; 16 | import java.util.Collections; 17 | import org.sosy_lab.common.Classes; 18 | import org.sosy_lab.common.Classes.UnsuitedClassException; 19 | import org.sosy_lab.common.configuration.ClassOption; 20 | import org.sosy_lab.common.configuration.InvalidConfigurationException; 21 | import org.sosy_lab.common.log.LogManager; 22 | 23 | public class ClassTypeConverter implements TypeConverter { 24 | 25 | @Override 26 | public Object convert( 27 | String optionName, 28 | String value, 29 | TypeToken type, 30 | Annotation secondaryOption, 31 | Path pSource, 32 | LogManager logger) 33 | throws InvalidConfigurationException { 34 | 35 | // null means "no prefix" 36 | @Var Iterable packagePrefixes = Collections.singleton(null); 37 | 38 | // get optional package prefix 39 | if (secondaryOption != null) { 40 | if (!(secondaryOption instanceof ClassOption)) { 41 | throw new UnsupportedOperationException( 42 | "Options of type Class may not be annotated with " + secondaryOption); 43 | } 44 | packagePrefixes = 45 | FluentIterable.from(packagePrefixes) 46 | .append(((ClassOption) secondaryOption).packagePrefix()); 47 | } 48 | 49 | // get class object 50 | @Var Class cls = null; 51 | for (String prefix : packagePrefixes) { 52 | try { 53 | cls = Classes.forName(value, prefix); 54 | } catch (ClassNotFoundException ignored) { 55 | // Ignore, we try next prefix and throw below if none is found. 56 | } 57 | } 58 | if (cls == null) { 59 | throw new InvalidConfigurationException( 60 | "Class " + value + " specified in option " + optionName + " not found"); 61 | } 62 | 63 | Object result; 64 | if (type.getRawType().equals(Class.class)) { 65 | // get value of type parameter 66 | TypeToken targetType = Classes.getSingleTypeArgument(type); 67 | 68 | // check type 69 | if (!targetType.isSupertypeOf(cls)) { 70 | throw new InvalidConfigurationException( 71 | String.format( 72 | "Class %s specified in option %s is not an instance of %s", 73 | value, optionName, targetType)); 74 | } 75 | 76 | result = cls; 77 | Classes.produceClassLoadingWarning(logger, cls, targetType.getRawType()); 78 | 79 | } else { 80 | // This should be a factory interface for which we create a proxy implementation. 81 | try { 82 | result = Classes.createFactory(type, cls); 83 | } catch (UnsuitedClassException e) { 84 | throw new InvalidConfigurationException( 85 | String.format( 86 | "Class %s specified in option %s is invalid (%s)", 87 | value, optionName, e.getMessage())); 88 | } 89 | Classes.produceClassLoadingWarning(logger, cls, type.getRawType()); 90 | } 91 | 92 | return result; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/converters/IntegerTypeConverter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.configuration.converters; 10 | 11 | import com.google.common.collect.Range; 12 | import com.google.common.reflect.TypeToken; 13 | import java.lang.annotation.Annotation; 14 | import java.nio.file.Path; 15 | import org.sosy_lab.common.configuration.IntegerOption; 16 | import org.sosy_lab.common.configuration.InvalidConfigurationException; 17 | import org.sosy_lab.common.log.LogManager; 18 | 19 | /** 20 | * Type converter for options of types Integer/Long annotated with {@link IntegerOption} (not for 21 | * integer options without this annotation). 22 | */ 23 | public class IntegerTypeConverter implements TypeConverter { 24 | 25 | @Override 26 | public Object convert( 27 | String optionName, 28 | String valueStr, 29 | TypeToken pType, 30 | Annotation pOption, 31 | Path pSource, 32 | LogManager logger) 33 | throws InvalidConfigurationException { 34 | Class type = pType.getRawType(); 35 | 36 | if (!(pOption instanceof IntegerOption)) { 37 | throw new UnsupportedOperationException( 38 | "IntegerTypeConverter needs options annotated with @IntegerOption"); 39 | } 40 | IntegerOption option = (IntegerOption) pOption; 41 | 42 | assert type.equals(Integer.class) || type.equals(Long.class); 43 | 44 | Object value = BaseTypeConverter.valueOf(type, optionName, valueStr); 45 | 46 | long n = ((Number) value).longValue(); 47 | if (option.min() > n || n > option.max()) { 48 | Range bound = Range.closed(option.min(), option.max()); 49 | Range typeBound = 50 | type.equals(Integer.class) 51 | ? Range.closed((long) Integer.MIN_VALUE, (long) Integer.MAX_VALUE) 52 | : Range.all(); 53 | 54 | throw new InvalidConfigurationException( 55 | String.format( 56 | "Invalid value in configuration file: \"%s = %s\" (not in range %s).", 57 | optionName, value, bound.intersection(typeBound))); 58 | } 59 | 60 | return value; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/converters/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** 10 | * This package provides the possibility to convert String values into appropriate objects of 11 | * certain types. This is used by the {@link org.sosy_lab.common.configuration.Configuration} class 12 | * to convert configuration options into objects before injecting them. The primary interface is 13 | * {@link org.sosy_lab.common.configuration.converters.TypeConverter}, and some default 14 | * implementations for commonly-used classes are also provided. 15 | */ 16 | @com.google.errorprone.annotations.CheckReturnValue 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 19 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 20 | package org.sosy_lab.common.configuration.converters; 21 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/configuration/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** 10 | * Java-Config is a library for injecting configuration options in a decentralized way. 11 | * 12 | *

{@link org.sosy_lab.common.configuration.Configuration} objects can be generated either from 13 | * {@code .properties} configuration files, or from command line options. The usability is geared 14 | * towards configuration files, but command line generation is also supported. 15 | * 16 | *

The library is conceptually similar to GFlags 17 | * and allows arbitrary option injection throughout used classes. 18 | * 19 | *

Annotating classes with options 20 | * 21 | *

The example below demonstrates defining options for a class: 22 | * 23 | *

24 |  * 
25 |  * {@literal @}Options(prefix="grep")
26 |  * public class Grep {
27 |  *   {@literal @}Option(description="Ignore case of the query", secure=true)
28 |  *   private boolean ignoreCase = false;
29 |  *
30 |  *   {@literal @}Option(description="File to search", secure=true)
31 |  *   {@literal @}FileOption(Type.REQUIRED_INPUT_FILE)
32 |  *   private PathCounterTemplate haystack = null;
33 |  *
34 |  *   public Grep(Configuration c) {
35 |  *     c.inject(this);
36 |  *   }
37 |  *
38 |  *   public boolean search(String needle) {
39 |  *      // ... search for a needle in a haystack.
40 |  *   }
41 |  * 
42 |  * 
43 | * 44 | *

Note the following features: 45 | * 46 | *

    47 | *
  • {@code @Option} annotations are used to define various options associated with a 48 | * class. Options are decentralized, the only requirement is that the {@link 49 | * org.sosy_lab.common.configuration.Configuration} object is injected (preferably in the 50 | * constructor). 51 | *
  • The fields defining options can be private. The injector contains reflection calls to set 52 | * them to the arbitrary file. 53 | *
  • Normally, the type of the option is defined by the type of the field. For complex 54 | * cases (e.g. files) additional decorators are used. 55 | *
  • Option name is either derived from the field name (prefixed with a base prefix), 56 | * or set explicitly in the {@link org.sosy_lab.common.configuration.Option} annotation. 57 | *
58 | * 59 | *

Configuration options instance can be constructed in three different ways: 60 | * 61 | *

    62 | *
  • Most common if you have a lot of options and a large project: load them from the 63 | * configuration file. See {@link 64 | * org.sosy_lab.common.configuration.ConfigurationBuilder#loadFromFile} for details. 65 | *
  • Useful for smaller programs: construct an instance from command line options. See {@link 66 | * org.sosy_lab.common.configuration.Configuration#fromCmdLineArguments}. 67 | *
  • Most rare, useful for small scripts: construct an instance by hand, using {@link 68 | * org.sosy_lab.common.configuration.ConfigurationBuilder}. 69 | *
70 | */ 71 | @com.google.errorprone.annotations.CheckReturnValue 72 | @javax.annotation.ParametersAreNonnullByDefault 73 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 74 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 75 | package org.sosy_lab.common.configuration; 76 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/io/DuplicateOutputStream.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.io; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.common.io.ByteStreams; 14 | import java.io.IOException; 15 | import java.io.OutputStream; 16 | import org.checkerframework.checker.nullness.qual.Nullable; 17 | 18 | /** 19 | * This class is an OutputStream implementation that sends everything to two other OutputStreams. 20 | * 21 | *

Exceptions thrown by any of the streams will be relayed to the caller. 22 | */ 23 | public class DuplicateOutputStream extends OutputStream { 24 | 25 | private final OutputStream stream1; 26 | private final OutputStream stream2; 27 | 28 | public DuplicateOutputStream(OutputStream pStream1, OutputStream pStream2) { 29 | stream1 = checkNotNull(pStream1); 30 | stream2 = checkNotNull(pStream2); 31 | } 32 | 33 | /** 34 | * Create an output stream that forwards to all given output streams, ignoring null parameters. 35 | */ 36 | public static OutputStream mergeStreams( 37 | @Nullable OutputStream stream1, @Nullable OutputStream stream2) { 38 | 39 | if (stream1 == null) { 40 | if (stream2 == null) { 41 | return ByteStreams.nullOutputStream(); 42 | } else { 43 | return stream2; 44 | } 45 | 46 | } else { 47 | if (stream2 == null) { 48 | return stream1; 49 | } else { 50 | return new DuplicateOutputStream(stream1, stream2); 51 | } 52 | } 53 | } 54 | 55 | @Override 56 | public void write(int pB) throws IOException { 57 | try { 58 | stream1.write(pB); 59 | } finally { 60 | stream2.write(pB); 61 | } 62 | } 63 | 64 | @Override 65 | public void write(byte[] pB) throws IOException { 66 | try { 67 | stream1.write(pB); 68 | } finally { 69 | stream2.write(pB); 70 | } 71 | } 72 | 73 | @Override 74 | public void write(byte[] pB, int pOff, int pLen) throws IOException { 75 | try { 76 | stream1.write(pB, pOff, pLen); 77 | } finally { 78 | stream2.write(pB, pOff, pLen); 79 | } 80 | } 81 | 82 | @Override 83 | public void flush() throws IOException { 84 | try { 85 | stream1.flush(); 86 | } finally { 87 | stream2.flush(); 88 | } 89 | } 90 | 91 | @Override 92 | public void close() throws IOException { 93 | try { 94 | stream1.close(); 95 | } finally { 96 | stream2.close(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/io/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.io; 10 | 11 | import com.google.common.base.Joiner; 12 | import com.google.common.testing.AbstractPackageSanityTests; 13 | import java.lang.reflect.Constructor; 14 | import java.lang.reflect.Method; 15 | import java.net.URL; 16 | import java.net.URLClassLoader; 17 | import java.nio.file.Path; 18 | 19 | @SuppressWarnings({"BanClassLoader", "resource"}) 20 | public class PackageSanityTest extends AbstractPackageSanityTests { 21 | 22 | { 23 | setDefault(String.class, "test"); 24 | setDefault(String[].class, new String[] {"test"}); 25 | setDefault(Joiner.MapJoiner.class, Joiner.on(",").withKeyValueSeparator("=")); 26 | setDefault(ClassLoader.class, new URLClassLoader(new URL[0])); 27 | setDefault(Path.class, Path.of("")); 28 | try { 29 | setDefault(Constructor.class, PackageSanityTest.class.getConstructor()); 30 | setDefault(Method.class, PackageSanityTest.class.getDeclaredMethod("defaultMethod")); 31 | } catch (NoSuchMethodException e) { 32 | throw new AssertionError(e); 33 | } 34 | } 35 | 36 | @SuppressWarnings("unused") 37 | private static void defaultMethod() {} 38 | } 39 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/io/PathCounterTemplate.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.io; 10 | 11 | import static com.google.common.base.Preconditions.checkArgument; 12 | 13 | import com.google.common.base.MoreObjects; 14 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 15 | import java.nio.file.Path; 16 | import java.util.IllegalFormatException; 17 | import java.util.concurrent.atomic.AtomicInteger; 18 | 19 | /** 20 | * A template for {@link Path} objects that uses a counter to produce paths with a fresh new name 21 | * for every request. 22 | */ 23 | public final class PathCounterTemplate { 24 | 25 | private final String template; 26 | private final AtomicInteger counter = new AtomicInteger(); 27 | 28 | private PathCounterTemplate(String pTemplate) { 29 | checkArgument(!pTemplate.isEmpty()); 30 | checkPatternValidity(pTemplate); 31 | 32 | template = pTemplate; 33 | } 34 | 35 | /** 36 | * Check whether a String is a valid template for inserting one int with {@link 37 | * String#format(String, Object...)}. 38 | * 39 | * @param pTemplate The template to check. 40 | * @throws IllegalFormatException If the pattern is invalid. 41 | */ 42 | @SuppressWarnings("ReturnValueIgnored") 43 | @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED") 44 | private static void checkPatternValidity(String pTemplate) { 45 | String.format(pTemplate, 0); 46 | } 47 | 48 | /** 49 | * Create a new instance. 50 | * 51 | * @param pTemplate A non-null non-empty template String in the format for {@link 52 | * String#format(String, Object...)} that is suited for exactly one argument of type int. 53 | * @throws IllegalFormatException If the template is invalid. 54 | */ 55 | public static PathCounterTemplate ofFormatString(String pTemplate) { 56 | return new PathCounterTemplate(pTemplate); 57 | } 58 | 59 | /** 60 | * Construct a concrete {@link Path} that was not handed out by this instance before. 61 | * 62 | * @throws IllegalFormatException If the template is invalid, or the arguments does not match the 63 | * template. 64 | */ 65 | public Path getFreshPath() { 66 | return Path.of(String.format(template, counter.getAndIncrement())); 67 | } 68 | 69 | /** Returns the raw template of this instance. */ 70 | public String getTemplate() { 71 | return template; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return MoreObjects.toStringHelper(this) 77 | .add("template", template) 78 | .add("counter", counter.get()) 79 | .toString(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/io/PathTemplate.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.io; 10 | 11 | import static com.google.common.base.Preconditions.checkArgument; 12 | 13 | import com.google.common.base.MoreObjects; 14 | import com.google.errorprone.annotations.Immutable; 15 | import java.nio.file.Path; 16 | import java.util.Arrays; 17 | import java.util.IllegalFormatException; 18 | 19 | /** 20 | * A template for paths, from which a real path can be constructed by passing some values to fill in 21 | * the blanks. 22 | */ 23 | @Immutable 24 | public final class PathTemplate { 25 | 26 | private final String template; 27 | 28 | private PathTemplate(String pTemplate) { 29 | checkArgument(!pTemplate.isEmpty()); 30 | template = pTemplate; 31 | } 32 | 33 | /** 34 | * Create a new instance. 35 | * 36 | * @param pTemplate A non-null non-empty template String in the format for {@link 37 | * String#format(String, Object...)}. 38 | */ 39 | public static PathTemplate ofFormatString(String pTemplate) { 40 | return new PathTemplate(pTemplate); 41 | } 42 | 43 | /** 44 | * Construct a concrete {@link Path} from this template and the given values. 45 | * 46 | * @throws IllegalFormatException If the template is invalid, or the arguments does not match the 47 | * template. 48 | */ 49 | public Path getPath(Object... args) { 50 | checkArgument(!Arrays.asList(args).contains(null), "Values for PathTemplate may not be null"); 51 | 52 | return Path.of(String.format(template, args)); 53 | } 54 | 55 | /** Returns the raw template of this instance. */ 56 | public String getTemplate() { 57 | return template; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return MoreObjects.toStringHelper(this).add("template", template).toString(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/io/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** This package contains utilities for I/O. */ 10 | @com.google.errorprone.annotations.CheckReturnValue 11 | @javax.annotation.ParametersAreNonnullByDefault 12 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 13 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 14 | package org.sosy_lab.common.io; 15 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/AbstractColoredLogFormatter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.common.base.MoreObjects; 12 | import java.util.logging.Formatter; 13 | import java.util.logging.Level; 14 | import java.util.logging.LogRecord; 15 | import org.sosy_lab.common.io.IO; 16 | 17 | /** 18 | * Abstract class for creating {@link Formatter}s that color {@link LogRecord}s with {@link 19 | * Level#SEVERE} and {@link Level#WARNING} red. 20 | */ 21 | abstract class AbstractColoredLogFormatter extends Formatter { 22 | 23 | private final boolean useColors; 24 | 25 | protected AbstractColoredLogFormatter(boolean pUseColors) { 26 | useColors = pUseColors && IO.mayUseColorForOutput(); 27 | } 28 | 29 | @Override 30 | public final String format(LogRecord lr) { 31 | StringBuilder sb = new StringBuilder(200); 32 | 33 | if (useColors) { 34 | if (lr.getLevel().equals(Level.WARNING)) { 35 | sb.append("\033[1m"); // bold normal color 36 | } else if (lr.getLevel().equals(Level.SEVERE)) { 37 | sb.append("\033[31;1m"); // bold red color 38 | } 39 | } 40 | format(lr, sb); 41 | if (useColors) { 42 | sb.append("\033[m"); 43 | } 44 | return sb.toString(); 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return MoreObjects.toStringHelper(this).add("useColors", useColors).toString(); 50 | } 51 | 52 | /** 53 | * Formats {@link LogRecord} using the provided {@link StringBuilder}.
54 | * This method corresponds to {@link Formatter#format(LogRecord)} in a template method pattern. 55 | * The coloring behaviour is provided by superclass. 56 | * 57 | * @see Formatter#format(LogRecord) 58 | * @param lr the {@link LogRecord} to format. 59 | * @param sb the {@link StringBuilder} for {@link LogRecord} formatting. 60 | */ 61 | protected abstract void format(LogRecord lr, StringBuilder sb); 62 | } 63 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/ConsoleLogFormatter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import java.util.Objects; 12 | import java.util.logging.Formatter; 13 | import java.util.logging.LogRecord; 14 | 15 | /** Class to handle formatting for console output. */ 16 | public class ConsoleLogFormatter extends AbstractColoredLogFormatter { 17 | 18 | public ConsoleLogFormatter(LoggingOptions options) { 19 | this(options.useColors()); 20 | } 21 | 22 | private ConsoleLogFormatter(boolean useColors) { 23 | super(useColors); 24 | } 25 | 26 | public static Formatter withoutColors() { 27 | return new ConsoleLogFormatter(/* useColors= */ false); 28 | } 29 | 30 | public static Formatter withColorsIfPossible() { 31 | return new ConsoleLogFormatter(/* useColors= */ true); 32 | } 33 | 34 | @Override 35 | protected void format(LogRecord lr, StringBuilder sb) { 36 | sb.append(lr.getMessage()).append(" ("); 37 | if (lr instanceof ExtendedLogRecord) { 38 | String component = ((ExtendedLogRecord) lr).getSourceComponentName(); 39 | if (!component.isEmpty()) { 40 | sb.append(component).append(':'); 41 | } 42 | } 43 | 44 | sb.append(Objects.requireNonNullElse(LogUtils.extractSimpleClassName(lr), "$Unknown$")) 45 | .append('.') 46 | .append(Objects.requireNonNullElse(lr.getSourceMethodName(), "$unknown$")) 47 | .append(", ") 48 | .append(lr.getLevel().toString()) 49 | .append(')'); 50 | sb.append("\n\n"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/ExtendedLogRecord.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | import com.google.common.base.MoreObjects; 14 | import java.util.logging.Level; 15 | import java.util.logging.LogRecord; 16 | import org.checkerframework.checker.nullness.qual.Nullable; 17 | 18 | /** An extension of {@link LogRecord} that stores additional information. */ 19 | public class ExtendedLogRecord extends LogRecord { 20 | 21 | private static final long serialVersionUID = -2531000268930566255L; 22 | 23 | private String componentName = ""; 24 | 25 | public ExtendedLogRecord(Level pLevel, @Nullable String pMsg) { 26 | super(pLevel, pMsg); 27 | } 28 | 29 | public void setSourceComponentName(String pComponentName) { 30 | componentName = checkNotNull(pComponentName); 31 | } 32 | 33 | public String getSourceComponentName() { 34 | return componentName; 35 | } 36 | 37 | @Override 38 | @SuppressWarnings("deprecation") // Java 16 replaces getThreadID() with getLongThreadID() 39 | public String toString() { 40 | return MoreObjects.toStringHelper(this) 41 | .add("sequenceNumber", getSequenceNumber()) 42 | .add("millis", getMillis()) 43 | .add("loggerName", getLoggerName()) 44 | .add("componentName", componentName) 45 | .add("sourceClassName", getSourceClassName()) 46 | .add("sourceMethodName", getSourceMethodName()) 47 | .add("threadID", getThreadID()) 48 | .add("level", getLevel()) 49 | .add("message", getMessage()) 50 | .add("parameters", getParameters()) 51 | .add("thrown", getThrown()) 52 | .toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/FileLogFormatter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | /** 12 | * @deprecated use {@link TimestampedLogFormatter} instead. 13 | */ 14 | @Deprecated 15 | public class FileLogFormatter extends TimestampedLogFormatter { 16 | 17 | /** 18 | * @deprecated use {@link TimestampedLogFormatter#withoutColors()} 19 | */ 20 | @Deprecated 21 | public FileLogFormatter() { 22 | super(false); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/ForwardingLogManager.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.errorprone.annotations.ForOverride; 12 | import com.google.errorprone.annotations.FormatMethod; 13 | import java.util.function.Supplier; 14 | import java.util.logging.Level; 15 | import org.checkerframework.checker.nullness.qual.Nullable; 16 | 17 | public abstract class ForwardingLogManager implements LogManager { 18 | 19 | @ForOverride 20 | protected abstract LogManager delegate(); 21 | 22 | @Override 23 | public boolean wouldBeLogged(Level pPriority) { 24 | return delegate().wouldBeLogged(pPriority); 25 | } 26 | 27 | @Override 28 | public void log(Level pPriority, Object... pArgs) { 29 | delegate().log(pPriority, pArgs); 30 | } 31 | 32 | @Override 33 | public void log(Level pPriority, Supplier pMsgSupplier) { 34 | delegate().log(pPriority, pMsgSupplier); 35 | } 36 | 37 | @Override 38 | @FormatMethod 39 | public void logf(Level pPriority, String pFormat, Object... pArgs) { 40 | delegate().logf(pPriority, pFormat, pArgs); 41 | } 42 | 43 | @Override 44 | public void logUserException(Level pPriority, Throwable pE, @Nullable String pAdditionalMessage) { 45 | delegate().logUserException(pPriority, pE, pAdditionalMessage); 46 | } 47 | 48 | @Override 49 | @FormatMethod 50 | public void logfUserException(Level pPriority, Throwable pE, String pFormat, Object... pArgs) { 51 | delegate().logfUserException(pPriority, pE, pFormat, pArgs); 52 | } 53 | 54 | @Override 55 | public void logDebugException(Throwable pE, @Nullable String pAdditionalMessage) { 56 | delegate().logDebugException(pE, pAdditionalMessage); 57 | } 58 | 59 | @Override 60 | @FormatMethod 61 | public void logfDebugException(Throwable pE, String pFormat, Object... pArgs) { 62 | delegate().logfDebugException(pE, pFormat, pArgs); 63 | } 64 | 65 | @Override 66 | public void logDebugException(Throwable pE) { 67 | delegate().logDebugException(pE); 68 | } 69 | 70 | @Override 71 | public void logException(Level pPriority, Throwable pE, @Nullable String pAdditionalMessage) { 72 | delegate().logException(pPriority, pE, pAdditionalMessage); 73 | } 74 | 75 | @Override 76 | @FormatMethod 77 | public void logfException(Level pPriority, Throwable pE, String pFormat, Object... pArgs) { 78 | delegate().logfException(pPriority, pE, pFormat, pArgs); 79 | } 80 | 81 | @Override 82 | public void flush() { 83 | delegate().flush(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/ForwardingLogManagerTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.common.testing.ForwardingWrapperTester; 12 | import org.junit.Test; 13 | 14 | public class ForwardingLogManagerTest { 15 | 16 | @Test 17 | public void test() { 18 | new ForwardingWrapperTester() 19 | .testForwarding( 20 | LogManager.class, 21 | pInput -> 22 | new ForwardingLogManager() { 23 | 24 | @Override 25 | protected LogManager delegate() { 26 | return pInput; 27 | } 28 | 29 | // following makes only sense in test 30 | 31 | @Override 32 | public LogManager withComponentName(String pName) { 33 | return pInput.withComponentName(pName); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return pInput.toString(); 39 | } 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/LogFormatterTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | 13 | import com.google.common.collect.ImmutableList; 14 | import java.util.logging.Formatter; 15 | import java.util.logging.Level; 16 | import java.util.logging.LogRecord; 17 | import org.checkerframework.checker.nullness.qual.Nullable; 18 | import org.junit.Before; 19 | import org.junit.Test; 20 | import org.junit.runner.RunWith; 21 | import org.junit.runners.Parameterized; 22 | import org.junit.runners.Parameterized.Parameter; 23 | import org.junit.runners.Parameterized.Parameters; 24 | 25 | @RunWith(Parameterized.class) 26 | public class LogFormatterTest { 27 | 28 | @Parameters(name = "{0}") 29 | public static ImmutableList formatters() { 30 | return ImmutableList.of( 31 | ConsoleLogFormatter.withColorsIfPossible(), 32 | ConsoleLogFormatter.withoutColors(), 33 | TimestampedLogFormatter.withColorsIfPossible(), 34 | TimestampedLogFormatter.withoutColors()); 35 | } 36 | 37 | @Parameter(0) 38 | public Formatter formatter; 39 | 40 | @Before 41 | public void setup() { 42 | formatter = ConsoleLogFormatter.withoutColors(); 43 | } 44 | 45 | private static LogRecord createTestLogRecord(Level level, @Nullable String msg) { 46 | LogRecord record = new LogRecord(level, msg); 47 | record.setSourceClassName("package.SourceClass"); 48 | record.setSourceMethodName("sourceMethod"); 49 | return record; 50 | } 51 | 52 | @Test 53 | public void testMessageContained() { 54 | LogRecord record = createTestLogRecord(Level.SEVERE, "TEST MESSAGE"); 55 | assertThat(formatter.format(record)).contains("TEST MESSAGE"); 56 | } 57 | 58 | @Test 59 | public void testLevelContainedSevere() { 60 | LogRecord record = createTestLogRecord(Level.SEVERE, null); 61 | String msg = formatter.format(record); 62 | assertThat(msg).contains("SEVERE"); 63 | assertThat(msg).doesNotContain("WARNING"); 64 | } 65 | 66 | @Test 67 | public void testLevelContainedWarning() { 68 | LogRecord record = createTestLogRecord(Level.WARNING, null); 69 | String msg = formatter.format(record); 70 | assertThat(msg).contains("WARNING"); 71 | assertThat(msg).doesNotContain("SEVERE"); 72 | } 73 | 74 | @Test 75 | public void testSourceClassContained() { 76 | LogRecord record = createTestLogRecord(Level.WARNING, null); 77 | String msg = formatter.format(record); 78 | assertThat(msg).contains("SourceClass"); 79 | assertThat(msg).doesNotContain("package"); 80 | } 81 | 82 | @Test 83 | public void testSourceMethodContained() { 84 | LogRecord record = createTestLogRecord(Level.WARNING, null); 85 | assertThat(formatter.format(record)).contains("sourceMethod"); 86 | } 87 | 88 | @Test 89 | public void testNoSourceInformation() { 90 | LogRecord record = new LogRecord(Level.WARNING, null); 91 | record.setSourceClassName(null); 92 | record.setSourceMethodName(null); 93 | assertThat(formatter.format(record)).contains("$Unknown$.$unknown$"); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/LogLevelFilter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.common.collect.ImmutableSet; 12 | import java.util.List; 13 | import java.util.logging.Filter; 14 | import java.util.logging.Level; 15 | import java.util.logging.LogRecord; 16 | 17 | /** {@link Filter} implementation for blacklisting log levels. */ 18 | class LogLevelFilter implements Filter { 19 | 20 | private final ImmutableSet excludeLevels; 21 | 22 | LogLevelFilter(List excludeLevels) { 23 | this.excludeLevels = ImmutableSet.copyOf(excludeLevels); 24 | } 25 | 26 | @Override 27 | public boolean isLoggable(LogRecord pRecord) { 28 | return !excludeLevels.contains(pRecord.getLevel()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/LogUtils.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import java.util.logging.LogRecord; 12 | import org.checkerframework.checker.nullness.qual.Nullable; 13 | 14 | final class LogUtils { 15 | 16 | private LogUtils() {} 17 | 18 | /** Get the simple name of the source class of a log record. */ 19 | static @Nullable String extractSimpleClassName(LogRecord lr) { 20 | String fullClassName = lr.getSourceClassName(); 21 | if (fullClassName == null) { 22 | return null; 23 | } 24 | int dotIndex = fullClassName.lastIndexOf('.'); 25 | assert dotIndex < fullClassName.length() - 1 : "Last character in a class name cannot be a dot"; 26 | 27 | // if no dot is contained, dotIndex is -1 so we get the substring from 0, 28 | // i.e., the whole string (which is what we want) 29 | 30 | String className = fullClassName.substring(dotIndex + 1); 31 | return className; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/LoggingOptions.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.common.collect.ImmutableList; 12 | import java.nio.file.Path; 13 | import java.util.List; 14 | import java.util.logging.Level; 15 | import org.sosy_lab.common.configuration.Configuration; 16 | import org.sosy_lab.common.configuration.FileOption; 17 | import org.sosy_lab.common.configuration.IntegerOption; 18 | import org.sosy_lab.common.configuration.InvalidConfigurationException; 19 | import org.sosy_lab.common.configuration.Option; 20 | import org.sosy_lab.common.configuration.Options; 21 | 22 | @Options( 23 | prefix = "log", 24 | description = 25 | "Possible log levels in descending order " 26 | + "\n(lower levels include higher ones):" 27 | + "\nOFF: no logs published" 28 | + "\nSEVERE: error messages" 29 | + "\nWARNING: warnings" 30 | + "\nINFO: messages" 31 | + "\nFINE: logs on main application level" 32 | + "\nFINER: logs on central CPA algorithm level" 33 | + "\nFINEST: logs published by specific CPAs" 34 | + "\nALL: debugging information" 35 | + "\nCare must be taken with levels of FINER or lower, as output files may " 36 | + "become quite large and memory usage might become an issue.") 37 | public class LoggingOptions { 38 | 39 | @Option( 40 | secure = true, 41 | name = "level", 42 | toUppercase = true, 43 | description = "log level of file output") 44 | private Level fileLevel = Level.OFF; 45 | 46 | @Option(secure = true, toUppercase = true, description = "log level of console output") 47 | private Level consoleLevel = Level.INFO; 48 | 49 | @Option( 50 | secure = true, 51 | toUppercase = true, 52 | description = "single levels to be excluded from being logged") 53 | private ImmutableList fileExclude = ImmutableList.of(); 54 | 55 | @Option( 56 | secure = true, 57 | toUppercase = true, 58 | description = "single levels to be excluded from being logged") 59 | private ImmutableList consoleExclude = ImmutableList.of(); 60 | 61 | @Option(secure = true, name = "file", description = "name of the log file") 62 | @FileOption(FileOption.Type.OUTPUT_FILE) 63 | private Path outputFile = Path.of("CPALog.txt"); 64 | 65 | @Option( 66 | secure = true, 67 | description = 68 | "Maximum size of log output strings before they will be truncated." 69 | + " Note that truncation is not precise and truncation to small values has no effect." 70 | + " Use 0 for disabling truncation completely.") 71 | @IntegerOption(min = 0) 72 | private int truncateSize = 10000; 73 | 74 | @Option(secure = true, description = "use colors for log messages on console") 75 | private boolean useColors = true; 76 | 77 | public LoggingOptions(Configuration config) throws InvalidConfigurationException { 78 | config.inject(this); 79 | } 80 | 81 | /** 82 | * This constructor is for inheritance, thus allowing users to use this class without sosy-lab's 83 | * {@link Configuration}. 84 | */ 85 | protected LoggingOptions() {} 86 | 87 | public Level getFileLevel() { 88 | return fileLevel; 89 | } 90 | 91 | public Level getConsoleLevel() { 92 | return consoleLevel; 93 | } 94 | 95 | public List getFileExclude() { 96 | return fileExclude; 97 | } 98 | 99 | public List getConsoleExclude() { 100 | return consoleExclude; 101 | } 102 | 103 | public Path getOutputFile() { 104 | return outputFile; 105 | } 106 | 107 | public int getTruncateSize() { 108 | return truncateSize; 109 | } 110 | 111 | public boolean useColors() { 112 | return useColors; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/NullLogManager.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import java.util.function.Supplier; 12 | import java.util.logging.Level; 13 | 14 | /** 15 | * {@link LogManager} implementation that does not log anything. 16 | * 17 | *

Note: Do not use this implementation for unit tests, use {@link TestLogManager} instead. 18 | * 19 | * @deprecated Use {@link LogManager#createNullLogManager()} instead. This class will be made 20 | * package-private. 21 | */ 22 | @Deprecated 23 | public enum NullLogManager implements LogManager { 24 | INSTANCE; 25 | 26 | public static LogManager getInstance() { 27 | return INSTANCE; 28 | } 29 | 30 | @Override 31 | public LogManager withComponentName(String pName) { 32 | return this; 33 | } 34 | 35 | @Override 36 | public boolean wouldBeLogged(Level pPriority) { 37 | return false; 38 | } 39 | 40 | @Override 41 | public void log(Level pPriority, Object... pArgs) {} 42 | 43 | @Override 44 | public void log(Level pPriority, Supplier pMsgSupplier) {} 45 | 46 | @Override 47 | public void logf(Level pPriority, String pFormat, Object... pArgs) {} 48 | 49 | @Override 50 | public void logUserException(Level pPriority, Throwable pE, String pAdditionalMessage) {} 51 | 52 | @Override 53 | public void logfUserException(Level pPriority, Throwable pE, String pFormat, Object... pArgs) {} 54 | 55 | @Override 56 | public void logDebugException(Throwable pE, String pAdditionalMessage) {} 57 | 58 | @Override 59 | public void logfDebugException(Throwable pE, String pFormat, Object... pArgs) {} 60 | 61 | @Override 62 | public void logDebugException(Throwable pE) {} 63 | 64 | @Override 65 | public void logException(Level pPriority, Throwable pE, String pAdditionalMessage) {} 66 | 67 | @Override 68 | public void logfException(Level pPriority, Throwable pE, String pFormat, Object... pArgs) {} 69 | 70 | @Override 71 | public void flush() {} 72 | } 73 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.common.base.Predicates; 12 | import com.google.common.testing.AbstractPackageSanityTests; 13 | import java.util.logging.Formatter; 14 | import java.util.logging.Handler; 15 | import java.util.logging.Level; 16 | import java.util.logging.LogRecord; 17 | import java.util.logging.SimpleFormatter; 18 | import org.sosy_lab.common.configuration.Configuration; 19 | import org.sosy_lab.common.configuration.InvalidConfigurationException; 20 | 21 | @SuppressWarnings("deprecation") 22 | public class PackageSanityTest extends AbstractPackageSanityTests { 23 | 24 | { 25 | setDefault(Handler.class, new StringBuildingLogHandler()); 26 | setDefault(Level.class, Level.ALL); 27 | setDefault(Formatter.class, new SimpleFormatter()); 28 | setDefault(LogRecord.class, new LogRecord(Level.ALL, "test")); 29 | 30 | setDefault(Configuration.class, Configuration.defaultConfiguration()); 31 | try { 32 | setDefault(LoggingOptions.class, new LoggingOptions(Configuration.defaultConfiguration())); 33 | } catch (InvalidConfigurationException e) { 34 | throw new AssertionError(e); 35 | } 36 | 37 | // NullLogManager does not do any checkNotNull checks on purpose 38 | ignoreClasses(Predicates.>equalTo(NullLogManager.class)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/StringBuildingLogHandler.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import com.google.errorprone.annotations.concurrent.GuardedBy; 12 | import java.util.logging.ErrorManager; 13 | import java.util.logging.Handler; 14 | import java.util.logging.LogRecord; 15 | import org.checkerframework.checker.nullness.qual.Nullable; 16 | 17 | /** This class may be used to read the log into a String. */ 18 | public class StringBuildingLogHandler extends Handler { 19 | 20 | @GuardedBy("this") 21 | private final StringBuilder sb = new StringBuilder(); 22 | 23 | @Override 24 | public void close() { 25 | // ignore 26 | } 27 | 28 | @Override 29 | public void flush() { 30 | // ignore 31 | } 32 | 33 | @Override 34 | public synchronized void publish(@Nullable LogRecord record) { 35 | // code copied from java.util.logging.StreamHandler#publish(LogRecord) 36 | if (!isLoggable(record)) { 37 | return; 38 | } 39 | String msg; 40 | try { 41 | msg = getFormatter().format(record); 42 | } catch (RuntimeException ex) { 43 | // We don't want to throw an exception here, but we 44 | // report the exception to any registered ErrorManager. 45 | reportError(null, ex, ErrorManager.FORMAT_FAILURE); 46 | return; 47 | } 48 | 49 | try { 50 | sb.append(msg); 51 | } catch (RuntimeException ex) { 52 | // We don't want to throw an exception here, but we 53 | // report the exception to any registered ErrorManager. 54 | reportError(null, ex, ErrorManager.WRITE_FAILURE); 55 | } 56 | } 57 | 58 | public synchronized String getLog() { 59 | return sb.toString(); 60 | } 61 | 62 | public synchronized void clear() { 63 | sb.setLength(0); 64 | sb.trimToSize(); // free memory 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/TimestampedLogFormatter.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.log; 10 | 11 | import java.time.ZoneId; 12 | import java.time.format.DateTimeFormatter; 13 | import java.util.Locale; 14 | import java.util.Objects; 15 | import java.util.logging.Formatter; 16 | import java.util.logging.Level; 17 | import java.util.logging.LogRecord; 18 | 19 | /** 20 | * Log formatter that produces output containing a timestamp. Each log message will look like this: 21 | * 22 | *

23 |  * timestamp {@link Level} (component:class.method) message
24 |  * 
25 | */ 26 | public class TimestampedLogFormatter extends AbstractColoredLogFormatter { 27 | 28 | private static final DateTimeFormatter DATE_FORMAT = 29 | DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS") 30 | .withLocale(Locale.getDefault(Locale.Category.FORMAT)) 31 | .withZone(ZoneId.systemDefault()); 32 | 33 | protected TimestampedLogFormatter(boolean useColors) { 34 | super(useColors); 35 | } 36 | 37 | @Override 38 | public void format(LogRecord lr, StringBuilder sb) { 39 | DATE_FORMAT.formatTo(lr.getInstant(), sb); 40 | sb.append('\t').append(lr.getLevel()).append('\t'); 41 | 42 | if (lr instanceof ExtendedLogRecord) { 43 | String component = ((ExtendedLogRecord) lr).getSourceComponentName(); 44 | if (!component.isEmpty()) { 45 | sb.append(component).append(':'); 46 | } 47 | } 48 | sb.append(Objects.requireNonNullElse(LogUtils.extractSimpleClassName(lr), "$Unknown$")) 49 | .append('.') 50 | .append(Objects.requireNonNullElse(lr.getSourceMethodName(), "$unknown$")) 51 | .append('\t') 52 | .append(lr.getMessage()) 53 | .append("\n\n"); 54 | } 55 | 56 | public static Formatter withoutColors() { 57 | return new TimestampedLogFormatter(/* useColors= */ false); 58 | } 59 | 60 | public static Formatter withColorsIfPossible() { 61 | return new TimestampedLogFormatter(/* useColors= */ true); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/log/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** 10 | * This package provides a logging framework. It is based on the JDK-internal logging, but provides 11 | * many additional features such as lazy log message creation, and convenience methods for 12 | * exceptions. 13 | */ 14 | @com.google.errorprone.annotations.CheckReturnValue 15 | @javax.annotation.ParametersAreNonnullByDefault 16 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 17 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 18 | package org.sosy_lab.common.log; 19 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** This package contains general utilities that do not fit anywhere else. */ 10 | @com.google.errorprone.annotations.CheckReturnValue 11 | @javax.annotation.ParametersAreNonnullByDefault 12 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 13 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 14 | package org.sosy_lab.common; 15 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/rationals/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2014-2020 Dirk Beyer 6 | // SPDX-FileCopyrightText: Université Grenoble Alpes 7 | // 8 | // SPDX-License-Identifier: Apache-2.0 9 | 10 | package org.sosy_lab.common.rationals; 11 | 12 | import com.google.common.testing.AbstractPackageSanityTests; 13 | 14 | public class PackageSanityTest extends AbstractPackageSanityTests { 15 | { 16 | setDistinctValues(Rational.class, Rational.of(1), Rational.of(2)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/rationals/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2014-2020 Dirk Beyer 6 | // SPDX-FileCopyrightText: Université Grenoble Alpes 7 | // 8 | // SPDX-License-Identifier: Apache-2.0 9 | 10 | /** Java-Rationals is a library for working with rationals and extended rationals in Java. */ 11 | @com.google.errorprone.annotations.CheckReturnValue 12 | @javax.annotation.ParametersAreNonnullByDefault 13 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 14 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 15 | package org.sosy_lab.common.rationals; 16 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/rationals/tests/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2016-2020 Dirk Beyer 6 | // SPDX-FileCopyrightText: Université Grenoble Alpes 7 | // 8 | // SPDX-License-Identifier: Apache-2.0 9 | 10 | /** Tests for the rationals package. */ 11 | @com.google.errorprone.annotations.CheckReturnValue 12 | @javax.annotation.ParametersAreNonnullByDefault 13 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 14 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 15 | package org.sosy_lab.common.rationals.tests; 16 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/time/PackageSanityTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.time; 10 | 11 | import com.google.common.testing.AbstractPackageSanityTests; 12 | 13 | public class PackageSanityTest extends AbstractPackageSanityTests { 14 | 15 | { 16 | setDefault(TimeSpan.class, TimeSpan.empty()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/time/TimerTest.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | package org.sosy_lab.common.time; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static org.junit.Assert.assertThrows; 13 | 14 | import org.junit.Test; 15 | 16 | public class TimerTest { 17 | 18 | @Test 19 | public void initialValue() { 20 | Timer timer = new Timer(); 21 | assertThat(timer.getNumberOfIntervals()).isEqualTo(0); 22 | assertThat(timer.getSumTime()).isEqualTo(TimeSpan.empty()); 23 | assertThat(timer.getLengthOfLastInterval()).isEqualTo(TimeSpan.empty()); 24 | assertThat(timer.getMaxTime()).isEqualTo(TimeSpan.empty()); 25 | assertThat(timer.getMinTime()).isEqualTo(TimeSpan.empty()); 26 | } 27 | 28 | @Test 29 | public void interval() { 30 | Timer timer = new Timer(); 31 | assertThat(timer.getNumberOfIntervals()).isEqualTo(0); 32 | timer.start(); 33 | assertThat(timer.getNumberOfIntervals()).isEqualTo(1); 34 | timer.stop(); 35 | assertThat(timer.getNumberOfIntervals()).isEqualTo(1); 36 | } 37 | 38 | @Test 39 | public void nterval2() { 40 | Timer timer = new Timer(); 41 | 42 | for (int i = 0; i < 5; i++) { 43 | assertThat(timer.getNumberOfIntervals()).isEqualTo(i); 44 | timer.start(); 45 | assertThat(timer.getNumberOfIntervals()).isEqualTo(i + 1); 46 | timer.stop(); 47 | assertThat(timer.getNumberOfIntervals()).isEqualTo(i + 1); 48 | } 49 | } 50 | 51 | @Test 52 | public void startTwice() { 53 | Timer timer = new Timer(); 54 | timer.start(); 55 | assertThrows(IllegalStateException.class, () -> timer.start()); 56 | } 57 | 58 | @Test 59 | public void stopTwice() { 60 | Timer timer = new Timer(); 61 | timer.start(); 62 | timer.stop(); 63 | assertThrows(IllegalStateException.class, () -> timer.stop()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/org/sosy_lab/common/time/package-info.java: -------------------------------------------------------------------------------- 1 | // This file is part of SoSy-Lab Common, 2 | // a library of useful utilities: 3 | // https://github.com/sosy-lab/java-common-lib 4 | // 5 | // SPDX-FileCopyrightText: 2007-2020 Dirk Beyer 6 | // 7 | // SPDX-License-Identifier: Apache-2.0 8 | 9 | /** 10 | * This package provides possibilities for measuring elapsed time, and a data class {@link 11 | * org.sosy_lab.common.time.TimeSpan} for storing time spans together with the respective time unit. 12 | */ 13 | @com.google.errorprone.annotations.CheckReturnValue 14 | @javax.annotation.ParametersAreNonnullByDefault 15 | @org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault 16 | @org.sosy_lab.common.annotations.FieldsAreNonnullByDefault 17 | package org.sosy_lab.common.time; 18 | -------------------------------------------------------------------------------- /website/index.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | SoSy-Lab Common Library 17 | 18 | 19 | 20 | Javadoc API documentation 21 | 22 | --------------------------------------------------------------------------------