Skip to content
This repository was archived by the owner on Jul 31, 2022. It is now read-only.

Commit 344e971

Browse files
authored
Merge pull request #78 from Ktt-Development/uniform-contexts@2a0e22f
Optimize Context Creation
2 parents 2a0e22f + a7c8c93 commit 344e971

File tree

7 files changed

+185
-115
lines changed

7 files changed

+185
-115
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.kttdevelopment</groupId>
88
<artifactId>simplehttpserver</artifactId>
9-
<version>03.05.02</version>
9+
<version>03.05.03</version>
1010
<packaging>jar</packaging>
1111

1212
<url>https://github.com/Ktt-Development/simplehttpserver</url>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.kttdevelopment.simplehttpserver;
2+
3+
/**
4+
* A utility class used to generate uniform contexts. Applications do not use this class.
5+
*
6+
* @since 03.05.03
7+
* @version 03.05.03
8+
* @author Ktt Development
9+
*/
10+
public abstract class ContextUtil {
11+
12+
13+
/**
14+
* Generates a uniform context with forward slashes removing any consecutive slashes.
15+
*
16+
* @param context context
17+
* @param leadingSlash if context should have a leading slash
18+
* @param trailingSlash if context should have a trailing slash
19+
* @return context with uniform slashes
20+
*
21+
* @see #joinContexts(boolean, boolean, String...)
22+
* @since 03.05.03
23+
* @author Ktt Development
24+
*/
25+
public static String getContext(final String context, final boolean leadingSlash, final boolean trailingSlash){
26+
final String linSlash = context.replace('\\','/').replaceAll("/{2,}","/");
27+
if(linSlash.isBlank() || linSlash.equals("/")) // handle blank or '/' contexts
28+
return leadingSlash || trailingSlash ? "/" : "";
29+
final String ltSlash = (!(linSlash.charAt(0) == '/') ? '/' : "") + linSlash + (!(linSlash.charAt(linSlash.length()-1) == '/') ? '/' : "");
30+
return ltSlash.substring(leadingSlash ? 0 : 1,ltSlash.length() + (trailingSlash ? 0 : -1));
31+
}
32+
33+
/**
34+
* Generates a uniform context given a set of strings using forward slashes and removing consecutive slashes.
35+
*
36+
* @param leadingSlash if context should have a leading slash
37+
* @param trailingSlash if context should have a trailing slash
38+
* @param contexts contexts to join
39+
* @return context with uniform slashes
40+
*
41+
* @see #getContext(String, boolean, boolean)
42+
* @since 03.05.03
43+
* @author Ktt Development
44+
*/
45+
public static String joinContexts(final boolean leadingSlash, final boolean trailingSlash, final String... contexts){
46+
final StringBuilder OUT = new StringBuilder();
47+
48+
for(final String context : contexts)
49+
OUT.append(getContext(context, true, false));
50+
51+
return getContext(OUT.toString(),leadingSlash,trailingSlash);
52+
}
53+
54+
}

src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpServerImpl.java

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* @see SimpleHttpServer
1515
* @since 02.00.00
16-
* @version 03.05.02
16+
* @version 03.05.03
1717
* @author Ktt Development
1818
*/
1919
@SuppressWarnings("SpellCheckingInspection")
@@ -61,7 +61,7 @@ public final HttpServer getHttpServer(){
6161
return server;
6262
}
6363

64-
//
64+
// region copy
6565

6666
@Override
6767
public synchronized final InetSocketAddress bind(final int port) throws IOException{
@@ -129,54 +129,54 @@ public final HttpSession getHttpSession(final SimpleHttpExchange exchange){
129129
//
130130

131131
@Override
132-
public synchronized final HttpContext createContext(final String path){
133-
return createContext(path,HttpExchange::close,null);
132+
public synchronized final HttpContext createContext(final String context){
133+
return createContext(context,HttpExchange::close,null);
134134
}
135135

136136
@Override
137-
public synchronized final HttpContext createContext(final String path, final HttpHandler handler){
138-
return createContext(path,handler,null);
137+
public synchronized final HttpContext createContext(final String context, final HttpHandler handler){
138+
return createContext(context,handler,null);
139139
}
140140

141141
//
142142

143143
@Override
144-
public synchronized final HttpContext createContext(final String path, final Authenticator authenticator){
145-
return createContext(path,HttpExchange::close,authenticator);
144+
public synchronized final HttpContext createContext(final String context, final Authenticator authenticator){
145+
return createContext(context,HttpExchange::close,authenticator);
146146
}
147147

148148
@Override
149-
public synchronized final HttpContext createContext(final String path, final HttpHandler handler, final Authenticator authenticator){
150-
if(!getContext(path).equals("/") && handler instanceof RootHandler)
149+
public synchronized final HttpContext createContext(final String context, final HttpHandler handler, final Authenticator authenticator){
150+
if(!ContextUtil.getContext(context,true,false).equals("/") && handler instanceof RootHandler)
151151
throw new IllegalArgumentException("RootHandler can only be used at the root '/' context");
152152

153153
final HttpHandler wrapper = exchange -> {
154154
handle(exchange);
155155
handler.handle(exchange);
156156
};
157157

158-
final HttpContext context = server.createContext(getContext(path),wrapper);
159-
contexts.put(context,handler);
158+
final HttpContext hc = server.createContext(ContextUtil.getContext(context,true,false),wrapper);
159+
contexts.put(hc,handler);
160160

161161
if(authenticator != null)
162-
context.setAuthenticator(authenticator);
162+
hc.setAuthenticator(authenticator);
163163

164-
return context;
164+
return hc;
165165
}
166166

167167
//
168168

169169
@SuppressWarnings("CaughtExceptionImmediatelyRethrown")
170170
@Override
171-
public synchronized final void removeContext(final String path){
171+
public synchronized final void removeContext(final String context){
172172
try{
173-
server.removeContext(getContext(path));
173+
server.removeContext(ContextUtil.getContext(context,true,false));
174174
}catch(final IllegalArgumentException e){
175175
throw e;
176176
}finally{
177-
for(final HttpContext context : contexts.keySet()){
178-
if(context.getPath().equalsIgnoreCase(getContext(path))){
179-
contexts.remove(context);
177+
for(final HttpContext hc : contexts.keySet()){
178+
if(hc.getPath().equalsIgnoreCase(ContextUtil.getContext(context,true,false))){
179+
contexts.remove(hc);
180180
break;
181181
}
182182
}
@@ -192,9 +192,9 @@ public synchronized final void removeContext(final HttpContext context){
192192
//
193193

194194
@Override
195-
public final HttpHandler getContextHandler(final String path){
195+
public final HttpHandler getContextHandler(final String context){
196196
for(final Map.Entry<HttpContext, HttpHandler> entry : contexts.entrySet())
197-
if(entry.getKey().getPath().equals(getContext(path)))
197+
if(entry.getKey().getPath().equals(ContextUtil.getContext(context,true,false)))
198198
return entry.getValue();
199199
return null;
200200
}
@@ -220,9 +220,9 @@ public synchronized final String getRandomContext(){
220220
public synchronized final String getRandomContext(final String context){
221221
String targetContext;
222222

223-
final String head = context.isEmpty() ? "" : getContext(context);
223+
final String head = context.isEmpty() ? "" : ContextUtil.getContext(context,true,false);
224224

225-
do targetContext = head + getContext(UUID.randomUUID().toString());
225+
do targetContext = head + ContextUtil.getContext(UUID.randomUUID().toString(),true,false);
226226
while(getContextHandler(targetContext) != null);
227227

228228
return targetContext;
@@ -252,7 +252,7 @@ public synchronized final void stop(final int delay){
252252
}
253253
}
254254

255-
//
255+
// endregion copy
256256

257257
@Override
258258
public String toString(){
@@ -264,12 +264,4 @@ public String toString(){
264264
"executor" + '=' + getExecutor() +
265265
'}';
266266
}
267-
268-
// start slash; no end slash
269-
private static String getContext(final String path){
270-
final String linSlash = path.replace("\\","/");
271-
if(linSlash.equals("/")) return "/";
272-
final String seSlash = (!linSlash.startsWith("/") ? "/" : "") + linSlash + (!linSlash.endsWith("/") ? "/" : "");
273-
return seSlash.substring(0,seSlash.length()-1);
274-
}
275267
}

src/main/java/com/kttdevelopment/simplehttpserver/SimpleHttpsServerImpl.java

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
*
1414
* @see SimpleHttpsServer
1515
* @since 03.04.00
16-
* @version 03.05.00
16+
* @version 03.05.03
1717
* @author Ktt Development
1818
*/
19+
@SuppressWarnings("SpellCheckingInspection")
1920
final class SimpleHttpsServerImpl extends SimpleHttpsServer {
2021

2122
private final HttpsServer server = HttpsServer.create();
@@ -74,29 +75,25 @@ public final HttpsConfigurator getHttpsConfigurator(){
7475

7576
// region copySimpleHttpServerImpl
7677

77-
@SuppressWarnings("SpellCheckingInspection")
7878
@Override
7979
public synchronized final InetSocketAddress bind(final int port) throws IOException{
8080
final InetSocketAddress addr = new InetSocketAddress(port);
8181
server.bind(addr, 0);
8282
return addr;
8383
}
8484

85-
@SuppressWarnings("SpellCheckingInspection")
8685
@Override
8786
public synchronized final InetSocketAddress bind(final int port, final int backlog) throws IOException{
8887
final InetSocketAddress addr = new InetSocketAddress(port);
8988
server.bind(addr, backlog);
9089
return addr;
9190
}
9291

93-
@SuppressWarnings("SpellCheckingInspection")
9492
@Override
9593
public synchronized final void bind(final InetSocketAddress addr) throws IOException{
9694
server.bind(addr,0);
9795
}
9896

99-
@SuppressWarnings("SpellCheckingInspection")
10097
@Override
10198
public synchronized final void bind(final InetSocketAddress addr, final int backlog) throws IOException{
10299
server.bind(addr,backlog);
@@ -143,51 +140,57 @@ public final HttpSession getHttpSession(final SimpleHttpExchange exchange){
143140

144141
//
145142

146-
@Override
147-
public synchronized final HttpContext createContext(final String path){
148-
return createContext(path,HttpExchange::close,null);
143+
@Override
144+
public synchronized final HttpContext createContext(final String context){
145+
return createContext(context,HttpExchange::close,null);
149146
}
150147

151148
@Override
152-
public synchronized final HttpContext createContext(final String path, final HttpHandler handler){
153-
return createContext(path,handler,null);
149+
public synchronized final HttpContext createContext(final String context, final HttpHandler handler){
150+
return createContext(context,handler,null);
154151
}
155152

156153
//
157154

158155
@Override
159-
public synchronized final HttpContext createContext(final String path, final Authenticator authenticator){
160-
return createContext(path,HttpExchange::close,authenticator);
156+
public synchronized final HttpContext createContext(final String context, final Authenticator authenticator){
157+
return createContext(context,HttpExchange::close,authenticator);
161158
}
162159

163160
@Override
164-
public synchronized final HttpContext createContext(final String path, final HttpHandler handler, final Authenticator authenticator){
165-
if(!getContext(path).equals("/") && handler instanceof RootHandler)
161+
public synchronized final HttpContext createContext(final String context, final HttpHandler handler, final Authenticator authenticator){
162+
if(!ContextUtil.getContext(context,true,false).equals("/") && handler instanceof RootHandler)
166163
throw new IllegalArgumentException("RootHandler can only be used at the root '/' context");
167164

168165
final HttpHandler wrapper = exchange -> {
169166
handle(exchange);
170167
handler.handle(exchange);
171168
};
172169

173-
final HttpContext context = server.createContext(getContext(path),wrapper);
174-
contexts.put(context,handler);
170+
final HttpContext hc = server.createContext(ContextUtil.getContext(context,true,false),wrapper);
171+
contexts.put(hc,handler);
175172

176173
if(authenticator != null)
177-
context.setAuthenticator(authenticator);
174+
hc.setAuthenticator(authenticator);
178175

179-
return context;
176+
return hc;
180177
}
181178

182179
//
183180

181+
@SuppressWarnings("CaughtExceptionImmediatelyRethrown")
184182
@Override
185-
public synchronized final void removeContext(final String path){
186-
server.removeContext(getContext(path));
187-
for(final HttpContext context : contexts.keySet()){
188-
if(context.getPath().equalsIgnoreCase(getContext(path))){
189-
contexts.remove(context);
190-
break;
183+
public synchronized final void removeContext(final String context){
184+
try{
185+
server.removeContext(ContextUtil.getContext(context,true,false));
186+
}catch(final IllegalArgumentException e){
187+
throw e;
188+
}finally{
189+
for(final HttpContext hc : contexts.keySet()){
190+
if(hc.getPath().equalsIgnoreCase(ContextUtil.getContext(context,true,false))){
191+
contexts.remove(hc);
192+
break;
193+
}
191194
}
192195
}
193196
}
@@ -201,9 +204,9 @@ public synchronized final void removeContext(final HttpContext context){
201204
//
202205

203206
@Override
204-
public final HttpHandler getContextHandler(final String path){
207+
public final HttpHandler getContextHandler(final String context){
205208
for(final Map.Entry<HttpContext, HttpHandler> entry : contexts.entrySet())
206-
if(entry.getKey().getPath().equals(getContext(path)))
209+
if(entry.getKey().getPath().equals(ContextUtil.getContext(context,true,false)))
207210
return entry.getValue();
208211
return null;
209212
}
@@ -229,9 +232,9 @@ public synchronized final String getRandomContext(){
229232
public synchronized final String getRandomContext(final String context){
230233
String targetContext;
231234

232-
final String head = context.isEmpty() ? "" : getContext(context);
235+
final String head = context.isEmpty() ? "" : ContextUtil.getContext(context,true,false);
233236

234-
do targetContext = head + getContext(UUID.randomUUID().toString());
237+
do targetContext = head + ContextUtil.getContext(UUID.randomUUID().toString(),true,false);
235238
while(getContextHandler(targetContext) != null);
236239

237240
return targetContext;
@@ -275,12 +278,4 @@ public String toString(){
275278
'}';
276279
}
277280

278-
// start slash; no end slash
279-
private static String getContext(final String path){
280-
final String linSlash = path.replace("\\","/");
281-
if(linSlash.equals("/")) return "/";
282-
final String seSlash = (!linSlash.startsWith("/") ? "/" : "") + linSlash + (!linSlash.endsWith("/") ? "/" : "");
283-
return seSlash.substring(0,seSlash.length()-1);
284-
}
285-
286281
}

0 commit comments

Comments
 (0)