Skip to content

Commit df8e05f

Browse files
committed
dsl chapter
1 parent b5c11a2 commit df8e05f

File tree

12 files changed

+808
-0
lines changed

12 files changed

+808
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2005 JBoss Inc
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+
17+
package lambdasinaction.dsl;
18+
19+
import lambdasinaction.chap5.Dish;
20+
21+
import java.util.List;
22+
import java.util.Map;
23+
import java.util.function.Function;
24+
import java.util.stream.Collector;
25+
26+
import static java.util.stream.Collectors.groupingBy;
27+
import static lambdasinaction.chap5.Dish.menu;
28+
import static lambdasinaction.dsl.Grouping.GroupingBuilder.groupOn;
29+
30+
public class Grouping {
31+
32+
enum CaloricLevel { DIET, NORMAL, FAT };
33+
34+
public static void main(String ... args) {
35+
System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel2());
36+
System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel3());
37+
}
38+
39+
private static CaloricLevel getCaloricLevel( Dish dish ) {
40+
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
41+
else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
42+
else return CaloricLevel.FAT;
43+
}
44+
45+
private static Map<Dish.Type, Map<CaloricLevel, List<Dish>>> groupDishedByTypeAndCaloricLevel2() {
46+
return menu.stream().collect(
47+
twoLevelGroupingBy(Dish::getType, dish -> getCaloricLevel( dish ) )
48+
);
49+
}
50+
51+
public static <A, B, T> Collector<T, ?, Map<A, Map<B, List<T>>>> twoLevelGroupingBy(Function<? super T, ? extends A> f1, Function<? super T, ? extends B> f2) {
52+
return groupingBy(f1, groupingBy(f2));
53+
}
54+
55+
private static Map<Dish.Type, Map<CaloricLevel, List<Dish>>> groupDishedByTypeAndCaloricLevel3() {
56+
Collector<? super Dish, ?, Map<Dish.Type, Map<CaloricLevel, List<Dish>>>> c = groupOn( ( Dish dish ) -> getCaloricLevel( dish ) ).after( Dish::getType ).get();
57+
return menu.stream().collect( c );
58+
}
59+
60+
public static class GroupingBuilder<T, D, K> {
61+
private final Collector<? super T, ?, Map<K, D>> collector;
62+
63+
public GroupingBuilder( Collector<? super T, ?, Map<K, D>> collector ) {
64+
this.collector = collector;
65+
}
66+
67+
public Collector<? super T, ?, Map<K, D>> get() {
68+
return collector;
69+
}
70+
71+
public <J> GroupingBuilder<T, Map<K, D>, J> after(Function<? super T, ? extends J> classifier) {
72+
return new GroupingBuilder<>( groupingBy( classifier, collector ) );
73+
}
74+
75+
public static <T, D, K> GroupingBuilder<T, List<T>, K> groupOn(Function<? super T, ? extends K> classifier) {
76+
return new GroupingBuilder<>( groupingBy( classifier ) );
77+
}
78+
}
79+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2005 JBoss Inc
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+
17+
package lambdasinaction.dsl;
18+
19+
import lambdasinaction.dsl.model.Order;
20+
import lambdasinaction.dsl.model.Stock;
21+
import lambdasinaction.dsl.model.Trade;
22+
23+
import java.util.function.Consumer;
24+
25+
public class LambdaOrderBuilder {
26+
27+
private Order order = new Order();
28+
29+
public static Order order(Consumer<LambdaOrderBuilder> consumer) {
30+
LambdaOrderBuilder builder = new LambdaOrderBuilder();
31+
consumer.accept( builder );
32+
return builder.order;
33+
}
34+
35+
public void forCustomer(String customer) {
36+
order.setCustomer( customer );
37+
}
38+
39+
public void buy(Consumer<TradeBuilder> consumer) {
40+
trade( consumer, Trade.Type.BUY );
41+
}
42+
43+
public void sell(Consumer<TradeBuilder> consumer) {
44+
trade( consumer, Trade.Type.SELL );
45+
}
46+
47+
private void trade( Consumer<TradeBuilder> consumer, Trade.Type type ) {
48+
TradeBuilder builder = new TradeBuilder();
49+
builder.trade.setType( type );
50+
consumer.accept( builder );
51+
order.addTrade( builder.trade );
52+
}
53+
54+
public static class TradeBuilder {
55+
private Trade trade = new Trade();
56+
57+
public void quantity(int quantity) {
58+
trade.setQuantity( quantity );
59+
}
60+
61+
public void price(double price) {
62+
trade.setPrice( price );
63+
}
64+
65+
public void stock(Consumer<StockBuilder> consumer) {
66+
StockBuilder builder = new StockBuilder();
67+
consumer.accept( builder );
68+
trade.setStock( builder.stock );
69+
}
70+
}
71+
72+
public static class StockBuilder {
73+
private Stock stock = new Stock();
74+
75+
public void symbol(String symbol) {
76+
stock.setSymbol( symbol );
77+
}
78+
79+
public void market(String market) {
80+
stock.setMarket( market );
81+
}
82+
}
83+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2005 JBoss Inc
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+
17+
package lambdasinaction.dsl;
18+
19+
import lambdasinaction.dsl.model.Order;
20+
import lambdasinaction.dsl.model.Stock;
21+
import lambdasinaction.dsl.model.Trade;
22+
23+
import static lambdasinaction.dsl.MethodChainingOrderBuilder.forCustomer;
24+
import static lambdasinaction.dsl.NestedFunctionOrderBuilder.*;
25+
26+
public class Main {
27+
28+
public void plain() {
29+
Order order = new Order();
30+
order.setCustomer( "BigBank" );
31+
32+
Trade trade1 = new Trade();
33+
trade1.setType( Trade.Type.BUY );
34+
35+
Stock stock1 = new Stock();
36+
stock1.setSymbol( "IBM" );
37+
stock1.setMarket( "NYSE" );
38+
39+
trade1.setStock( stock1 );
40+
trade1.setPrice( 125.00 );
41+
trade1.setQuantity( 80 );
42+
order.addTrade( trade1 );
43+
44+
Trade trade2 = new Trade();
45+
trade2.setType( Trade.Type.BUY );
46+
47+
Stock stock2 = new Stock();
48+
stock2.setSymbol( "GOOGLE" );
49+
stock2.setMarket( "NASDAQ" );
50+
51+
trade2.setStock( stock2 );
52+
trade2.setPrice( 375.00 );
53+
trade2.setQuantity( 50 );
54+
order.addTrade( trade2 );
55+
}
56+
57+
public void methodChaining() {
58+
Order order = forCustomer( "BigBank" )
59+
.buy( 80 ).stock( "IBM" ).on( "NYSE" ).at( 125.00 )
60+
.sell( 50 ).stock( "GOOGLE" ).on( "NASDAQ" ).at( 375.00 )
61+
.end();
62+
63+
}
64+
65+
public void nestedFunction() {
66+
Order order = order("BigBank",
67+
buy(80,
68+
stock( "IBM", on( "NYSE" ) ),
69+
at(125.00)),
70+
sell(50,
71+
stock("GOOGLE", on("NASDAQ")),
72+
at(375.00))
73+
);
74+
}
75+
76+
public void lambda() {
77+
Order order = LambdaOrderBuilder.order( o -> {
78+
o.forCustomer( "BigBank" );
79+
o.buy( t -> {
80+
t.quantity( 80 );
81+
t.price( 125.00 );
82+
t.stock( s -> {
83+
s.symbol( "IBM" );
84+
s.market( "NYSE" );
85+
} );
86+
});
87+
o.sell( t -> {
88+
t.quantity( 50 );
89+
t.price( 375.00 );
90+
t.stock( s -> {
91+
s.symbol( "GOOGLE" );
92+
s.market( "NASDAQ" );
93+
} );
94+
});
95+
} );
96+
}
97+
98+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2005 JBoss Inc
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+
17+
package lambdasinaction.dsl;
18+
19+
import lambdasinaction.dsl.model.Order;
20+
import lambdasinaction.dsl.model.Stock;
21+
import lambdasinaction.dsl.model.Trade;
22+
23+
public class MethodChainingOrderBuilder {
24+
25+
public final Order order = new Order();
26+
27+
private MethodChainingOrderBuilder(String customer) {
28+
order.setCustomer( customer );
29+
}
30+
31+
public static MethodChainingOrderBuilder forCustomer( String customer ) {
32+
return new MethodChainingOrderBuilder(customer);
33+
}
34+
35+
public Order end() {
36+
return order;
37+
}
38+
39+
public TradeBuilder buy(int quantity) {
40+
return new TradeBuilder( this, Trade.Type.BUY, quantity );
41+
}
42+
43+
public TradeBuilder sell(int quantity) {
44+
return new TradeBuilder( this, Trade.Type.SELL, quantity );
45+
}
46+
47+
private MethodChainingOrderBuilder addTrade(Trade trade) {
48+
order.addTrade( trade );
49+
return this;
50+
}
51+
52+
public static class TradeBuilder {
53+
private final MethodChainingOrderBuilder builder;
54+
public final Trade trade = new Trade();
55+
56+
private TradeBuilder(MethodChainingOrderBuilder builder, Trade.Type type, int quantity) {
57+
this.builder = builder;
58+
trade.setType( type );
59+
trade.setQuantity( quantity );
60+
}
61+
62+
public StockBuilder stock(String symbol) {
63+
return new StockBuilder( builder, trade, symbol );
64+
}
65+
}
66+
67+
public static class TradeBuilderWithStock {
68+
private final MethodChainingOrderBuilder builder;
69+
private final Trade trade;
70+
71+
public TradeBuilderWithStock( MethodChainingOrderBuilder builder, Trade trade ) {
72+
this.builder = builder;
73+
this.trade = trade;
74+
}
75+
76+
public MethodChainingOrderBuilder at(double price) {
77+
trade.setPrice( price );
78+
return builder.addTrade( trade );
79+
}
80+
}
81+
82+
public static class StockBuilder {
83+
private final MethodChainingOrderBuilder builder;
84+
private final Trade trade;
85+
private final Stock stock = new Stock();
86+
87+
private StockBuilder(MethodChainingOrderBuilder builder, Trade trade, String symbol) {
88+
this.builder = builder;
89+
this.trade = trade;
90+
stock.setSymbol( symbol );
91+
}
92+
93+
public TradeBuilderWithStock on(String market) {
94+
stock.setMarket( market );
95+
trade.setStock( stock );
96+
return new TradeBuilderWithStock( builder, trade );
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)