├── siden-sandbox
└── .gitignore
├── siden-example
├── assets
│ ├── moge.txt
│ ├── hello.jsx
│ ├── react.mustache
│ ├── console-polyfill.js
│ ├── chat.html
│ └── comments.jsx
├── src
│ └── main
│ │ ├── resources
│ │ └── templates
│ │ │ └── say
│ │ │ └── hello.html
│ │ └── java
│ │ └── example
│ │ ├── User.java
│ │ ├── UseWebsocket.java
│ │ ├── CollectMetrics.java
│ │ ├── URLShortener.java
│ │ ├── UseReactSSR.java
│ │ ├── UseHandlebars.java
│ │ ├── Main.java
│ │ └── UseReactComplexSSR.java
└── README.md
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── settings.gradle
├── siden-core
└── src
│ ├── main
│ ├── resources
│ │ └── favicon.ico
│ └── java
│ │ └── ninja
│ │ └── siden
│ │ ├── internal
│ │ ├── ExchangeState.java
│ │ ├── BlockingRenderer.java
│ │ ├── ConnectionCallback.java
│ │ ├── MethodOverrideHandler.java
│ │ ├── Core.java
│ │ ├── FiltersHandler.java
│ │ ├── SecurityHandler.java
│ │ ├── ReceiveListenerAdapter.java
│ │ ├── MIMEPredicate.java
│ │ ├── PathPredicate.java
│ │ ├── SidenSession.java
│ │ ├── SidenCookie.java
│ │ ├── SidenResponse.java
│ │ └── LambdaWebSocketFactory.java
│ │ ├── Stoppable.java
│ │ ├── WebSocketFactory.java
│ │ ├── jmx
│ │ ├── SessionMXBean.java
│ │ ├── RequestMXBean.java
│ │ ├── WebSocketMXBean.java
│ │ ├── RouteTracker.java
│ │ ├── ObjectNames.java
│ │ ├── RequestMetrics.java
│ │ ├── RequestMeter.java
│ │ ├── WebSocketTracker.java
│ │ ├── SessionMetrics.java
│ │ └── MetricsAppBuilder.java
│ │ ├── FilterChain.java
│ │ ├── Route.java
│ │ ├── Filter.java
│ │ ├── util
│ │ ├── ExceptionalSupplier.java
│ │ ├── ExceptionalConsumer.java
│ │ ├── ExceptionalFunction.java
│ │ ├── ExceptionalBiConsumer.java
│ │ ├── Predicates.java
│ │ ├── Suppress.java
│ │ ├── LongAccumulators.java
│ │ ├── Publisher.java
│ │ ├── Using.java
│ │ ├── ExactlyOnceCloseable.java
│ │ └── Trial.java
│ │ ├── RendererCustomizer.java
│ │ ├── ExceptionalRoute.java
│ │ ├── Session.java
│ │ ├── RoutingCustomizer.java
│ │ ├── AssetsCustomizer.java
│ │ ├── def
│ │ ├── SubAppDef.java
│ │ ├── AppBuilder.java
│ │ ├── AppContext.java
│ │ ├── ErrorCodeRoutingDef.java
│ │ ├── FilterDef.java
│ │ ├── ExceptionalRoutingDef.java
│ │ ├── WebSocketDef.java
│ │ ├── AppDef.java
│ │ ├── RoutingDef.java
│ │ └── AssetDef.java
│ │ ├── RendererRepository.java
│ │ ├── WebSocket.java
│ │ ├── AttributeContainer.java
│ │ ├── WebSocketCustomizer.java
│ │ ├── Cookie.java
│ │ ├── Response.java
│ │ ├── Renderer.java
│ │ ├── SecurityHeaders.java
│ │ ├── HttpMethod.java
│ │ ├── Request.java
│ │ └── Connection.java
│ └── test
│ └── java
│ └── ninja
│ └── siden
│ ├── util
│ ├── ExactlyOnceCloseableTest.java
│ ├── PublisherTest.java
│ ├── TrialTest.java
│ └── LongAccumulatorsTest.java
│ ├── jmx
│ ├── ObjectNamesTest.java
│ └── MetricsAppBuilderTest.java
│ └── internal
│ ├── SecurityHandlerTest.java
│ ├── MIMEPredicateTest.java
│ ├── FiltersHandlerTest.java
│ ├── MethodOverrideHandlerTest.java
│ ├── Testing.java
│ ├── RendererSelectorTest.java
│ ├── SidenRequestTest.java
│ └── PathPredicateTest.java
├── .gitignore
├── wercker.yml
├── siden-react
├── src
│ ├── test
│ │ └── java
│ │ │ └── ninja
│ │ │ └── siden
│ │ │ └── react
│ │ │ └── JsEngineTest.java
│ └── main
│ │ └── java
│ │ └── ninja
│ │ └── siden
│ │ └── react
│ │ ├── JsEngine.java
│ │ └── React.java
└── README.md
├── README.md
├── TODO.md
└── gradlew.bat
/siden-sandbox/.gitignore:
--------------------------------------------------------------------------------
1 | /.generatedsrc/
2 |
--------------------------------------------------------------------------------
/siden-example/assets/moge.txt:
--------------------------------------------------------------------------------
1 | aaaa
2 | bbbb
3 | cccc
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/taichi/siden/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'siden'
2 |
3 | include 'siden-core', 'siden-react', 'siden-example', 'siden-sandbox'
4 |
5 |
--------------------------------------------------------------------------------
/siden-core/src/main/resources/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/taichi/siden/HEAD/siden-core/src/main/resources/favicon.ico
--------------------------------------------------------------------------------
/siden-example/src/main/resources/templates/say/hello.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hello {{name}} !!
5 |
6 |
7 |
--------------------------------------------------------------------------------
/siden-example/assets/hello.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 | var HelloMessage = React.createClass({
3 | render: function() {
4 | return Hello {this.props.name}
;
5 | }
6 | });
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /build
3 | */build
4 | gradle.properties
5 |
6 | */bin
7 | *.project
8 | *.classpath
9 | *.settings
10 | *.factorypath
11 | *.generated
12 |
13 | .idea
14 | *.ipr
15 | *.iws
16 | *.iml
17 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Sep 16 15:02:34 JST 2014
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip
7 |
--------------------------------------------------------------------------------
/siden-example/assets/react.mustache:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{& rendered}}
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/wercker.yml:
--------------------------------------------------------------------------------
1 | box: taichi/java8-oracle@0.0.1
2 | build:
3 | steps:
4 | - script:
5 | name: chmod
6 | code: chmod +x ./gradlew
7 | - script:
8 | name: show env
9 | code: ./gradlew --project-cache-dir=$WERCKER_CACHE_DIR/.gradle -v
10 | - script:
11 | name: run test
12 | code: ./gradlew --project-cache-dir=$WERCKER_CACHE_DIR/.gradle --full-stacktrace build
13 |
--------------------------------------------------------------------------------
/siden-example/README.md:
--------------------------------------------------------------------------------
1 | # Siden Examples
2 |
3 | TBD
4 |
5 | see. https://github.com/taichi/siden/blob/master/siden-example/src/main/java/example/Main.java
6 |
7 | ## Request
8 |
9 | ### Session
10 |
11 | ## Filter
12 |
13 | ## Response
14 |
15 | ## Rendering
16 |
17 | ### Handlebars.java
18 |
19 | ### Boon JSON
20 |
21 | ### Jackson
22 |
23 | ## Error handling
24 |
25 | ### Exception
26 |
27 | ### Response code
28 |
29 | ## Compose Application
30 |
31 | ## Configurations
32 |
33 | ### Siden
34 |
35 | #### Turn off Response Headers for Security
36 |
37 | ### Undertow
38 |
39 | #### Use SSL
40 |
--------------------------------------------------------------------------------
/siden-example/assets/console-polyfill.js:
--------------------------------------------------------------------------------
1 | // Console-polyfill. MIT license.
2 | // https://github.com/paulmillr/console-polyfill
3 | // Make it safe to do console.log() always.
4 | (function(con) {
5 | 'use strict';
6 | var prop, method;
7 | var empty = {};
8 | var dummy = function() {};
9 | var properties = 'memory'.split(',');
10 | var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
11 | 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
12 | 'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
13 | while (prop = properties.pop()) con[prop] = con[prop] || empty;
14 | while (method = methods.pop()) con[method] = con[method] || dummy;
15 | })(this.console = this.console || {}); // Using `this` for web workers.
16 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/internal/ExchangeState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | enum ExchangeState {
22 | Rendered, Redirected;
23 | }
24 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Stoppable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface Stoppable {
22 |
23 | void stop();
24 |
25 | void addShutdownHook();
26 | }
27 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/WebSocketFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface WebSocketFactory {
22 |
23 | WebSocket create(Connection connection);
24 | }
25 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/jmx/SessionMXBean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface SessionMXBean {
22 |
23 | SessionMetrics getMetrics();
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/FilterChain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface FilterChain {
23 |
24 | Object next() throws Exception;
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/jmx/RequestMXBean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface RequestMXBean {
22 |
23 | RequestMetrics getMetrics();
24 |
25 | void reset();
26 | }
27 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Route.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 |
19 | /**
20 | * @author taichi
21 | */
22 | @FunctionalInterface
23 | public interface Route {
24 |
25 | Object handle(Request request, Response response) throws Exception;
26 | }
27 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Filter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface Filter {
23 |
24 | void filter(Request req, Response res, FilterChain chain) throws Exception;
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/ExceptionalSupplier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface ExceptionalSupplier {
23 |
24 | T get() throws EX;
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/RendererCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface RendererCustomizer> {
22 |
23 | T render(Renderer renderer);
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/ExceptionalConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface ExceptionalConsumer {
23 |
24 | void accept(T t) throws EX;
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/ExceptionalFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface ExceptionalFunction {
23 |
24 | R apply(T t) throws EX;
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/ExceptionalBiConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface ExceptionalBiConsumer {
23 |
24 | void accept(T t, U u) throws EX;
25 | }
26 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/ExceptionalRoute.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface ExceptionalRoute {
23 |
24 | Object handle(EX ex, Request request, Response response);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/siden-example/src/main/java/example/User.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package example;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public class User {
22 |
23 | String name;
24 |
25 | public User(String name) {
26 | this.name = name;
27 | }
28 |
29 | public String getName() {
30 | return this.name;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Session.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface Session extends AttributeContainer {
22 |
23 | String id();
24 |
25 | void invalidate();
26 |
27 | Session regenerate();
28 |
29 | io.undertow.server.session.Session raw();
30 | }
31 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/Predicates.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import java.util.function.Predicate;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public class Predicates {
24 |
25 | public static Predicate not(Predicate predicate) {
26 | return predicate.negate();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/Suppress.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface Suppress {
22 |
23 | static T get(ExceptionalSupplier supplier) {
24 | try {
25 | return supplier.get();
26 | } catch (RuntimeException e) {
27 | throw e;
28 | } catch (Exception e) {
29 | throw new RuntimeException(e);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/RoutingCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import java.util.function.Predicate;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public interface RoutingCustomizer extends
24 | RendererCustomizer {
25 |
26 | RoutingCustomizer type(String type);
27 |
28 | RoutingCustomizer accept(String type);
29 |
30 | RoutingCustomizer match(Predicate fn);
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/AssetsCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface AssetsCustomizer {
22 |
23 | AssetsCustomizer cacheTime(Integer time);
24 |
25 | AssetsCustomizer directoryListing(boolean is);
26 |
27 | AssetsCustomizer welcomeFiles(String... files);
28 |
29 | // AssetsCustomizer etag(Boolean is);
30 |
31 | AssetsCustomizer from(ClassLoader loader);
32 | }
33 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/jmx/WebSocketMXBean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface WebSocketMXBean {
22 |
23 | RequestMetrics getOnConnect();
24 |
25 | RequestMetrics getOnText();
26 |
27 | RequestMetrics getOnBinary();
28 |
29 | RequestMetrics getOnPong();
30 |
31 | RequestMetrics getOnPing();
32 |
33 | RequestMetrics getOnClose();
34 |
35 | void reset();
36 | }
37 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/SubAppDef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 |
19 | /**
20 | * @author taichi
21 | */
22 | public class SubAppDef {
23 |
24 | final String prefix;
25 |
26 | final AppDef app;
27 |
28 | public SubAppDef(String prefix, AppDef app) {
29 | super();
30 | this.prefix = prefix;
31 | this.app = app;
32 | }
33 |
34 | public String prefix() {
35 | return this.prefix;
36 | }
37 |
38 | public AppDef app() {
39 | return this.app;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/LongAccumulators.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import java.util.concurrent.atomic.LongAccumulator;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public interface LongAccumulators {
24 |
25 | static LongAccumulator max() {
26 | return new LongAccumulator((x, y) -> x < y ? y : x, 0);
27 | }
28 |
29 | static LongAccumulator min() {
30 | return new LongAccumulator(
31 | (x, y) -> y < x || (x < 0 && -1 < y) ? y : x, -1);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/siden-example/src/main/java/example/UseWebsocket.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package example;
17 |
18 | import ninja.siden.App;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public class UseWebsocket {
24 |
25 | public static void main(String[] args) {
26 | App app = new App();
27 |
28 | app.get("/", (q, s) -> new java.io.File("assets/chat.html"));
29 |
30 | app.websocket("/ws").onText(
31 | (con, txt) -> con.peers().forEach(c -> c.send(txt)));
32 |
33 | app.listen(8181).addShutdownHook();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/util/ExactlyOnceCloseableTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | import org.junit.Test;
21 |
22 | /**
23 | * @author taichi
24 | */
25 | public class ExactlyOnceCloseableTest {
26 |
27 | @Test
28 | public void close() {
29 | int[] counter = { 0 };
30 | ExactlyOnceCloseable c = ExactlyOnceCloseable.wrap(() -> counter[0]++);
31 | c.close();
32 | c.close();
33 | assertEquals(1, counter[0]);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/RendererRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | @FunctionalInterface
22 | public interface RendererRepository {
23 |
24 | static RendererRepository EMPTY = new RendererRepository() {
25 | @Override
26 | public Renderer find(String path) {
27 | throw new IllegalStateException(
28 | "RendererRepository is not configured. see. "
29 | + Config.class.getName() + "#"
30 | + Config.RENDERER_REPOSITORY.getName());
31 | }
32 | };
33 |
34 | Renderer find(String path);
35 | }
36 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/WebSocket.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import java.nio.ByteBuffer;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public interface WebSocket {
24 |
25 | default void onConnect(Connection connection) throws Exception {
26 | }
27 |
28 | default void onText(String payload) throws Exception {
29 | }
30 |
31 | default void onBinary(ByteBuffer[] payload) throws Exception {
32 | }
33 |
34 | default void onPong(ByteBuffer[] payload) throws Exception {
35 | }
36 |
37 | default void onPing(ByteBuffer[] payload) throws Exception {
38 | }
39 |
40 | default void onClose(ByteBuffer[] payload) throws Exception {
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/siden-example/src/main/java/example/CollectMetrics.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package example;
17 |
18 | import ninja.siden.App;
19 | import ninja.siden.Config;
20 |
21 | /**
22 | * @author taichi
23 | */
24 | public class CollectMetrics {
25 |
26 | public static void main(String[] args) {
27 | // development environments don't need metrics.
28 | App app = App.configure(b -> b.set(Config.ENV, "stable"));
29 |
30 | app.get("/", (req, res) -> "hello");
31 |
32 | App sub = new App();
33 | sub.get("/hoi", (req, res) -> "HOIHOI");
34 | sub.websocket("/ws").onText((c, s) -> c.send(s));
35 |
36 | app.use("/aaa", sub);
37 | app.use("/bbb", sub);
38 |
39 | app.listen().addShutdownHook();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/AppBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 | import io.undertow.server.HttpHandler;
19 | import ninja.siden.App;
20 |
21 | /**
22 | * @author taichi
23 | */
24 | public interface AppBuilder {
25 |
26 | void begin();
27 |
28 | void apply(AppContext context, AssetDef def);
29 |
30 | void apply(AppContext context, RoutingDef def);
31 |
32 | void apply(AppContext context, ErrorCodeRoutingDef def);
33 |
34 | void apply(AppContext context, ExceptionalRoutingDef> def);
35 |
36 | void apply(AppContext context, SubAppDef def);
37 |
38 | void apply(AppContext context, WebSocketDef def);
39 |
40 | void apply(AppContext context, FilterDef def);
41 |
42 | HttpHandler end(App root);
43 | }
44 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/AttributeContainer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import java.util.Optional;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public interface AttributeContainer extends Iterable {
24 |
25 | /**
26 | * @param key
27 | * attribute name
28 | * @param newone
29 | * new attribute
30 | * @return existing value
31 | */
32 | Optional attr(String key, T newone);
33 |
34 | Optional attr(String key);
35 |
36 | /**
37 | * @param key
38 | * @return existing value
39 | */
40 | Optional remove(String key);
41 |
42 | interface Attr {
43 | String name();
44 |
45 | T value();
46 |
47 | T remove();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/AppContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 | import ninja.siden.App;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public class AppContext {
24 |
25 | final App root;
26 |
27 | AppDef app;
28 |
29 | String prefix = "";
30 |
31 | public AppContext(App root) {
32 | this.root = root;
33 | }
34 |
35 | public AppContext(AppContext parent, SubAppDef sam) {
36 | this.root = parent.root();
37 | this.app = sam.app();
38 | this.prefix = parent.prefix() + sam.prefix();
39 | }
40 |
41 | public App root() {
42 | return this.root;
43 | }
44 |
45 | public AppDef app() {
46 | return this.app;
47 | }
48 |
49 | public String prefix() {
50 | return this.prefix;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/Publisher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import java.util.ArrayList;
19 | import java.util.Collections;
20 | import java.util.Iterator;
21 | import java.util.List;
22 | import java.util.function.Consumer;
23 |
24 | /**
25 | * @author taichi
26 | */
27 | public class Publisher {
28 |
29 | List> listeners = Collections
30 | .synchronizedList(new ArrayList<>());
31 |
32 | public void on(Consumer fn) {
33 | this.listeners.add(fn);
34 | }
35 |
36 | public void off(Consumer fn) {
37 | this.listeners.remove(fn);
38 | }
39 |
40 | public void post(E event) {
41 | for (Iterator> i = this.listeners.iterator(); i.hasNext();) {
42 | try {
43 | i.next().accept(event);
44 | } finally {
45 | i.remove();
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/siden-react/src/test/java/ninja/siden/react/JsEngineTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.react;
17 |
18 | import static org.junit.Assert.*;
19 |
20 | import java.util.Collections;
21 |
22 | import org.junit.Before;
23 | import org.junit.Test;
24 |
25 | /**
26 | * @author taichi
27 | */
28 | public class JsEngineTest {
29 |
30 | JsEngine target;
31 |
32 | @Before
33 | public void setUp() {
34 | this.target = new JsEngine();
35 | }
36 |
37 | @Test
38 | public void testContainGlobal() {
39 | this.target.initialize(Collections.emptyList());
40 | assertNotNull(this.target.eval("global"));
41 | }
42 |
43 | @Test
44 | public void testEvalSeparately() throws Exception {
45 | this.target.initialize(Collections.emptyList());
46 | this.target.eval("var hoge = 10");
47 | assertNull(this.target.eval("this['hoge']"));
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/jmx/RouteTracker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | import ninja.siden.Request;
19 | import ninja.siden.Response;
20 | import ninja.siden.Route;
21 |
22 | /**
23 | * @author taichi
24 | */
25 | public class RouteTracker implements Route, RequestMXBean {
26 |
27 | Route original;
28 | RequestMeter totalResult = new RequestMeter();
29 |
30 | public RouteTracker(Route original) {
31 | this.original = original;
32 | }
33 |
34 | @Override
35 | public Object handle(Request request, Response response) throws Exception {
36 | return totalResult.apply(m -> original.handle(request, response));
37 | }
38 |
39 | @Override
40 | public void reset() {
41 | this.totalResult.reset();
42 | }
43 |
44 | @Override
45 | public RequestMetrics getMetrics() {
46 | return this.totalResult.toMetrics();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/internal/BlockingRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import io.undertow.server.HttpServerExchange;
19 |
20 | import java.io.IOException;
21 |
22 | import ninja.siden.Renderer;
23 |
24 | /**
25 | * @author taichi
26 | */
27 | public class BlockingRenderer implements Renderer {
28 |
29 | final Renderer renderer;
30 |
31 | public BlockingRenderer(Renderer renderer) {
32 | super();
33 | this.renderer = renderer;
34 | }
35 |
36 | @Override
37 | public void render(T model, HttpServerExchange sink) throws IOException {
38 | if (sink.isBlocking() == false) {
39 | sink.startBlocking();
40 | }
41 | if (sink.isInIoThread()) {
42 | sink.dispatch(exchange -> {
43 | renderer.render(model, exchange);
44 | });
45 | } else {
46 | renderer.render(model, sink);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/siden-example/src/main/java/example/URLShortener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package example;
17 |
18 | import java.util.Optional;
19 | import java.util.concurrent.ConcurrentHashMap;
20 |
21 | import ninja.siden.App;
22 |
23 | /**
24 | * @author taichi
25 | */
26 | public class URLShortener {
27 |
28 | public static void main(String[] args) {
29 | App app = new App();
30 | ConcurrentHashMap map = new ConcurrentHashMap<>();
31 | app.post("/", (req, res) -> {
32 | Optional opt = req.body();
33 | return opt.map(s -> {
34 | String k = Integer.toHexString(s.hashCode());
35 | map.put(k, s);
36 | return String.format("http://%s/%s",
37 | req.raw().getHostAndPort(), k);
38 | });
39 | });
40 |
41 | app.get("/:k", (req, res) -> req.params("k").map(key -> map.get(key))
42 | .map(res::redirect).orElse(404));
43 |
44 | app.listen();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/Using.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | /**
19 | * @author taichi
20 | */
21 | public interface Using {
22 |
23 | static R transform(
24 | ExceptionalSupplier supplier,
25 | ExceptionalFunction transformer) {
26 | try (IO t = supplier.get()) {
27 | return transformer.apply(t);
28 | } catch (RuntimeException e) {
29 | throw e;
30 | } catch (Exception e) {
31 | throw new RuntimeException(e);
32 | }
33 | }
34 |
35 | static void consume(
36 | ExceptionalSupplier supplier,
37 | ExceptionalConsumer consumer) {
38 | try (IO t = supplier.get()) {
39 | consumer.accept(t);
40 | } catch (RuntimeException e) {
41 | throw e;
42 | } catch (Exception e) {
43 | throw new RuntimeException(e);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/ErrorCodeRoutingDef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 | import ninja.siden.Renderer;
19 | import ninja.siden.RendererCustomizer;
20 | import ninja.siden.Route;
21 |
22 | /**
23 | * @author taichi
24 | */
25 | public class ErrorCodeRoutingDef implements
26 | RendererCustomizer {
27 |
28 | final int code;
29 | final Route route;
30 | Renderer> renderer;
31 |
32 | public ErrorCodeRoutingDef(int code, Route route) {
33 | super();
34 | this.code = code;
35 | this.route = route;
36 | }
37 |
38 | @Override
39 | public ErrorCodeRoutingDef render(Renderer renderer) {
40 | this.renderer = renderer;
41 | return this;
42 | }
43 |
44 | public int code() {
45 | return this.code;
46 | }
47 |
48 | public Route route() {
49 | return this.route;
50 | }
51 |
52 | public Renderer> renderer() {
53 | return this.renderer;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/WebSocketCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import java.nio.ByteBuffer;
19 |
20 | import ninja.siden.util.ExceptionalBiConsumer;
21 | import ninja.siden.util.ExceptionalConsumer;
22 |
23 | /**
24 | * @author taichi
25 | */
26 | public interface WebSocketCustomizer {
27 |
28 | WebSocketCustomizer onConnect(ExceptionalConsumer fn);
29 |
30 | WebSocketCustomizer onText(
31 | ExceptionalBiConsumer fn);
32 |
33 | WebSocketCustomizer onBinary(
34 | ExceptionalBiConsumer fn);
35 |
36 | WebSocketCustomizer onPong(
37 | ExceptionalBiConsumer fn);
38 |
39 | WebSocketCustomizer onPing(
40 | ExceptionalBiConsumer fn);
41 |
42 | WebSocketCustomizer onClose(
43 | ExceptionalBiConsumer fn);
44 | }
45 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/jmx/ObjectNamesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | import java.util.Arrays;
21 | import java.util.List;
22 |
23 | import javax.management.ObjectName;
24 |
25 | import ninja.siden.jmx.ObjectNames;
26 |
27 | import org.junit.Test;
28 |
29 | /**
30 | * @author taichi
31 | */
32 | public class ObjectNamesTest {
33 |
34 | @Test
35 | public void to() throws Exception {
36 | ObjectName name = ObjectNames.to("aaa.bbb:type=Z");
37 | assertEquals("aaa.bbb", name.getDomain());
38 | assertEquals("Z", name.getKeyProperty("type"));
39 | }
40 |
41 | @Test
42 | public void withMap() throws Exception {
43 | List list = Arrays.asList("type", "Z", "aaa", "bbb", "ccc",
44 | "ddd", "bbb", "zzz");
45 | ObjectName name = ObjectNames.to("aaa.bbb", list);
46 | assertEquals("aaa.bbb:type=Z,aaa=bbb,ccc=ddd,bbb=zzz", name.toString());
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Cookie.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import java.util.Date;
19 |
20 | /**
21 | * @author taichi
22 | */
23 | public interface Cookie {
24 |
25 | String name();
26 |
27 | String value();
28 |
29 | Cookie value(final String value);
30 |
31 | String path();
32 |
33 | Cookie path(final String path);
34 |
35 | String domain();
36 |
37 | Cookie domain(final String domain);
38 |
39 | Integer maxAge();
40 |
41 | Cookie maxAge(final Integer maxAge);
42 |
43 | boolean discard();
44 |
45 | Cookie discard(final boolean discard);
46 |
47 | boolean secure();
48 |
49 | Cookie secure(final boolean secure);
50 |
51 | int version();
52 |
53 | Cookie version(final int version);
54 |
55 | boolean httpOnly();
56 |
57 | Cookie httpOnly(final boolean httpOnly);
58 |
59 | Date expires();
60 |
61 | Cookie expires(final Date expires);
62 |
63 | String comment();
64 |
65 | Cookie comment(final String comment);
66 | }
67 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/FilterDef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 | import io.undertow.predicate.Predicate;
19 | import io.undertow.server.HttpServerExchange;
20 |
21 | import java.util.Objects;
22 |
23 | import ninja.siden.Filter;
24 | import ninja.siden.FilterChain;
25 | import ninja.siden.Request;
26 | import ninja.siden.Response;
27 |
28 | /**
29 | * @author taichi
30 | */
31 | public class FilterDef implements Predicate, Filter {
32 |
33 | final Predicate predicate;
34 |
35 | final Filter filter;
36 |
37 | public FilterDef(Predicate predicate, Filter filter) {
38 | this.predicate = Objects.requireNonNull(predicate);
39 | this.filter = Objects.requireNonNull(filter);
40 | }
41 |
42 | @Override
43 | public boolean resolve(HttpServerExchange value) {
44 | return this.predicate.resolve(value);
45 | }
46 |
47 | @Override
48 | public void filter(Request req, Response res, FilterChain chain)
49 | throws Exception {
50 | this.filter.filter(req, res, chain);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/ExceptionalRoutingDef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 | import ninja.siden.ExceptionalRoute;
19 | import ninja.siden.Renderer;
20 | import ninja.siden.RendererCustomizer;
21 |
22 | /**
23 | * @author taichi
24 | */
25 | public class ExceptionalRoutingDef implements
26 | RendererCustomizer> {
27 |
28 | Class type;
29 | ExceptionalRoute route;
30 | Renderer> renderer;
31 |
32 | public ExceptionalRoutingDef(Class type, ExceptionalRoute route) {
33 | super();
34 | this.type = type;
35 | this.route = route;
36 | }
37 |
38 | @Override
39 | public ExceptionalRoutingDef render(Renderer renderer) {
40 | this.renderer = renderer;
41 | return this;
42 | }
43 |
44 | public Class type() {
45 | return this.type;
46 | }
47 |
48 | public ExceptionalRoute route() {
49 | return this.route;
50 | }
51 |
52 | public Renderer> renderer() {
53 | return this.renderer;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/jmx/ObjectNames.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | import java.util.Iterator;
19 | import java.util.List;
20 |
21 | import javax.management.MalformedObjectNameException;
22 | import javax.management.ObjectName;
23 |
24 | /**
25 | * @author taichi
26 | */
27 | public interface ObjectNames {
28 |
29 | static ObjectName to(CharSequence name) {
30 | try {
31 | return new ObjectName(name.toString());
32 | } catch (MalformedObjectNameException e) {
33 | throw new IllegalArgumentException(e);
34 | }
35 | }
36 |
37 | static ObjectName to(CharSequence domain, List props) {
38 | if (props.size() % 2 != 0) {
39 | throw new IllegalArgumentException();
40 | }
41 | StringBuilder stb = new StringBuilder(domain);
42 | stb.append(":");
43 | for (Iterator i = props.iterator(); i.hasNext();) {
44 | stb.append(i.next());
45 | stb.append('=');
46 | stb.append(i.next());
47 | if (i.hasNext()) {
48 | stb.append(',');
49 | }
50 | }
51 | return to(stb);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/util/PublisherTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | import java.util.function.Consumer;
21 |
22 | import ninja.siden.util.Publisher;
23 |
24 | import org.junit.Before;
25 | import org.junit.Test;
26 |
27 | /**
28 | * @author taichi
29 | */
30 | public class PublisherTest {
31 |
32 | Publisher target;
33 |
34 | @Before
35 | public void setUp() throws Exception {
36 | this.target = new Publisher<>();
37 | }
38 |
39 | @Test
40 | public void on() throws Exception {
41 | String[] called = { null };
42 | target.on(s -> called[0] = s);
43 | target.post("aaa");
44 | assertEquals("aaa", called[0]);
45 | target.post("bbb");
46 | assertEquals("aaa", called[0]);
47 | }
48 |
49 | @Test
50 | public void off() throws Exception {
51 | String[] called = { "aaa" };
52 | Consumer fn = s -> called[0] = s;
53 | target.on(fn);
54 | target.off(fn);
55 | target.post("bbb");
56 | assertEquals("aaa", called[0]);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/util/TrialTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | import java.io.File;
21 | import java.io.IOException;
22 | import java.util.Optional;
23 |
24 | import org.junit.Test;
25 |
26 | /**
27 | * @author taichi
28 | */
29 | public class TrialTest {
30 |
31 | static File ok(String s) throws IOException {
32 | return new File(s);
33 | }
34 |
35 | static File ng(String s) throws IOException {
36 | throw new IOException(s);
37 | }
38 |
39 | @Test
40 | public void success() throws Exception {
41 | int ret = Optional.of("aaa").map(Trial.of(TrialTest::ok))
42 | . map(t -> t.either(f -> 200, ioex -> 400))
43 | .map(i -> i + 10).get();
44 | assertEquals(210, ret);
45 | }
46 |
47 | @Test
48 | public void failed() throws Exception {
49 | int ret = Optional.of("aaa").map(Trial.of(TrialTest::ng))
50 | . map(t -> t.either(f -> 200, ioex -> 400))
51 | .map(i -> i + 11).get();
52 |
53 | assertEquals(411, ret);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Response.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import io.undertow.server.HttpServerExchange;
19 |
20 | import java.util.Map;
21 |
22 | /**
23 | * @author taichi
24 | */
25 | public interface Response {
26 |
27 | Response status(int code);
28 |
29 | Response header(String name, String... values);
30 |
31 | /**
32 | * set RFC1123 date pattern to Response header.
33 | *
34 | * @param name
35 | * @param date
36 | * @return this
37 | */
38 | Response header(String name, long date);
39 |
40 | Response headers(Map headers);
41 |
42 | Cookie cookie(String name, String value);
43 |
44 | /**
45 | * @param name
46 | * @return existing value
47 | */
48 | Cookie removeCookie(String name);
49 |
50 | /**
51 | * @param contentType
52 | */
53 | Response type(String contentType);
54 |
55 | Object redirect(String location);
56 |
57 | Object redirect(int code, String location);
58 |
59 | Object render(MODEL model, Renderer renderer);
60 |
61 | Object render(MODEL model, String template);
62 |
63 | HttpServerExchange raw();
64 | }
65 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/util/ExactlyOnceCloseable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
19 | import java.util.logging.Level;
20 | import java.util.logging.Logger;
21 |
22 | /**
23 | * @author taichi
24 | */
25 | public class ExactlyOnceCloseable implements AutoCloseable {
26 |
27 | static final AtomicReferenceFieldUpdater UPDATER = AtomicReferenceFieldUpdater
28 | .newUpdater(ExactlyOnceCloseable.class, AutoCloseable.class,
29 | "delegate");
30 |
31 | volatile AutoCloseable delegate;
32 |
33 | public ExactlyOnceCloseable(AutoCloseable closeable) {
34 | this.delegate = closeable;
35 | }
36 |
37 | public static ExactlyOnceCloseable wrap(AutoCloseable c) {
38 | return new ExactlyOnceCloseable(c);
39 | }
40 |
41 | @Override
42 | public void close() {
43 | try {
44 | UPDATER.getAndUpdate(this, c -> () -> {
45 | }).close();
46 | } catch (Exception ignore) {
47 | Logger.getLogger(ExactlyOnceCloseable.class.getName()).log(
48 | Level.FINER, ignore.getMessage(), ignore);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Siden
2 | tiny web application framework for Java SE 8.
3 |
4 | Siden focus on writing your application quickly and running server more faster.
5 |
6 | ## Getting Started
7 |
8 | ### Write simple java application
9 |
10 | ```java
11 | import ninja.siden.App;
12 |
13 | public class Main {
14 | public static void main(String[] args) {
15 | App app = new App();
16 | app.get("/hello", (req, res) -> "Hello world");
17 | app.listen();
18 | }
19 | }
20 | ```
21 |
22 | if you want to more examples, see [example/Main.java](https://github.com/taichi/siden/blob/master/siden-example/src/main/java/example/Main.java).
23 |
24 | ### Add dependency to your build.gradle
25 |
26 | ```groovy
27 | apply plugin: 'java'
28 |
29 | repositories.jcenter()
30 |
31 | dependencies {
32 | compile 'ninja.siden:siden-core:0.6.0'
33 | }
34 |
35 | sourceCompatibility = targetCompatibility = 1.8
36 | ```
37 |
38 | ### Run and View
39 |
40 | http://localhost:8080/hello
41 |
42 | ## WebSocket Example
43 |
44 | ```java
45 | import java.nio.file.Paths;
46 | import ninja.siden.App;
47 |
48 | public class UseWebsocket {
49 | public static void main(String[] args) {
50 | App app = new App();
51 | app.get("/", (q, s) -> Paths.get("assets/chat.html"));
52 | app.websocket("/ws").onText(
53 | (con, txt) -> con.peers().forEach(c -> c.send(txt)));
54 | app.listen(8181);
55 | }
56 | }
57 | ```
58 |
59 | # License
60 |
61 | Apache License, Version 2.0
62 |
63 | # Inspired projects
64 |
65 | * http://expressjs.com/
66 | * http://www.sinatrarb.com/
67 | * http://www.sparkjava.com/
68 | * http://flask.pocoo.org/
69 |
70 | # Badges
71 |
72 | [](https://app.wercker.com/project/bykey/de09957e13da7a18ae6cf3fbd67afc68)
73 |
--------------------------------------------------------------------------------
/siden-example/src/main/java/example/UseReactSSR.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package example;
17 |
18 | import java.nio.file.Paths;
19 | import java.util.Arrays;
20 |
21 | import ninja.siden.App;
22 | import ninja.siden.react.React;
23 |
24 | /**
25 | * React.js Server Side Rendering Example on JVM.
26 | *
27 | * @author taichi
28 | */
29 | public class UseReactSSR {
30 |
31 | public static void main(String[] args) {
32 | // setup react server side rendering
33 | React rc = new React("HelloMessage", "content", Arrays.asList(
34 | // https://github.com/paulmillr/console-polyfill
35 | // Nashorn don't contain console object.
36 | Paths.get("assets", "console-polyfill.js"),
37 | // https://github.com/facebook/react
38 | Paths.get("assets", "react.js"),
39 | // npm install -g react-tools
40 | // jsx -x jsx assets build
41 | // siden-react don't support jsx compile.
42 | Paths.get("build", "hello.js")));
43 |
44 | App app = new App();
45 | app.get("/", (q, s) -> {
46 | // serialized json
47 | String props = "{\"name\":\"john\"}";
48 | // server side rendering
49 | return "" + rc.toHtml(props) + "";
50 | }).type("text/html");
51 | app.listen().addShutdownHook();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/def/WebSocketDef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.def;
17 |
18 | import io.undertow.predicate.Predicate;
19 | import io.undertow.predicate.PredicatesHandler;
20 | import io.undertow.websockets.WebSocketProtocolHandshakeHandler;
21 | import ninja.siden.WebSocketFactory;
22 | import ninja.siden.internal.ConnectionCallback;
23 |
24 | import org.xnio.OptionMap;
25 |
26 | /**
27 | * @author taichi
28 | */
29 | public class WebSocketDef {
30 |
31 | final String template;
32 | final Predicate predicate;
33 | final WebSocketFactory factory;
34 |
35 | public WebSocketDef(String template, Predicate predicate,
36 | WebSocketFactory factory) {
37 | super();
38 | this.template = template;
39 | this.predicate = predicate;
40 | this.factory = factory;
41 | }
42 |
43 | public String template() {
44 | return this.template;
45 | }
46 |
47 | public Predicate predicate() {
48 | return this.predicate;
49 | }
50 |
51 | public WebSocketFactory factory() {
52 | return this.factory;
53 | }
54 |
55 | public void addTo(PredicatesHandler ph, OptionMap config) {
56 | ph.addPredicatedHandler(this.predicate(),
57 | next -> new WebSocketProtocolHandshakeHandler(
58 | new ConnectionCallback(this.factory()), next));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/internal/SecurityHandlerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import static org.junit.Assert.assertNotNull;
19 | import io.undertow.server.HttpHandler;
20 | import io.undertow.server.HttpServerExchange;
21 | import io.undertow.util.HttpString;
22 | import mockit.integration.junit4.JMockit;
23 | import ninja.siden.Config;
24 | import ninja.siden.SecurityHeaders;
25 |
26 | import org.junit.Before;
27 | import org.junit.Test;
28 | import org.junit.runner.RunWith;
29 |
30 | /**
31 | * @author taichi
32 | */
33 | @RunWith(JMockit.class)
34 | public class SecurityHandlerTest {
35 |
36 | HttpServerExchange exchange;
37 | HttpHandler target;
38 |
39 | @Before
40 | public void setUp() {
41 | this.exchange = new HttpServerExchange(null);
42 | this.exchange.putAttachment(Core.CONFIG, Config.defaults().getMap());
43 |
44 | this.target = new SecurityHandler(Testing.mustCall());
45 | }
46 |
47 | void assertHeader(HttpString name) {
48 | assertNotNull(this.exchange.getResponseHeaders().get(name));
49 | }
50 |
51 | @Test
52 | public void testHeaders() throws Exception {
53 | this.target.handleRequest(this.exchange);
54 | assertHeader(SecurityHeaders.FRAME_OPTIONS);
55 | assertHeader(SecurityHeaders.XSS_PROTECTION);
56 | assertHeader(SecurityHeaders.CONTENT_TYPE_OPTIONS);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/util/LongAccumulatorsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.util;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | import java.util.concurrent.atomic.LongAccumulator;
21 |
22 | import org.junit.experimental.runners.Enclosed;
23 | import org.junit.experimental.theories.DataPoints;
24 | import org.junit.experimental.theories.Theories;
25 | import org.junit.experimental.theories.Theory;
26 | import org.junit.runner.RunWith;
27 |
28 | /**
29 | * @author taichi
30 | */
31 | @RunWith(Enclosed.class)
32 | public class LongAccumulatorsTest {
33 |
34 | @RunWith(Theories.class)
35 | public static class Max {
36 | @DataPoints
37 | public static int[][] fixtures = { { 10, 11, 11 }, { 10, 9, 10 } };
38 |
39 | @Theory
40 | public void test(int[] fixture) {
41 | LongAccumulator la = LongAccumulators.max();
42 | la.accumulate(fixture[0]);
43 | la.accumulate(fixture[1]);
44 | assertEquals(fixture[2], la.get());
45 | }
46 | }
47 |
48 | @RunWith(Theories.class)
49 | public static class Min {
50 | @DataPoints
51 | public static int[][] fixtures = { { 10, 11, 10 }, { 10, 9, 9 },
52 | { -10, 7, 7 } };
53 |
54 | @Theory
55 | public void test(int[] fixture) {
56 | LongAccumulator la = LongAccumulators.min();
57 | la.accumulate(fixture[0]);
58 | la.accumulate(fixture[1]);
59 | assertEquals(fixture[2], la.get());
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 |
2 | # Monitoring support
3 | * https://github.com/rhq-project/rhq
4 | * https://github.com/dropwizard/metrics
5 | * https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/MetricsHandler.java
6 | * https://github.com/CloudBees-community/wildfly-clickstack/blob/master/src/clickstack-resources/jboss-base-dir/configuration/wildfly-metrics.xml
7 |
8 | # Write more documents
9 |
10 | * make site on s3
11 | * define deployment pipeline.
12 | * more examples
13 | * javadoc
14 |
15 | # database integration
16 |
17 | * https://github.com/jOOQ/jOOQ
18 | * https://github.com/brianm/jdbi
19 |
20 | # don't work
21 |
22 | # template engine support
23 | ## Handlebars.java
24 | https://github.com/jknack/handlebars.java
25 |
26 | ## FreeMarker
27 | http://freemarker.org/
28 |
29 | ## Thymeleaf
30 | http://www.thymeleaf.org/
31 |
32 | ## Mustache
33 | https://github.com/spullara/mustache.java
34 |
35 | ## Jade
36 | https://github.com/neuland/jade4j
37 |
38 |
39 | ## NestedQuery support
40 | [Rack](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L104) や[qs](https://github.com/hapijs/qs)のようなnested queryはパラメータのキー表現とそれを取り出すときのコードの表現が一致しているから使い易いのであって、Javaでやるとどうしても全然違った表現になってしまう為、特に使い易くない。
41 |
42 | やるならJAX-RSのようにパラメータをオブジェクトにマッピングすべき。
43 | JSONからオブジェクトへのマッピングは便利なライブラリが沢山あるのであるからして、NestedQueryを使いたいケースは少ない気がする。
44 |
45 |
46 |
47 | ```java
48 | public class NestedQuery {
49 |
50 | Map kids = new HashMap<>();
51 |
52 | String value = "";
53 |
54 | List list = new ArrayList<>();
55 |
56 | public NestedQuery get(String key) {
57 | return this.kids.get(key);
58 | }
59 |
60 | public String value() {
61 | return this.value;
62 | }
63 |
64 | public List list() {
65 | return Collections.unmodifiableList(this.list);
66 | }
67 |
68 | public static NestedQuery to(Map> params) {
69 | return to(params, Config.defaults().getMap());
70 | }
71 |
72 | public static NestedQuery to(Map> params,
73 | OptionMap options) {
74 | return null;
75 | }
76 | }
77 | ```
78 |
79 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Renderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import io.undertow.server.HttpServerExchange;
19 |
20 | import java.io.IOException;
21 | import java.io.OutputStream;
22 | import java.io.OutputStreamWriter;
23 | import java.io.Writer;
24 |
25 | import ninja.siden.internal.BlockingRenderer;
26 | import ninja.siden.internal.Core;
27 |
28 | import org.xnio.OptionMap;
29 |
30 | /**
31 | * @author taichi
32 | */
33 | @FunctionalInterface
34 | public interface Renderer {
35 |
36 | void render(T model, HttpServerExchange sink) throws IOException;
37 |
38 | public static Renderer ofStream(
39 | OutputStreamConsumer fn) {
40 | return new BlockingRenderer((model, sink) -> fn.render(model,
41 | sink.getOutputStream()));
42 | }
43 |
44 | public static Renderer of(WriterConsumer fn) {
45 | return new BlockingRenderer((model, sink) -> {
46 | OptionMap config = sink.getAttachment(Core.CONFIG);
47 | Writer w = new OutputStreamWriter(sink.getOutputStream(),
48 | config.get(Config.CHARSET));
49 | fn.render(model, w);
50 | w.flush();
51 | });
52 | }
53 |
54 | @FunctionalInterface
55 | public interface OutputStreamConsumer {
56 | void render(T model, OutputStream out) throws IOException;
57 | }
58 |
59 | @FunctionalInterface
60 | public interface WriterConsumer {
61 | void render(T model, Writer out) throws IOException;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/SecurityHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import io.undertow.util.HttpString;
19 |
20 | /**
21 | * @author taichi
22 | * @see List_of_useful_HTTP_headers
24 | */
25 | public interface SecurityHeaders {
26 |
27 | String REQUESTED_WITH_STRING = "X-Requested-With";
28 |
29 | String STRICT_TRANSPORT_SECURITY_STRING = "Strict-Transport-Security";
30 | String FRAME_OPTIONS_STRING = "X-Frame-Options";
31 | String XSS_PROTECTION_STRING = "X-XSS-Protection";
32 | String CONTENT_TYPE_OPTIONS_STRING = "X-Content-Type-Options";
33 | String CONTENT_SECURITY_POLICY_STRING = "Content-Security-Policy";
34 | String CONTENT_SECURITY_POLICY_REPORT_ONLY_STRING = "Content-Security-Policy-Report-Only";
35 |
36 | HttpString REQUESTED_WITH = new HttpString(REQUESTED_WITH_STRING);
37 |
38 | HttpString STRICT_TRANSPORT_SECURITY = new HttpString(
39 | STRICT_TRANSPORT_SECURITY_STRING);
40 | HttpString FRAME_OPTIONS = new HttpString(FRAME_OPTIONS_STRING);
41 | HttpString XSS_PROTECTION = new HttpString(XSS_PROTECTION_STRING);
42 | HttpString CONTENT_TYPE_OPTIONS = new HttpString(
43 | CONTENT_TYPE_OPTIONS_STRING);
44 | HttpString CONTENT_SECURITY_POLICY = new HttpString(
45 | CONTENT_SECURITY_POLICY_STRING);
46 | HttpString CONTENT_SECURITY_REPORT_ONLY_POLICY = new HttpString(
47 | CONTENT_SECURITY_POLICY_REPORT_ONLY_STRING);
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/siden-react/src/main/java/ninja/siden/react/JsEngine.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.react;
17 |
18 | import java.nio.file.Files;
19 | import java.nio.file.Path;
20 | import java.util.List;
21 |
22 | import javax.script.ScriptContext;
23 | import javax.script.ScriptEngine;
24 | import javax.script.ScriptEngineManager;
25 |
26 | import ninja.siden.util.Suppress;
27 | import ninja.siden.util.Using;
28 |
29 | import org.jboss.logging.Logger;
30 |
31 | /**
32 | * @author taichi
33 | */
34 | public class JsEngine {
35 |
36 | static final Logger LOG = Logger.getLogger(JsEngine.class);
37 |
38 | final ScriptEngineManager manager;
39 |
40 | public JsEngine() {
41 | manager = new ScriptEngineManager();
42 | }
43 |
44 | ScriptEngine newEngine() {
45 | return manager.getEngineByExtension("js");
46 | }
47 |
48 | public void initialize(List scripts) {
49 | ScriptEngine se = newEngine();
50 | Suppress.get(() -> se.eval("var global = this;"));
51 | scripts.forEach(p -> eval(se, p));
52 | this.manager.setBindings(se.getBindings(ScriptContext.ENGINE_SCOPE));
53 | }
54 |
55 | public Object eval(String script) {
56 | LOG.debug(manager.getBindings().keySet());
57 | ScriptEngine engine = newEngine();
58 | return Suppress.get(() -> engine.eval(script));
59 | }
60 |
61 | public Object eval(Path path) {
62 | LOG.debug(manager.getBindings().keySet());
63 | return eval(newEngine(), path);
64 | }
65 |
66 | Object eval(ScriptEngine engine, Path path) {
67 | return Using.transform(() -> Files.newBufferedReader(path),
68 | engine::eval);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/internal/ConnectionCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import io.undertow.UndertowLogger;
19 | import io.undertow.websockets.WebSocketConnectionCallback;
20 | import io.undertow.websockets.core.WebSocketChannel;
21 | import io.undertow.websockets.spi.WebSocketHttpExchange;
22 |
23 | import java.io.IOException;
24 | import java.util.Collections;
25 | import java.util.Set;
26 | import java.util.concurrent.ConcurrentHashMap;
27 |
28 | import ninja.siden.Connection;
29 | import ninja.siden.WebSocket;
30 | import ninja.siden.WebSocketFactory;
31 |
32 | import org.xnio.IoUtils;
33 |
34 | /**
35 | * @author taichi
36 | */
37 | public class ConnectionCallback implements WebSocketConnectionCallback {
38 |
39 | final WebSocketFactory factory;
40 | final Set peers = Collections
41 | .newSetFromMap(new ConcurrentHashMap<>());
42 |
43 | public ConnectionCallback(WebSocketFactory factory) {
44 | this.factory = factory;
45 | }
46 |
47 | @Override
48 | public void onConnect(WebSocketHttpExchange exchange,
49 | WebSocketChannel channel) {
50 | try {
51 | Connection connection = new SidenConnection(exchange, channel,
52 | peers);
53 | WebSocket socket = factory.create(connection);
54 | socket.onConnect(connection);
55 | channel.getReceiveSetter().set(new ReceiveListenerAdapter(socket));
56 | channel.resumeReceives();
57 | } catch (IOException e) {
58 | UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
59 | IoUtils.safeClose(channel);
60 | } catch (Exception e) {
61 | IoUtils.safeClose(channel);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/internal/MethodOverrideHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import io.undertow.server.HttpHandler;
19 | import io.undertow.server.HttpServerExchange;
20 | import io.undertow.server.handlers.form.FormData;
21 | import io.undertow.server.handlers.form.FormDataParser;
22 | import io.undertow.util.HttpString;
23 | import io.undertow.util.Methods;
24 |
25 | import java.util.Optional;
26 |
27 | import ninja.siden.HttpMethod;
28 |
29 | /**
30 | * @author taichi
31 | */
32 | public class MethodOverrideHandler implements HttpHandler {
33 |
34 | static final HttpString HEADER = new HttpString("X-HTTP-Method-Override");
35 |
36 | static final String FORM = "_method";
37 |
38 | HttpHandler next;
39 |
40 | public MethodOverrideHandler(HttpHandler next) {
41 | this.next = next;
42 | }
43 |
44 | @Override
45 | public void handleRequest(HttpServerExchange exchange) throws Exception {
46 | if (Methods.POST.equals(exchange.getRequestMethod())) {
47 | String newMethod = exchange.getRequestHeaders().getFirst(HEADER);
48 | Optional opt = HttpMethod.find(newMethod);
49 | if (opt.isPresent()) {
50 | exchange.setRequestMethod(opt.get());
51 | } else {
52 | FormData data = exchange
53 | .getAttachment(FormDataParser.FORM_DATA);
54 | if (data != null) {
55 | FormData.FormValue fv = data.getFirst(FORM);
56 | if (fv != null && fv.isFile() == false) {
57 | HttpMethod.find(fv.getValue()).map(
58 | exchange::setRequestMethod);
59 | }
60 | }
61 | }
62 | }
63 | this.next.handleRequest(exchange);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/siden-react/src/main/java/ninja/siden/react/React.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.react;
17 |
18 | import java.nio.file.Path;
19 | import java.util.List;
20 |
21 | /**
22 | * @author taichi
23 | */
24 | public class React {
25 |
26 | final JsEngine engine = new JsEngine();
27 |
28 | final String name;
29 |
30 | final String containerId;
31 |
32 | public React(String name, String containerId, List scripts) {
33 | super();
34 | this.name = name;
35 | this.containerId = containerId;
36 | this.engine.initialize(scripts);
37 | }
38 |
39 | String makeScript(String encodedProps) {
40 | StringBuilder stb = new StringBuilder();
41 | stb.append("React.renderToString(");
42 | appendInitializer(stb, encodedProps);
43 | stb.append(")");
44 | return stb.toString();
45 | }
46 |
47 | public StringBuilder toHtml(String encodedProps) {
48 | StringBuilder stb = new StringBuilder();
49 | stb.append("");
52 | stb.append(this.engine.eval(makeScript(encodedProps)));
53 | stb.append("
");
54 | return stb;
55 | }
56 |
57 | public StringBuilder toClientJs(String encodedProps) {
58 | StringBuilder stb = new StringBuilder();
59 | stb.append("React.render(");
60 | appendInitializer(stb, encodedProps);
61 | stb.append(", document.getElementById(");
62 | stb.append("\"");
63 | stb.append(this.containerId);
64 | stb.append("\"));");
65 | return stb;
66 | }
67 |
68 | void appendInitializer(StringBuilder a, String encodedProps) {
69 | a.append(this.name);
70 | a.append('(');
71 | a.append(encodedProps);
72 | a.append(')');
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/HttpMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import io.undertow.predicate.Predicate;
19 | import io.undertow.server.HttpServerExchange;
20 | import io.undertow.util.HttpString;
21 | import io.undertow.util.Methods;
22 |
23 | import java.util.HashMap;
24 | import java.util.Map;
25 | import java.util.Optional;
26 |
27 | /**
28 | * @author taichi
29 | */
30 | public enum HttpMethod implements Predicate {
31 |
32 | GET(Methods.GET), HEAD(Methods.HEAD), POST(Methods.POST), PUT(Methods.PUT), DELETE(
33 | Methods.DELETE), TRACE(Methods.TRACE), OPTIONS(Methods.OPTIONS), CONNECT(
34 | Methods.CONNECT), PATCH(new HttpString("PATCH")), LINK(
35 | new HttpString("LINK")), UNLINK(new HttpString("UNLINK"));
36 |
37 | static final Map methods = new HashMap<>();
38 | static {
39 | for (HttpMethod hm : HttpMethod.values()) {
40 | methods.put(hm.rawdata, hm);
41 | }
42 | }
43 |
44 | HttpString rawdata;
45 |
46 | private HttpMethod(HttpString string) {
47 | this.rawdata = string;
48 | }
49 |
50 | @Override
51 | public boolean resolve(HttpServerExchange value) {
52 | return this.rawdata.equals(value.getRequestMethod());
53 | }
54 |
55 | public static HttpMethod of(HttpServerExchange exchange) {
56 | return methods.getOrDefault(exchange.getRequestMethod(), GET);
57 | }
58 |
59 | public static Optional find(String method) {
60 | if (method == null || method.isEmpty()) {
61 | return Optional.empty();
62 | }
63 | String m = method.toUpperCase();
64 | return Optional.ofNullable(methods.get(new HttpString(m))).map(
65 | hm -> hm.rawdata);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Request.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import io.undertow.server.HttpServerExchange;
19 |
20 | import java.io.File;
21 | import java.util.List;
22 | import java.util.Map;
23 | import java.util.Optional;
24 |
25 | /**
26 | * @author taichi
27 | */
28 | public interface Request extends AttributeContainer {
29 |
30 | HttpMethod method();
31 |
32 | String path();
33 |
34 | /**
35 | * get path parameter
36 | *
37 | * @param key
38 | * @return
39 | */
40 | Optional params(String key);
41 |
42 | Map params();
43 |
44 | /**
45 | * get query parameter
46 | *
47 | * @param key
48 | * @return
49 | */
50 | Optional query(String key);
51 |
52 | Optional header(String name);
53 |
54 | List headers(String name);
55 |
56 | Map> headers();
57 |
58 | Map cookies();
59 |
60 | Optional cookie(String name);
61 |
62 | Optional form(String key);
63 |
64 | List forms(String key);
65 |
66 | Map> forms();
67 |
68 | Optional file(String key);
69 |
70 | List files(String key);
71 |
72 | Map> files();
73 |
74 | Optional body();
75 |
76 | /**
77 | * get current session or create new session.
78 | *
79 | * @return session
80 | */
81 | Session session();
82 |
83 | /**
84 | * get current session
85 | *
86 | * @return session or empty
87 | */
88 | Optional current();
89 |
90 | boolean xhr();
91 |
92 | String protocol();
93 |
94 | String scheme();
95 |
96 | HttpServerExchange raw();
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/siden-example/src/main/java/example/UseHandlebars.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package example;
17 |
18 | import ninja.siden.App;
19 | import ninja.siden.Config;
20 | import ninja.siden.Renderer;
21 | import ninja.siden.RendererRepository;
22 | import ninja.siden.util.Suppress;
23 |
24 | import com.github.jknack.handlebars.Handlebars;
25 | import com.github.jknack.handlebars.Template;
26 | import com.github.jknack.handlebars.io.ClassPathTemplateLoader;
27 | import com.github.jknack.handlebars.io.TemplateLoader;
28 |
29 | /**
30 | * @author taichi
31 | */
32 | public class UseHandlebars {
33 |
34 | public static void main(String[] args) throws Exception {
35 | App app = App.configure(conf -> {
36 | conf.set(Config.RENDERER_REPOSITORY, new HandleBarsRepo());
37 | return conf;
38 | });
39 |
40 | // see. https://github.com/jknack/handlebars.java
41 | Handlebars engine = new Handlebars();
42 | Template t = engine.compileInline("Hello {{this}}!");
43 |
44 | // use handlebars simply
45 | app.get("/bars",
46 | (req, res) -> res.render("john", Renderer.of(t::apply)));
47 |
48 | // read template from templates/say/hello.html
49 | app.get("/hello",
50 | (req, res) -> res.render(new User("peter"), "say/hello"));
51 |
52 | app.listen().addShutdownHook();
53 | }
54 |
55 | static class HandleBarsRepo implements RendererRepository {
56 | final Handlebars engine;
57 |
58 | public HandleBarsRepo() {
59 | TemplateLoader loader = new ClassPathTemplateLoader();
60 | loader.setPrefix("/templates");
61 | loader.setSuffix(".html");
62 | engine = new Handlebars(loader);
63 | }
64 |
65 | @Override
66 | public Renderer find(String path) {
67 | Template t = Suppress.get(() -> engine.compile(path));
68 | return Renderer.of(t::apply);
69 | }
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/internal/Core.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import io.undertow.server.HttpHandler;
19 | import io.undertow.server.HttpServerExchange;
20 | import io.undertow.util.AttachmentKey;
21 |
22 | import java.util.function.Predicate;
23 |
24 | import ninja.siden.Request;
25 | import ninja.siden.Response;
26 |
27 | import org.xnio.OptionMap;
28 |
29 | /**
30 | * @author taichi
31 | */
32 | public class Core implements HttpHandler {
33 |
34 | public static final AttachmentKey CONFIG = AttachmentKey
35 | .create(OptionMap.class);
36 |
37 | public static final AttachmentKey REQUEST = AttachmentKey
38 | .create(Request.class);
39 |
40 | public static final AttachmentKey RESPONSE = AttachmentKey
41 | .create(Response.class);
42 |
43 | final OptionMap config;
44 | final HttpHandler next;
45 |
46 | public Core(OptionMap config, HttpHandler next) {
47 | super();
48 | this.config = config;
49 | this.next = next;
50 | }
51 |
52 | @Override
53 | public void handleRequest(HttpServerExchange exchange) throws Exception {
54 | exchange.putAttachment(CONFIG, config);
55 | exchange.putAttachment(REQUEST, new SidenRequest(exchange));
56 | exchange.putAttachment(RESPONSE, new SidenResponse(exchange));
57 | exchange.addExchangeCompleteListener((ex, next) -> {
58 | try {
59 | exchange.removeAttachment(CONFIG);
60 | exchange.removeAttachment(REQUEST);
61 | exchange.removeAttachment(RESPONSE);
62 | } finally {
63 | next.proceed();
64 | }
65 | });
66 | next.handleRequest(exchange);
67 | }
68 |
69 | public static io.undertow.predicate.Predicate adapt(Predicate fn) {
70 | return exchange -> {
71 | Request request = exchange.getAttachment(Core.REQUEST);
72 | return fn.test(request);
73 | };
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/Connection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden;
17 |
18 | import io.undertow.websockets.core.WebSocketChannel;
19 |
20 | import java.io.OutputStream;
21 | import java.io.Writer;
22 | import java.nio.ByteBuffer;
23 | import java.util.List;
24 | import java.util.Map;
25 | import java.util.Optional;
26 | import java.util.Set;
27 | import java.util.concurrent.CompletableFuture;
28 |
29 | import ninja.siden.util.ExceptionalConsumer;
30 |
31 | /**
32 | * @author taichi
33 | * @see io.undertow.websockets.core.WebSocketChannel
34 | */
35 | public interface Connection extends AttributeContainer {
36 |
37 | // endpoint methods
38 |
39 | CompletableFuture send(String text);
40 |
41 | CompletableFuture send(ByteBuffer payload);
42 |
43 | CompletableFuture ping(ByteBuffer payload);
44 |
45 | CompletableFuture pong(ByteBuffer payload);
46 |
47 | CompletableFuture close();
48 |
49 | CompletableFuture close(int code, String reason);
50 |
51 | void sendStream(ExceptionalConsumer fn);
52 |
53 | void sendWriter(ExceptionalConsumer fn);
54 |
55 | // informations
56 |
57 | String protocolVersion();
58 |
59 | String subProtocol();
60 |
61 | boolean secure();
62 |
63 | boolean open();
64 |
65 | Set peers();
66 |
67 | // from request
68 |
69 | Optional params(String key);
70 |
71 | Map params();
72 |
73 | Optional query(String key);
74 |
75 | Optional header(String name);
76 |
77 | List headers(String name);
78 |
79 | Map> headers();
80 |
81 | Map cookies();
82 |
83 | Optional cookie(String name);
84 |
85 | /**
86 | * get current session
87 | *
88 | * @return session or empty
89 | */
90 | Optional current();
91 |
92 | WebSocketChannel raw();
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/internal/FiltersHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import io.undertow.server.HttpHandler;
19 | import io.undertow.server.HttpServerExchange;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 |
24 | import ninja.siden.FilterChain;
25 | import ninja.siden.Request;
26 | import ninja.siden.Response;
27 | import ninja.siden.def.FilterDef;
28 |
29 | /**
30 | * @author taichi
31 | */
32 | public class FiltersHandler implements HttpHandler {
33 |
34 | HttpHandler next;
35 |
36 | List filters = new ArrayList<>();
37 |
38 | public FiltersHandler(HttpHandler next) {
39 | this.next = next;
40 | }
41 |
42 | @Override
43 | public void handleRequest(HttpServerExchange exchange) throws Exception {
44 | if (filters.size() < 1) {
45 | next.handleRequest(exchange);
46 | return;
47 | }
48 | SimpleChain chain = new SimpleChain(exchange);
49 | chain.next();
50 | }
51 |
52 | public void add(FilterDef model) {
53 | this.filters.add(model);
54 | }
55 |
56 | enum ChainState {
57 | HasNext, NoMore;
58 | }
59 |
60 | class SimpleChain implements FilterChain {
61 |
62 | int cursor;
63 |
64 | HttpServerExchange exchange;
65 |
66 | Request request;
67 |
68 | Response response;
69 |
70 | public SimpleChain(HttpServerExchange exchange) {
71 | super();
72 | this.exchange = exchange;
73 | this.request = exchange.getAttachment(Core.REQUEST);
74 | this.response = exchange.getAttachment(Core.RESPONSE);
75 | }
76 |
77 | @Override
78 | public Object next() throws Exception {
79 | for (int index = cursor++; index < filters.size(); index = cursor++) {
80 | FilterDef f = filters.get(index);
81 | if (f.resolve(exchange)) {
82 | f.filter(request, response, this);
83 | return ChainState.HasNext;
84 | }
85 | }
86 | next.handleRequest(exchange);
87 | return ChainState.NoMore;
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/siden-example/assets/chat.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Simple WebSocket Chat
7 |
8 |
9 |
10 |
17 |
52 |
53 |
54 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/siden-core/src/main/java/ninja/siden/jmx/RequestMetrics.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.jmx;
17 |
18 | import io.undertow.server.handlers.MetricsHandler;
19 | import io.undertow.server.handlers.MetricsHandler.MetricResult;
20 |
21 | import java.beans.ConstructorProperties;
22 | import java.util.Date;
23 |
24 | /**
25 | * @author taichi
26 | */
27 | public class RequestMetrics {
28 |
29 | Date metricsStartDate;
30 |
31 | long totalRequestTime;
32 | long maxRequestTime;
33 | long minRequestTime;
34 | long totalRequests;
35 |
36 | @ConstructorProperties({ "metricsStartDate", "totalRequestTime",
37 | "maxRequestTime", "minRequestTime", "totalRequests" })
38 | public RequestMetrics(Date metricsStartDate, long totalRequestTime,
39 | long maxRequestTime, long minRequestTime, long totalRequests) {
40 | super();
41 | this.metricsStartDate = metricsStartDate;
42 | this.totalRequestTime = totalRequestTime;
43 | this.maxRequestTime = maxRequestTime;
44 | this.minRequestTime = minRequestTime;
45 | this.totalRequests = totalRequests;
46 | }
47 |
48 | public static RequestMXBean to(MetricsHandler handler) {
49 | return new RequestMXBean() {
50 |
51 | @Override
52 | public void reset() {
53 | handler.reset();
54 | }
55 |
56 | @Override
57 | public RequestMetrics getMetrics() {
58 | MetricResult result = handler.getMetrics();
59 | return new RequestMetrics(result.getMetricsStartDate(),
60 | result.getTotalRequestTime(),
61 | result.getMaxRequestTime(), result.getMinRequestTime(),
62 | result.getTotalRequests());
63 | }
64 | };
65 | }
66 |
67 | public Date getMetricsStartDate() {
68 | return this.metricsStartDate;
69 | }
70 |
71 | public long getTotalRequestTime() {
72 | return this.totalRequestTime;
73 | }
74 |
75 | public long getMaxRequestTime() {
76 | return this.maxRequestTime;
77 | }
78 |
79 | public long getMinRequestTime() {
80 | return this.minRequestTime;
81 | }
82 |
83 | public long getTotalRequests() {
84 | return this.totalRequests;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/siden-core/src/test/java/ninja/siden/internal/MIMEPredicateTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 SATO taichi
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package ninja.siden.internal;
17 |
18 | import static org.junit.Assert.assertEquals;
19 | import io.undertow.predicate.Predicate;
20 | import io.undertow.server.HttpServerExchange;
21 | import io.undertow.util.Headers;
22 |
23 | import java.util.Arrays;
24 |
25 | import org.junit.Before;
26 | import org.junit.Test;
27 | import org.junit.runner.RunWith;
28 | import org.junit.runners.Parameterized;
29 | import org.junit.runners.Parameterized.Parameters;
30 |
31 | /**
32 | * @author taichi
33 | */
34 | @RunWith(Parameterized.class)
35 | public class MIMEPredicateTest {
36 |
37 | HttpServerExchange exchange;
38 |
39 | @Before
40 | public void setUp() {
41 | this.exchange = new HttpServerExchange(null);
42 | }
43 |
44 | String wait;
45 |
46 | String request;
47 |
48 | boolean is;
49 |
50 | public MIMEPredicateTest(String wait, String request, boolean is) {
51 | this.wait = wait;
52 | this.request = request;
53 | this.is = is;
54 | }
55 |
56 | @Parameters(name = "{0} {1}")
57 | public static Iterable