Skip to content

Commit 45419fd

Browse files
committed
Initial commit
0 parents  commit 45419fd

27 files changed

+1306
-0
lines changed

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/
8+
*.iws
9+
*.iml
10+
*.ipr
11+
12+
### Eclipse ###
13+
.apt_generated
14+
.classpath
15+
.factorypath
16+
.project
17+
.settings
18+
.springBeans
19+
.sts4-cache
20+
21+
### NetBeans ###
22+
/nbproject/private/
23+
/nbbuild/
24+
/dist/
25+
/nbdist/
26+
/.nb-gradle/
27+
build/
28+
!**/src/main/**/build/
29+
!**/src/test/**/build/
30+
31+
### VS Code ###
32+
.vscode/
33+
34+
### Mac OS ###
35+
.DS_Store

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# RegexSolver Java API Client
2+
3+
This repository contains the source code of the Java library for [RegexSolver](https://regexsolver.com) API.
4+
5+
RegexSolver is a powerful regular expression manipulation toolkit, that gives you the power to manipulate regex as if
6+
they were sets.

pom.xml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.regexsolver.api</groupId>
8+
<artifactId>RegexSolver</artifactId>
9+
<version>1.0.0</version>
10+
11+
<url>https://regexsolver.com</url>
12+
<organization>
13+
<name>RegexSolver</name>
14+
<url>https://regexsolver.com</url>
15+
</organization>
16+
<scm>
17+
<url>https://github.com/RegexSolver/regexsolver-java</url>
18+
</scm>
19+
<description>
20+
RegexSolver allows you to manipulate regular expressions as sets, enabling operations such as intersection,
21+
union, and subtraction.
22+
</description>
23+
24+
<properties>
25+
<maven.compiler.source>11</maven.compiler.source>
26+
<maven.compiler.target>11</maven.compiler.target>
27+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
28+
</properties>
29+
30+
<dependencies>
31+
<dependency>
32+
<groupId>com.squareup.retrofit2</groupId>
33+
<artifactId>retrofit</artifactId>
34+
<version>2.11.0</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.squareup.retrofit2</groupId>
38+
<artifactId>converter-jackson</artifactId>
39+
<version>2.11.0</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>junit</groupId>
43+
<artifactId>junit</artifactId>
44+
<version>4.13.2</version>
45+
<scope>test</scope>
46+
</dependency>
47+
<dependency>
48+
<groupId>com.squareup.okhttp3</groupId>
49+
<artifactId>mockwebserver</artifactId>
50+
<version>3.14.9</version>
51+
<scope>test</scope>
52+
</dependency>
53+
</dependencies>
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>org.apache.maven.plugins</groupId>
58+
<artifactId>maven-javadoc-plugin</artifactId>
59+
<version>3.7.0</version>
60+
<configuration>
61+
<sourceFileExcludes>
62+
<sourceFileExclude>**/ResponseContent.java</sourceFileExclude>
63+
</sourceFileExcludes>
64+
</configuration>
65+
<executions>
66+
<execution>
67+
<goals>
68+
<goal>javadoc</goal>
69+
</goals>
70+
</execution>
71+
</executions>
72+
</plugin>
73+
</plugins>
74+
</build>
75+
</project>
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package com.regexsolver.api;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.regexsolver.api.Request.GenerateStringsRequest;
5+
import com.regexsolver.api.Request.MultiTermsRequest;
6+
import com.regexsolver.api.Response.BooleanResponse;
7+
import com.regexsolver.api.Response.StringsResponse;
8+
import com.regexsolver.api.dto.Details;
9+
import com.regexsolver.api.exception.ApiError;
10+
import com.regexsolver.api.exception.MissingAPITokenException;
11+
import okhttp3.OkHttpClient;
12+
import okhttp3.Request;
13+
import okhttp3.ResponseBody;
14+
import retrofit2.Call;
15+
import retrofit2.Response;
16+
import retrofit2.Retrofit;
17+
import retrofit2.converter.jackson.JacksonConverterFactory;
18+
import retrofit2.http.Body;
19+
import retrofit2.http.POST;
20+
21+
import java.io.IOException;
22+
import java.util.List;
23+
import java.util.Objects;
24+
25+
final class RegexSolverApiWrapper {
26+
private static final RegexSolverApiWrapper INSTANCE = new RegexSolverApiWrapper();
27+
28+
private final static String DEFAULT_BASE_URL = "https://api.regexsolver.com/";
29+
30+
private final static String USER_AGENT = "RegexSolver Java / 1.0.0";
31+
32+
private RegexApi api;
33+
34+
public static RegexSolverApiWrapper getInstance() {
35+
return INSTANCE;
36+
}
37+
38+
private RegexSolverApiWrapper() {
39+
initializeInternal(null, DEFAULT_BASE_URL);
40+
}
41+
42+
public static void initialize(String token) {
43+
getInstance().initializeInternal(token, DEFAULT_BASE_URL);
44+
}
45+
46+
public static void initialize(String token, String baseUrl) {
47+
getInstance().initializeInternal(token, baseUrl);
48+
}
49+
50+
private void initializeInternal(String token, String baseUrl) {
51+
Retrofit retrofit = new Retrofit.Builder()
52+
.client(new OkHttpClient.Builder().addInterceptor(chain -> {
53+
if (token == null) {
54+
throw new MissingAPITokenException();
55+
}
56+
Request newRequest = chain.request().newBuilder()
57+
.addHeader("User-Agent", USER_AGENT)
58+
.addHeader("Authorization", "Bearer " + token)
59+
.build();
60+
return chain.proceed(newRequest);
61+
}).build())
62+
.baseUrl(baseUrl)
63+
.addConverterFactory(JacksonConverterFactory.create())
64+
.build();
65+
66+
api = retrofit.create(RegexApi.class);
67+
}
68+
69+
public Term computeIntersection(MultiTermsRequest multiTermsRequest) throws ApiError, IOException {
70+
Response<Term> response = api.computeIntersection(multiTermsRequest).execute();
71+
if (response.isSuccessful()) {
72+
return response.body();
73+
} else {
74+
throw getApiError(response);
75+
}
76+
}
77+
78+
public Term computeUnion(MultiTermsRequest multiTermsRequest) throws ApiError, IOException {
79+
Response<Term> response = api.computeUnion(multiTermsRequest).execute();
80+
if (response.isSuccessful()) {
81+
return response.body();
82+
} else {
83+
throw getApiError(response);
84+
}
85+
}
86+
87+
public Term computeSubtraction(MultiTermsRequest multiTermsRequest) throws ApiError, IOException {
88+
Response<Term> response = api.computeSubtraction(multiTermsRequest).execute();
89+
if (response.isSuccessful()) {
90+
return response.body();
91+
} else {
92+
throw getApiError(response);
93+
}
94+
}
95+
96+
public Details getDetails(Term term) throws ApiError, IOException {
97+
Response<Details> response = api.getDetails(term).execute();
98+
if (response.isSuccessful()) {
99+
return response.body();
100+
} else {
101+
throw getApiError(response);
102+
}
103+
}
104+
105+
public boolean equivalence(MultiTermsRequest multiTermsRequest) throws ApiError, IOException {
106+
Response<BooleanResponse> response = api.equivalence(multiTermsRequest).execute();
107+
if (response.isSuccessful()) {
108+
return response.body().value();
109+
} else {
110+
throw getApiError(response);
111+
}
112+
}
113+
114+
public boolean subset(MultiTermsRequest multiTermsRequest) throws ApiError, IOException {
115+
Response<BooleanResponse> response = api.subset(multiTermsRequest).execute();
116+
if (response.isSuccessful()) {
117+
return response.body().value();
118+
} else {
119+
throw getApiError(response);
120+
}
121+
}
122+
123+
public List<String> generateStrings(Term term, int count) throws ApiError, IOException {
124+
GenerateStringsRequest generateStringsRequest = new GenerateStringsRequest(term, count);
125+
Response<StringsResponse> response = api.generateStrings(generateStringsRequest).execute();
126+
if (response.isSuccessful()) {
127+
return response.body().value();
128+
} else {
129+
throw getApiError(response);
130+
}
131+
}
132+
133+
private static <T> ApiError getApiError(Response<T> response) throws IOException {
134+
assert !response.isSuccessful();
135+
try (ResponseBody errorBody = response.errorBody()) {
136+
String json = Objects.requireNonNull(errorBody).string();
137+
ObjectMapper mapper = new ObjectMapper();
138+
return mapper.readValue(json, ApiError.class);
139+
}
140+
}
141+
142+
private interface RegexApi {
143+
@POST("api/compute/intersection")
144+
Call<Term> computeIntersection(@Body MultiTermsRequest multiTermsRequest);
145+
146+
@POST("api/compute/union")
147+
Call<Term> computeUnion(@Body MultiTermsRequest multiTermsRequest);
148+
149+
@POST("api/compute/subtraction")
150+
Call<Term> computeSubtraction(@Body MultiTermsRequest multiTermsRequest);
151+
152+
@POST("api/analyze/details")
153+
Call<Details> getDetails(@Body Term term);
154+
155+
@POST("api/analyze/equivalence")
156+
Call<BooleanResponse> equivalence(@Body MultiTermsRequest multiTermsRequest);
157+
158+
@POST("api/analyze/subset")
159+
Call<BooleanResponse> subset(@Body MultiTermsRequest multiTermsRequest);
160+
161+
@POST("api/generate/strings")
162+
Call<StringsResponse> generateStrings(@Body GenerateStringsRequest request);
163+
}
164+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.regexsolver.api;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import java.util.List;
6+
7+
final class Request {
8+
9+
public static final class MultiTermsRequest {
10+
private final List<Term> terms;
11+
12+
public MultiTermsRequest(@JsonProperty("terms") List<Term> terms) {
13+
this.terms = terms;
14+
}
15+
16+
public List<Term> getTerms() {
17+
return terms;
18+
}
19+
}
20+
21+
public static final class GenerateStringsRequest {
22+
private final Term term;
23+
private final int count;
24+
25+
public GenerateStringsRequest(
26+
@JsonProperty("term") Term term,
27+
@JsonProperty("count") int count
28+
) {
29+
this.term = term;
30+
this.count = count;
31+
}
32+
33+
public Term getTerm() {
34+
return term;
35+
}
36+
37+
public int getCount() {
38+
return count;
39+
}
40+
}
41+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.regexsolver.api;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import java.util.List;
6+
7+
final class Response {
8+
public static final class BooleanResponse implements ResponseContent {
9+
private final boolean value;
10+
11+
public BooleanResponse(@JsonProperty("value") boolean value) {
12+
this.value = value;
13+
}
14+
15+
public boolean value() {
16+
return value;
17+
}
18+
}
19+
20+
public static final class StringsResponse implements ResponseContent {
21+
private final List<String> value;
22+
23+
public StringsResponse(@JsonProperty("value") List<String> value) {
24+
this.value = value;
25+
}
26+
27+
public List<String> value() {
28+
return value;
29+
}
30+
}
31+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.regexsolver.api;
2+
3+
import com.fasterxml.jackson.annotation.JsonSubTypes;
4+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
5+
import com.regexsolver.api.Response.BooleanResponse;
6+
import com.regexsolver.api.Response.StringsResponse;
7+
import com.regexsolver.api.dto.Details;
8+
9+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
10+
@JsonSubTypes({
11+
@JsonSubTypes.Type(value = Term.Fair.class, name = "fair"),
12+
@JsonSubTypes.Type(value = Term.Regex.class, name = "regex"),
13+
@JsonSubTypes.Type(value = Details.class, name = "details"),
14+
@JsonSubTypes.Type(value = StringsResponse.class, name = "strings"),
15+
@JsonSubTypes.Type(value = BooleanResponse.class, name = "boolean"),
16+
})
17+
public interface ResponseContent {
18+
}

0 commit comments

Comments
 (0)