Skip to content

Commit

Permalink
Merge pull request #68 from microsphere-projects/dev-1.x
Browse files Browse the repository at this point in the history
Release 0.1.0
  • Loading branch information
mercyblitz authored Jan 7, 2025
2 parents b963193 + b46ff5e commit 1960355
Show file tree
Hide file tree
Showing 246 changed files with 14,728 additions and 4,154 deletions.
16 changes: 12 additions & 4 deletions .github/workflows/maven-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ jobs:
strategy:
matrix:
java: [ '8', '11' , '17' , '21' ]
maven-profile-spring-boot: [ 'spring-boot-2.7' ]
maven-profile-spring-framework: [
'spring-framework-5.3' , 'spring-framework-5.2', 'spring-framework-5.1' , 'spring-framework-5.0' ,
'spring-framework-4.3'
]
steps:
- name: Checkout Source
uses: actions/checkout@v4
Expand All @@ -38,6 +41,11 @@ jobs:
--update-snapshots
--file pom.xml
-Drevision=0.0.1-SNAPSHOT
-DargLine="${{ matrix.java >= 16 && '--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED' || '' }}"
-P${{ matrix.maven-profile-spring-boot }}
test
test
--activate-profiles test,coverage,${{ matrix.maven-profile-spring-framework }}

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: microsphere-projects/microsphere-spring
9 changes: 8 additions & 1 deletion .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ jobs:
cache: maven

- name: Publish package
run: mvn --batch-mode --update-snapshots -Drevision=${{ inputs.revision }} -Dgpg.skip=true -Prelease,ci clean deploy
run: mvn
--batch-mode
--update-snapshots
--file pom.xml
-Drevision=${{ inputs.revision }}
-Dgpg.skip=true
deploy
--activate-profiles release,ci
env:
MAVEN_USERNAME: ${{ secrets.OSS_SONATYPE_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSS_SONATYPE_PASSWORD }}
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
# microsphere-spring
Microsphere Projects for Spring
> Microsphere Projects for Spring
[![Maven Build](https://github.com/microsphere-projects/microsphere-spring/actions/workflows/maven-build.yml/badge.svg)](https://github.com/microsphere-projects/microsphere-spring/actions/workflows/maven-build.yml)
[![Codecov](https://codecov.io/gh/microsphere-projects/microsphere-spring/branch/dev-1.x/graph/badge.svg)](https://app.codecov.io/gh/microsphere-projects/microsphere-spring)
![Maven](https://img.shields.io/maven-central/v/io.github.microsphere-projects/microsphere-spring.svg)
![License](https://img.shields.io/github/license/microsphere-projects/microsphere-spring.svg)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/microsphere-projects/microsphere-spring.svg)](http://isitmaintained.com/project/microsphere-projects/microsphere-spring "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/microsphere-projects/microsphere-spring.svg)](http://isitmaintained.com/project/microsphere-projects/microsphere-spring "Percentage of issues still open")
45 changes: 45 additions & 0 deletions microsphere-spring-compatible/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?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">
<parent>
<groupId>io.github.microsphere-projects</groupId>
<artifactId>microsphere-spring-parent</artifactId>
<version>${revision}</version>
<relativePath>../microsphere-spring-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>io.github.microsphere-projects</groupId>
<artifactId>microsphere-spring-compatible</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>

<name>Microsphere :: Spring :: Compatible</name>
<description>Microsphere Spring Compatible</description>

<dependencies>

<!-- JSR 305 -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<optional>true</optional>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.core.env;

import java.util.function.Predicate;

/**
* Profile predicate that may be {@linkplain Environment#acceptsProfiles(Profiles)
* accepted} by an {@link Environment}.
*
* <p>May be implemented directly or, more usually, created using the
* {@link #of(String...) of(...)} factory method.
*
* @author Phillip Webb
* @author Sam Brannen
* @since 5.1
*/
@FunctionalInterface
public interface Profiles {

/**
* Test if this {@code Profiles} instance <em>matches</em> against the given
* active profiles predicate.
* @param activeProfiles a predicate that tests whether a given profile is
* currently active
*/
boolean matches(Predicate<String> activeProfiles);


/**
* Create a new {@link Profiles} instance that checks for matches against
* the given <em>profile expressions</em>.
* <p>The returned instance will {@linkplain Profiles#matches(Predicate) match}
* if any one of the given profile expressions matches.
* <p>A profile expression may contain a simple profile name (for example
* {@code "production"}) or a compound expression. A compound expression allows
* for more complicated profile logic to be expressed, for example
* {@code "production & cloud"}.
* <p>The following operators are supported in profile expressions.
* <ul>
* <li>{@code !} - A logical <em>NOT</em> of the profile name or compound expression</li>
* <li>{@code &} - A logical <em>AND</em> of the profile names or compound expressions</li>
* <li>{@code |} - A logical <em>OR</em> of the profile names or compound expressions</li>
* </ul>
* <p>Please note that the {@code &} and {@code |} operators may not be mixed
* without using parentheses. For example, {@code "a & b | c"} is not a valid
* expression: it must be expressed as {@code "(a & b) | c"} or
* {@code "a & (b | c)"}.
* <p>As of Spring Framework 5.1.17, two {@code Profiles} instances returned
* by this method are considered equivalent to each other (in terms of
* {@code equals()} and {@code hashCode()} semantics) if they are created
* with identical <em>profile expressions</em>.
* @param profileExpressions the <em>profile expressions</em> to include
* @return a new {@link Profiles} instance
*/
static Profiles of(String... profileExpressions) {
return ProfilesParser.parse(profileExpressions);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.core.env;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.function.Predicate;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
* Internal parser used by {@link Profiles#of}.
*
* @author Phillip Webb
* @author Sam Brannen
* @since 5.1
*/
final class ProfilesParser {

private ProfilesParser() {
}


static Profiles parse(String... expressions) {
Assert.notEmpty(expressions, "Must specify at least one profile expression");
Profiles[] parsed = new Profiles[expressions.length];
for (int i = 0; i < expressions.length; i++) {
parsed[i] = parseExpression(expressions[i]);
}
return new ParsedProfiles(expressions, parsed);
}

private static Profiles parseExpression(String expression) {
Assert.hasText(expression, () -> "Invalid profile expression [" + expression + "]: must contain text");
StringTokenizer tokens = new StringTokenizer(expression, "()&|!", true);
return parseTokens(expression, tokens);
}

private static Profiles parseTokens(String expression, StringTokenizer tokens) {
return parseTokens(expression, tokens, Context.NONE);
}

private static Profiles parseTokens(String expression, StringTokenizer tokens, Context context) {
List<Profiles> elements = new ArrayList<>();
Operator operator = null;
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
if (token.isEmpty()) {
continue;
}
switch (token) {
case "(":
Profiles contents = parseTokens(expression, tokens, Context.PARENTHESIS);
if (context == Context.NEGATE) {
return contents;
}
elements.add(contents);
break;
case "&":
assertWellFormed(expression, operator == null || operator == Operator.AND);
operator = Operator.AND;
break;
case "|":
assertWellFormed(expression, operator == null || operator == Operator.OR);
operator = Operator.OR;
break;
case "!":
elements.add(not(parseTokens(expression, tokens, Context.NEGATE)));
break;
case ")":
Profiles merged = merge(expression, elements, operator);
if (context == Context.PARENTHESIS) {
return merged;
}
elements.clear();
elements.add(merged);
operator = null;
break;
default:
Profiles value = equals(token);
if (context == Context.NEGATE) {
return value;
}
elements.add(value);
}
}
return merge(expression, elements, operator);
}

private static Profiles merge(String expression, List<Profiles> elements, @Nullable Operator operator) {
assertWellFormed(expression, !elements.isEmpty());
if (elements.size() == 1) {
return elements.get(0);
}
Profiles[] profiles = elements.toArray(new Profiles[0]);
return (operator == Operator.AND ? and(profiles) : or(profiles));
}

private static void assertWellFormed(String expression, boolean wellFormed) {
Assert.isTrue(wellFormed, () -> "Malformed profile expression [" + expression + "]");
}

private static Profiles or(Profiles... profiles) {
return activeProfile -> Arrays.stream(profiles).anyMatch(isMatch(activeProfile));
}

private static Profiles and(Profiles... profiles) {
return activeProfile -> Arrays.stream(profiles).allMatch(isMatch(activeProfile));
}

private static Profiles not(Profiles profiles) {
return activeProfile -> !profiles.matches(activeProfile);
}

private static Profiles equals(String profile) {
return activeProfile -> activeProfile.test(profile);
}

private static Predicate<Profiles> isMatch(Predicate<String> activeProfiles) {
return profiles -> profiles.matches(activeProfiles);
}


private enum Operator { AND, OR }

private enum Context { NONE, NEGATE, PARENTHESIS }


private static class ParsedProfiles implements Profiles {

private final Set<String> expressions = new LinkedHashSet<>();

private final Profiles[] parsed;

ParsedProfiles(String[] expressions, Profiles[] parsed) {
Collections.addAll(this.expressions, expressions);
this.parsed = parsed;
}

@Override
public boolean matches(Predicate<String> activeProfiles) {
for (Profiles candidate : this.parsed) {
if (candidate.matches(activeProfiles)) {
return true;
}
}
return false;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
ParsedProfiles that = (ParsedProfiles) obj;
return this.expressions.equals(that.expressions);
}

@Override
public int hashCode() {
return this.expressions.hashCode();
}

@Override
public String toString() {
return StringUtils.collectionToDelimitedString(this.expressions, " or ");
}
}

}
Loading

0 comments on commit 1960355

Please sign in to comment.