Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implement EnvPathParser #12

Merged
merged 15 commits into from
Dec 7, 2023
39 changes: 13 additions & 26 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ on:
jobs:

test:

if: github.ref != 'refs/heads/main'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 1.8
uses: actions/setup-java@v3
with:
Expand All @@ -32,35 +32,22 @@ jobs:
run: mvn -B --update-snapshots clean test

build:

if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK 1.8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'corretto'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml

# create_tag:
#
# runs-on: ubuntu-latest
#
# needs: build
#
# if: github.ref == 'refs/heads/main'
#
# steps:
# - name: Get version from pom.xml
# run: echo "##[set-output name=version]$(xmllint --xpath 'string(/project/version)' pom.xml)"
# id: get_version
# - name: Create tag
# run: |
# echo "Creating tag v${{ steps.get_version.outputs.version }}"
# git tag -a v${{ steps.get_version.outputs.version }} -m "Release v${{ steps.get_version.outputs.version }}"
# git push origin v${{ steps.get_version.outputs.version }}
#
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
- name: Publish package
run: mvn --batch-mode clean deploy
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ build/
.DS_Store

### Project ###
dependency-reduced-pom.xml
pom.xml.versionsBackup
javadoc
/dependency-reduced-pom.xml
/javadoc
/release.properties
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.0.6] - 07-12-2023

### Added

- `EnvPathParser` first implementation and JavaDoc
- `EnvPathParser` simple unit tests
- `ParametersProvider` in test package to facilitate testing with several, different parameters.

### Changed

- Reworked GitHub `maven.yml` to only test in non-production branches and compile, test, package and deploy on
production branches.
- README.md Update

### Changed

- Moved `DocConstants` to `pt/codeforge/toolertools/xml` to make it effectively Package-Private

## [0.0.5] - 03-12-2023

### Added
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ simplify your development tasks.
</dependency>
```

## Featuring
## Tools

**XmlHandler** retrieves values from a doc when provided with the target XPath.

Why parse through a whole XML just to retrieve one value? We can use the power of tooler-tools and XPath. There's no
management or error handling.
**EnvPathParser** parses and expands env path variables into file paths.

![EnvPathParserUseCase.png](docs/resources/EnvPathParserUseCase.png)

### Example - Get String From XPath

Expand Down
Binary file added docs/resources/EnvPathParserUseCase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 5 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>pt.codeforge</groupId>
<artifactId>tooler-tools</artifactId>
<version>0.0.5</version>
<version>0.0.6</version>
<packaging>jar</packaging>
<name>tooler-tools</name>
<description>Versatile library for backend and CLI developers, offers a growing collection of
Expand All @@ -33,10 +31,10 @@

<scm>
<connection>scm:git:git://github.com/rikkarth/tooler-tools.git</connection>
<developerConnection>scm:git:ssh://github.com:rikkarth/tooler-tools.git
</developerConnection>
<developerConnection>scm:git:git@github.com:rikkarth/tooler-tools.git</developerConnection>
<url>http://github.com/rikkarth/tooler-tools/tree/main</url>
</scm>
<tag>tooler-tools-0.0.6</tag>
</scm>

<distributionManagement>
<repository>
Expand Down
13 changes: 0 additions & 13 deletions src/main/java/pt/codeforge/toolertools/internal/DocConstants.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package pt.codeforge.toolertools.pathfinder;

import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
* Utility class for parsing and expanding environment variables in file paths. This class provides static methods for
* parsing input paths, replacing environment variable placeholders with their respective values on both Windows and
* Unix-like systems.
*
* <p><b>Note:</b> This class should not be instantiated as it consists of static utility methods only.
*
* @see EnvPathParser#getEnvPath(String)
* @see EnvPathParser#parseIfMys(AtomicReference, List)
* @see EnvPathParser#parseIfUnix(AtomicReference, List)
*/
public class EnvPathParser {

private EnvPathParser() {
throw new AssertionError("EnvPathParser should not be instantiated.");
}

/**
* Parses the input path by replacing environment variable placeholders with their respective values. Environment
* variable placeholders are denoted by percent signs ('%') on both ends for Windows and by a dollar sign ('$') at
* the beginning for Unix-like systems. The method handles both styles. After parsing, the method returns the
* normalized path as a String, or if when path string cannot be converted into a {@link Path} because the path
* string contains invalid characters, or the path string is invalid for other file system specific reasons, it
* returns the path as literally converted.
*
* @param input The input path to be parsed. Must not be null.
* @return The parsed and normalized path as a String.
* @throws IllegalArgumentException If the input parameter is null.
*/
public static String getEnvPath(String input) {
if (input == null) {
throw new IllegalArgumentException("Input cannot be null.");
}

AtomicReference<String> inputCopy = new AtomicReference<>(input);
List<String> pathComponentsList = Arrays.asList((inputCopy.get()).split("[/\\\\:-]"));
parseIfMys(inputCopy, pathComponentsList);
parseIfUnix(inputCopy, pathComponentsList);

return getPathOrDefault(inputCopy);
}

private static String getPathOrDefault(AtomicReference<String> inputCopy) {
try {
return Paths.get(inputCopy.get()).toString();
} catch (InvalidPathException ipe) {
return inputCopy.get();
}
}

private static void parseIfMys(AtomicReference<String> inputCopy,
List<String> pathComponentsList) {
pathComponentsList
.stream()
.filter(component -> component.startsWith("%") && component.endsWith("%"))
.forEach(component -> {
String envVarName = component.substring(1, component.length() - 1);
String envVarValue = System.getenv(envVarName);
if (envVarValue != null) {
inputCopy.set((inputCopy.get()).replace(component, envVarValue));
}
});
}

private static void parseIfUnix(AtomicReference<String> inputCopy,
List<String> pathComponentsList) {
pathComponentsList
.stream()
.filter(component -> component.startsWith("$"))
.forEach(component -> {
String envVarName = component.substring(1);
String envVarValue = System.getenv(envVarName);
if (envVarValue != null) {
inputCopy.set((inputCopy.get()).replace(component, envVarValue));
}
});
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.apache.commons.configuration2.ex.ConfigurationException;
import pt.codeforge.toolertools.internal.exceptions.PropertiesGenerationException;
import pt.codeforge.toolertools.internal.exceptions.PropertiesLoadingException;
import pt.codeforge.toolertools.pathfinder.SystemEnvParser;
import pt.codeforge.toolertools.pathfinder.EnvPathParser;

public class PropertiesLoader {

Expand All @@ -21,7 +21,7 @@ public Properties loadProperties(String propName) throws PropertiesGenerationExc
String filePath = this.getOptionalFilePath(propName).orElseThrow(
() -> new PropertiesLoadingException(getPropertiesLoadingErrorMsg(propName)));

String propsPath = SystemEnvParser.getEnvPath(filePath);
String propsPath = EnvPathParser.getEnvPath(filePath);

return this.getOptionalProperties(propsPath).orElseThrow(
() -> new PropertiesGenerationException(getInvalidPathToPropErrorMsg(propName, propsPath)));
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/pt/codeforge/toolertools/xml/DocConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package pt.codeforge.toolertools.xml;

class DocConstants {

private DocConstants() {
}

protected static final String NAMESPACES = "http://xml.org/sax/features/namespaces";
protected static final String VALIDATION = "http://xml.org/sax/features/validation";
protected static final String LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
protected static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
}
1 change: 0 additions & 1 deletion src/main/java/pt/codeforge/toolertools/xml/XmlHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import pt.codeforge.toolertools.internal.DocConstants;

/**
* Utility class for handling operations on XML files or XPath expressions.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package pt.codeforge.toolertools.pathfinder;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class EnvPathParserTest {

@ParameterizedTest
@ValueSource(strings = "$HOME")
void givenUnixValidEnvVariable_testgetEnvPath_shouldReturnValidPath(String input) {
String result = EnvPathParser.getEnvPath(input);

assertValidResult(input, result);
}

@ParameterizedTest
@ValueSource(strings = "$HOME/$TEMP")
void givenUnixMultipleValidEnvVariables_testgetEnvPath_shouldReturnValidPath(String input) {
String result = EnvPathParser.getEnvPath(input);

assertValidResult(input, result);
}

@ParameterizedTest
@ValueSource(strings = "$HOME/%HOME%")
void givenUnixAndMysMultipleValidEnvVariables_testgetEnvPath_shouldReturnValidPath(String input) {
String result = EnvPathParser.getEnvPath(input);

assertValidResult(input, result);
}

@Test
void givenNullInput_testGetEnvPath_shouldThrowIllegalArgumentException() {
assertThrows(IllegalArgumentException.class, () -> EnvPathParser.getEnvPath(null),
"EnvPathParser#getEnvPath should throw IllegalArgumentException.class.");
}

private static void assertValidResult(String input, String result) {
assertNotEquals(input, result, "Input should not be equal to result.");
assertFalse(result.isEmpty(), "Result should not be empty.");
}
}
Loading