-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'release-5u18' into master
# Conflicts: # pom.xml
- Loading branch information
Showing
35 changed files
with
1,793 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
src/main/java/nablarch/integration/router/PathOptions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package nablarch.integration.router; | ||
|
||
import net.unit8.http.router.Options; | ||
|
||
/** | ||
* パスと、それに割り当てられている {@link Options} のセット。 | ||
* | ||
* @author Tanaka Tomoyuki | ||
*/ | ||
public class PathOptions { | ||
private final String path; | ||
private final Options options; | ||
|
||
/** | ||
* コンストラクタ。 | ||
* @param path パス | ||
* @param options パスに割り当てられた設定 | ||
*/ | ||
public PathOptions(String path, Options options) { | ||
this.path = path; | ||
this.options = options; | ||
} | ||
|
||
/** | ||
* パスを取得する。 | ||
* @return パス | ||
*/ | ||
public String getPath() { | ||
return path; | ||
} | ||
|
||
/** | ||
* 設定を取得する | ||
* @return 設定 | ||
*/ | ||
public Options getOptions() { | ||
return options; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/nablarch/integration/router/PathOptionsFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package nablarch.integration.router; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* ログに出力するために {@link PathOptions} をフォーマットする機能を提供するインターフェース。 | ||
* | ||
* @author Tanaka Tomoyuki | ||
*/ | ||
public interface PathOptionsFormatter { | ||
|
||
/** | ||
* {@link PathOptions} のリストをログ出力用にフォーマットする。 | ||
* @param pathOptionsList フォーマット対象の {@link PathOptions} のリスト | ||
* @return フォーマット結果 | ||
*/ | ||
String format(List<PathOptions> pathOptionsList); | ||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/nablarch/integration/router/PathOptionsProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package nablarch.integration.router; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* ルーティング定義を収集する機能を提供するインターフェース。 | ||
* | ||
* @author Tanaka Tomoyuki | ||
*/ | ||
public interface PathOptionsProvider { | ||
|
||
/** | ||
* ルーティング定義を収集する。 | ||
* @return ルーティング定義のリスト | ||
*/ | ||
List<PathOptions> provide(); | ||
} |
117 changes: 117 additions & 0 deletions
117
src/main/java/nablarch/integration/router/PathOptionsProviderRoutesMapping.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package nablarch.integration.router; | ||
|
||
import nablarch.core.log.Logger; | ||
import nablarch.core.log.LoggerManager; | ||
import nablarch.core.repository.initialization.Initializable; | ||
import nablarch.fw.ExecutionContext; | ||
import nablarch.fw.web.HttpErrorResponse; | ||
import nablarch.fw.web.HttpRequest; | ||
import nablarch.fw.web.HttpResponse; | ||
import nablarch.fw.web.handler.RoutingHandlerSupport; | ||
import nablarch.fw.web.servlet.ServletExecutionContext; | ||
import net.unit8.http.router.ARStringUtil; | ||
import net.unit8.http.router.Options; | ||
import net.unit8.http.router.RouteSet; | ||
import net.unit8.http.router.RoutingException; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* {@link PathOptionsProvider} から取得したルーティング定義をベースにActionメソッドを特定するハンドラ。 | ||
* | ||
* @author Tanaka Tomoyuki | ||
*/ | ||
public class PathOptionsProviderRoutesMapping extends RoutingHandlerSupport implements Initializable { | ||
private static final Logger LOGGER = LoggerManager.get(PathOptionsProviderRoutesMapping.class); | ||
|
||
private final RouteSet routeSet = new RouteSet(); | ||
private String baseUri = ""; | ||
private PathOptionsProvider pathOptionsProvider; | ||
private PathOptionsFormatter pathOptionsFormatter = new SimplePathOptionsFormatter(); | ||
|
||
@Override | ||
protected Class<?> getHandlerClass(HttpRequest request, ExecutionContext executionContext) throws ClassNotFoundException { | ||
try { | ||
String path = getPath(request, executionContext); | ||
Options options = routeSet.recognizePath(path, request.getMethod()); | ||
|
||
executionContext.setMethodBinder(methodBinderFactory.create((String) options.get("action"))); | ||
|
||
Options params = options.except("controller", "action"); | ||
for (Map.Entry<String, Object> option : params.entrySet()) { | ||
if (option.getValue() != null) { | ||
request.setParam(option.getKey(), option.getValue().toString()); | ||
} | ||
} | ||
|
||
return Thread.currentThread().getContextClassLoader().loadClass((String) options.get("controller")); | ||
} catch (RoutingException e) { | ||
throw new HttpErrorResponse(HttpResponse.Status.NOT_FOUND.getStatusCode(), e); | ||
} | ||
} | ||
|
||
private String getPath(HttpRequest request, ExecutionContext executionContext) { | ||
String path; | ||
if (executionContext instanceof ServletExecutionContext) { | ||
path = ((ServletExecutionContext) executionContext).getHttpRequest().getRequestPath(); | ||
} else { | ||
path = request.getRequestPath(); | ||
} | ||
String normalized = ARStringUtil.removeStart(path, getBaseUri()); | ||
return normalized.startsWith("/") ? normalized : "/" + normalized; | ||
} | ||
|
||
@Override | ||
public void initialize() { | ||
if (pathOptionsProvider == null) { | ||
throw new IllegalStateException("pathOptionsProvider is not set."); | ||
} | ||
|
||
List<PathOptions> pathOptionsList = pathOptionsProvider.provide(); | ||
|
||
for (PathOptions pathOptions : pathOptionsList) { | ||
routeSet.addRoute(pathOptions.getPath() , pathOptions.getOptions()); | ||
} | ||
|
||
if (methodBinderFactory == null) { | ||
setMethodBinderFactory(new RoutesMethodBinderFactory()); | ||
} | ||
|
||
if (LOGGER.isDebugEnabled()) { | ||
LOGGER.logDebug(pathOptionsFormatter.format(pathOptionsList)); | ||
} | ||
} | ||
|
||
/** | ||
* ベースURIを取得する。 | ||
* @return ベースURI | ||
*/ | ||
public String getBaseUri() { | ||
return baseUri; | ||
} | ||
|
||
/** | ||
* ベースURIを設定する。 | ||
* @param baseUri ベースURI | ||
*/ | ||
public void setBaseUri(String baseUri) { | ||
this.baseUri = baseUri; | ||
} | ||
|
||
/** | ||
* {@link PathOptionsProvider} を設定する。 | ||
* @param pathOptionsProvider {@link PathOptionsProvider} | ||
*/ | ||
public void setPathOptionsProvider(PathOptionsProvider pathOptionsProvider) { | ||
this.pathOptionsProvider = pathOptionsProvider; | ||
} | ||
|
||
/** | ||
* {@link PathOptionsFormatter} を設定する。 | ||
* @param pathOptionsFormatter {@link PathOptionsFormatter} | ||
*/ | ||
public void setPathOptionsFormatter(PathOptionsFormatter pathOptionsFormatter) { | ||
this.pathOptionsFormatter = pathOptionsFormatter; | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/nablarch/integration/router/SimplePathOptionsFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package nablarch.integration.router; | ||
|
||
import nablarch.core.util.StringUtil; | ||
import net.unit8.http.router.Options; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.SortedMap; | ||
import java.util.TreeMap; | ||
|
||
/** | ||
* {@link PathOptions} を単純な形式でフォーマットする機能を提供するクラス。 | ||
* <p> | ||
* このフォーマッタは、まず {@link PathOptions} のリストを {@code path} とHTTPメソッド({@code options.conditions.method})の昇順でソートする。<br> | ||
* そして、それぞれの {@link PathOptions} を {@code "<options.conditions.method> <path> => <options.controller>#<options.action>"} | ||
* という書式でフォーマットし、改行コード({@code System.getProperty("line.separator")})で連結したものをフォーマット結果として返す。<br> | ||
* </p> | ||
* | ||
* @author Tanaka Tomoyuki | ||
*/ | ||
public class SimplePathOptionsFormatter implements PathOptionsFormatter { | ||
|
||
@Override | ||
public String format(List<PathOptions> pathOptionsList) { | ||
SortedMap<String, PathOptions> sortedByPathAndHttpMethod = new TreeMap<String, PathOptions>(); | ||
|
||
for (PathOptions pathOptions : pathOptionsList) { | ||
Options condition = (Options)pathOptions.getOptions().get("conditions"); | ||
sortedByPathAndHttpMethod.put(pathOptions.getPath() + " " + condition.get("method"), pathOptions); | ||
} | ||
|
||
List<String> logStringList = new ArrayList<String>(pathOptionsList.size()); | ||
for (PathOptions pathOptions : sortedByPathAndHttpMethod.values()) { | ||
logStringList.add(format(pathOptions)); | ||
} | ||
|
||
return StringUtil.join(System.getProperty("line.separator"), logStringList); | ||
} | ||
|
||
private String format(PathOptions pathOptions) { | ||
Options options = pathOptions.getOptions(); | ||
Options conditions = (Options) options.get("conditions"); | ||
return String.format("%s %s => %s#%s", conditions.get("method"), pathOptions.getPath(), options.get("controller"), options.get("action")); | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
src/main/java/nablarch/integration/router/jaxrs/JaxRsPathOptionsProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package nablarch.integration.router.jaxrs; | ||
|
||
import nablarch.integration.router.PathOptionsProvider; | ||
import nablarch.integration.router.PathOptions; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
|
||
/** | ||
* {@link javax.ws.rs.Path} アノテーションが設定されたクラスを探索してルーティング定義を収集するクラス。 | ||
* | ||
* @author Tanaka Tomoyuki | ||
*/ | ||
public class JaxRsPathOptionsProvider implements PathOptionsProvider { | ||
private static final Comparator<PathOptions> ORDER_BY_PATH_ASC = new Comparator<PathOptions>() { | ||
@Override | ||
public int compare(PathOptions left, PathOptions right) { | ||
return left.getPath().compareTo(right.getPath()); | ||
} | ||
}; | ||
|
||
private String basePackage; | ||
private String applicationPath; | ||
|
||
@Override | ||
public List<PathOptions> provide() { | ||
if (applicationPath == null) { | ||
throw new IllegalStateException("applicationPath is not set."); | ||
} | ||
if (basePackage == null) { | ||
throw new IllegalStateException("basePackage is not set."); | ||
} | ||
|
||
JaxRsResourceFinder resourceFinder = new JaxRsResourceFinder(); | ||
JaxRsRouterConverter pathStringParser = new JaxRsRouterConverter(applicationPath); | ||
|
||
List<PathOptions> pathOptionsList = new ArrayList<PathOptions>(); | ||
|
||
for (JaxRsResource jaxRsResource : resourceFinder.find(basePackage)) { | ||
pathOptionsList.addAll(pathStringParser.parse(jaxRsResource)); | ||
} | ||
|
||
/* | ||
* http-request-router はルーティング定義のリストを順番に調べて、 | ||
* 最初にマッチした定義を使用するようになっている。 | ||
* | ||
* したがって、以下のような順番でルーティング定義がリストに入っていると、 | ||
* "/foo" へのリクエストが "/foo/(:param)" の定義とマッチしてしまう。 | ||
* | ||
* 1. "/foo/(:param)" | ||
* 2. "/foo" | ||
* | ||
* これを回避するため、定義のリストをパスの昇順でソートしている。 | ||
*/ | ||
Collections.sort(pathOptionsList, ORDER_BY_PATH_ASC); | ||
|
||
return pathOptionsList; | ||
} | ||
|
||
/** | ||
* 検索ルートとなるパッケージを設定する。 | ||
* @param basePackage 検索ルートとなるパッケージ | ||
*/ | ||
public void setBasePackage(String basePackage) { | ||
this.basePackage = basePackage; | ||
} | ||
|
||
/** | ||
* アプリケーションパスを設定する。 | ||
* @param applicationPath アプリケーションパス | ||
*/ | ||
public void setApplicationPath(String applicationPath) { | ||
this.applicationPath = applicationPath; | ||
} | ||
} |
Oops, something went wrong.