Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 75 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,84 @@

# Overview

Library designed for retrieving properties set at application startup.
Library designed for retrieving properties set at application startup. If you don't use Spring Framework/Spring Boot but
like its configuration via yaml - you will find this library useful.

# Advantages

1) Lightweight, no need to pull lots of dependencies
2) No reflection and typecasts
3) Null safe and runtime exception free

# Quick start

This library is distributed via [jitpack.io](https://jitpack.io/#ArtemGet/entrys)

# Supported properties
# Supported entries

1) Properties passed via -D
2) Json files (strings, objects, arrays)
2) Environment variables
3) Json strings
4) Yaml files

# Examples

## Properties:

```java
String prop=new EProp("your_prop_passed_via_-D").value();
```

## Environment variables:

```java
String env=new EEnv("my_env").value()
```

## Json strings:

TODO add docs

## Yaml files:

1) Works similar to spring
framework [@Value](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Value.html)
2) Supports string, number, arrays, float, boolean as value
3) Supports default values and env injections
4) Default yaml file config is placed under "src/main/resources/application.yaml", but is configurable

```yaml
sex: "male"
person:
name: "kekus"
languages: [ ru,en ]
age: ${AGE_ENV:123}
```

#### Getting attribute:

```java
String sex=new EVal("sex").value();
```

#### Getting nested attribute:

```java
String name=new EVal("person.name").value();
```

#### Getting array

```java
List<String> languages=new ESplit(new EVal("person.languages")).value();
```

#### Getting env

```java
String age=new EVal("person.age").value();
```

TODO:
1) Environment variables
2) Yaml files
3) Properties files
1) If there is a default value and env is not present - will return default value
2) If there is a default value and env is present - will return value from env
3) If default value is not present - will return value from env
12 changes: 11 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.amihaiemil.web</groupId>
<artifactId>eo-yaml</artifactId>
<version>8.0.6</version>
<exclusions>
<exclusion>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
Expand All @@ -27,7 +38,6 @@
<groupId>org.cactoos</groupId>
<artifactId>cactoos</artifactId>
<version>0.57.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
Expand Down
63 changes: 63 additions & 0 deletions src/main/java/io/github/artemget/entrys/file/EFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* MIT License
*
* Copyright (c) 2024-2025. Artem Getmanskii
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.github.artemget.entrys.file;

import io.github.artemget.entrys.ESafe;
import io.github.artemget.entrys.EntryException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* File's content entry.
*
* @since 0.4.0
*/
public class EFile extends ESafe<String> {
public EFile(final String path) {
this(path, StandardCharsets.UTF_8);
}

public EFile(final String path, final Charset charset) {
super(
() -> {
try {
return Files.readString(Path.of(path), charset);
} catch (final IOException | SecurityException exception) {
throw new EntryException(
String.format(
"Failed to load contents of file for path: '%s'",
path
),
exception
);
}
},
() -> String.format("Empty file for path: '%s'", path)
);
}
}
134 changes: 134 additions & 0 deletions src/main/java/io/github/artemget/entrys/file/EVal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* MIT License
*
* Copyright (c) 2024-2025. Artem Getmanskii
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.github.artemget.entrys.file;

import com.amihaiemil.eoyaml.Node;
import com.amihaiemil.eoyaml.Yaml;
import com.amihaiemil.eoyaml.YamlMapping;
import com.amihaiemil.eoyaml.YamlNode;
import io.github.artemget.entrys.ESafe;
import io.github.artemget.entrys.Entry;
import io.github.artemget.entrys.EntryException;
import io.github.artemget.entrys.operation.EContains;
import io.github.artemget.entrys.operation.EFork;
import io.github.artemget.entrys.operation.ESplit;
import io.github.artemget.entrys.operation.EUnwrap;
import io.github.artemget.entrys.system.EEnv;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
* Configuration properties entry.
* By default gets entries from "src/main/resources/application.yaml"
* Supports all yaml types, default values and envs passed via ${ENV}.
*
* @since 0.4.0
*/
public final class EVal extends ESafe<String> {

/**
* From yaml file at default dir.
*
* @param key Of entry
*/
public EVal(final String key) {
this(key, "src/main/resources/application.yaml");
}

/**
* From yaml file.
*
* @param key Of entry
* @param path To yaml file
*/
public EVal(final String key, final String path) {
this(key, new EFile(path));
}

/**
* Main ctor.
*
* @param key Of Entry
* @param content Yaml content
*/
@SuppressWarnings("PMD.ConstructorOnlyInitializesOrCallOtherConstructors")
public EVal(final String key, final Entry<String> content) {
super(
() -> {
YamlMapping root;
try {
root = Yaml.createYamlInput(content.value())
.readYamlMapping();
} catch (final IOException | EntryException exception) {
throw new EntryException(
String.format("Failed to read yaml mapping for key: '%s'", key),
exception
);
}
String res = null;
final List<String> elements = new ESplit(() -> key, ".").value();
for (int element = 0; element < elements.size(); ++element) {
if (element == elements.size() - 1) {
final YamlNode value = root.value(elements.get(element));
if (Node.SCALAR == value.type()) {
res = EVal.ejected(value);
} else if (Node.SEQUENCE == value.type()) {
res = value.asSequence()
.children().stream()
.map(node -> node.asScalar().value())
.collect(Collectors.joining(";"));
}
}
root = root.yamlMapping(elements.get(element));
}
return res;
},
() -> String.format("Attribute for key '%s' is null", key)
);
}

private static String ejected(final YamlNode node) throws EntryException {
final String scalar = node.asScalar().value();
return new EFork<>(
() -> scalar.startsWith("${") && scalar.endsWith("}"),
new EFork<>(
() -> new ESplit(() -> scalar, ":").value().size() == 2,
new EFork<>(
new EContains(new EEnv(() -> EVal.selected(scalar, 0).trim())),
new EEnv(() -> EVal.selected(scalar, 0).trim()),
() -> EVal.selected(scalar, 1).trim()
),
new EEnv(new EUnwrap(scalar, "${", "}"))
),
() -> scalar
).value();
}

private static String selected(final String scalar, final int pos) throws EntryException {
return new ESplit(new EUnwrap(scalar, "${", "}"), ":")
.value().get(pos);
}
}
28 changes: 28 additions & 0 deletions src/main/java/io/github/artemget/entrys/file/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* MIT License
*
* Copyright (c) 2024-2025. Artem Getmanskii
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/**
* Entries that read stuff from files.
*/
package io.github.artemget.entrys.file;
Loading