Merge remote-tracking branch 'eugenp/master'
This commit is contained in:
commit
41b847381b
|
@ -1,3 +0,0 @@
|
|||
[submodule "testgitrepo"]
|
||||
path = testgitrepo
|
||||
url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/
|
|
@ -22,3 +22,6 @@
|
|||
- [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words)
|
||||
- [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations)
|
||||
- [Find All Pairs of Numbers in an Array That Add Up to a Given Sum](http://www.baeldung.com/java-algorithm-number-pairs-sum)
|
||||
- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic)
|
||||
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
|
||||
- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element)
|
||||
|
|
|
@ -10,7 +10,7 @@ public class MonteCarloTreeSearch {
|
|||
|
||||
private static final int WIN_SCORE = 10;
|
||||
private int level;
|
||||
private int oponent;
|
||||
private int opponent;
|
||||
|
||||
public MonteCarloTreeSearch() {
|
||||
this.level = 3;
|
||||
|
@ -32,11 +32,11 @@ public class MonteCarloTreeSearch {
|
|||
long start = System.currentTimeMillis();
|
||||
long end = start + 60 * getMillisForCurrentLevel();
|
||||
|
||||
oponent = 3 - playerNo;
|
||||
opponent = 3 - playerNo;
|
||||
Tree tree = new Tree();
|
||||
Node rootNode = tree.getRoot();
|
||||
rootNode.getState().setBoard(board);
|
||||
rootNode.getState().setPlayerNo(oponent);
|
||||
rootNode.getState().setPlayerNo(opponent);
|
||||
|
||||
while (System.currentTimeMillis() < end) {
|
||||
// Phase 1 - Selection
|
||||
|
@ -93,7 +93,7 @@ public class MonteCarloTreeSearch {
|
|||
State tempState = tempNode.getState();
|
||||
int boardStatus = tempState.getBoard().checkStatus();
|
||||
|
||||
if (boardStatus == oponent) {
|
||||
if (boardStatus == opponent) {
|
||||
tempNode.getParent().getState().setWinScore(Integer.MIN_VALUE);
|
||||
return boardStatus;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Java with ANTLR](http://www.baeldung.com/java-antlr)
|
|
@ -0,0 +1,60 @@
|
|||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Transform: 'AWS::Serverless-2016-10-31'
|
||||
Description: Baeldung Serverless Application Model Example with Implicit API Definition
|
||||
Globals:
|
||||
Api:
|
||||
EndpointConfiguration: REGIONAL
|
||||
Name: "TestAPI"
|
||||
Resources:
|
||||
PersonTable:
|
||||
Type: AWS::Serverless::SimpleTable
|
||||
Properties:
|
||||
PrimaryKey:
|
||||
Name: id
|
||||
Type: Number
|
||||
TableName: Person
|
||||
StorePersonFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleRequest
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
StoreApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: PUT
|
||||
GetPersonByHTTPParamFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByParam
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBReadPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
GetByPathApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons/{id}
|
||||
Method: GET
|
||||
GetByQueryApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: GET
|
|
@ -0,0 +1,112 @@
|
|||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Transform: 'AWS::Serverless-2016-10-31'
|
||||
Description: Baeldung Serverless Application Model Example with Inline Swagger API Definition
|
||||
Resources:
|
||||
PersonTable:
|
||||
Type: AWS::Serverless::SimpleTable
|
||||
Properties:
|
||||
PrimaryKey:
|
||||
Name: id
|
||||
Type: Number
|
||||
TableName: Person
|
||||
StorePersonFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleRequest
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
StoreApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: PUT
|
||||
RestApiId:
|
||||
Ref: MyApi
|
||||
GetPersonByHTTPParamFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByParam
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBReadPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
GetByPathApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons/{id}
|
||||
Method: GET
|
||||
RestApiId:
|
||||
Ref: MyApi
|
||||
GetByQueryApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: GET
|
||||
RestApiId:
|
||||
Ref: MyApi
|
||||
MyApi:
|
||||
Type: AWS::Serverless::Api
|
||||
Properties:
|
||||
StageName: test
|
||||
EndpointConfiguration: REGIONAL
|
||||
DefinitionBody:
|
||||
swagger: "2.0"
|
||||
info:
|
||||
title: "TestAPI"
|
||||
paths:
|
||||
/persons:
|
||||
get:
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "query"
|
||||
required: true
|
||||
type: "string"
|
||||
x-amazon-apigateway-request-validator: "Validate query string parameters and\
|
||||
\ headers"
|
||||
x-amazon-apigateway-integration:
|
||||
uri:
|
||||
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByHTTPParamFunction.Arn}/invocations
|
||||
responses: {}
|
||||
httpMethod: "POST"
|
||||
type: "aws_proxy"
|
||||
put:
|
||||
x-amazon-apigateway-integration:
|
||||
uri:
|
||||
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${StorePersonFunction.Arn}/invocations
|
||||
responses: {}
|
||||
httpMethod: "POST"
|
||||
type: "aws_proxy"
|
||||
/persons/{id}:
|
||||
get:
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
required: true
|
||||
type: "string"
|
||||
responses: {}
|
||||
x-amazon-apigateway-integration:
|
||||
uri:
|
||||
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByHTTPParamFunction.Arn}/invocations
|
||||
responses: {}
|
||||
httpMethod: "POST"
|
||||
type: "aws_proxy"
|
||||
x-amazon-apigateway-request-validators:
|
||||
Validate query string parameters and headers:
|
||||
validateRequestParameters: true
|
||||
validateRequestBody: false
|
|
@ -36,9 +36,7 @@ public class APIDemoHandler implements RequestStreamHandler {
|
|||
|
||||
dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||
.putItem(new PutItemSpec().withItem(new Item().withNumber("id", person.getId())
|
||||
.withString("firstName", person.getFirstName())
|
||||
.withString("lastName", person.getLastName()).withNumber("age", person.getAge())
|
||||
.withString("address", person.getAddress())));
|
||||
.withString("name", person.getName())));
|
||||
}
|
||||
|
||||
JSONObject responseBody = new JSONObject();
|
||||
|
@ -61,8 +59,7 @@ public class APIDemoHandler implements RequestStreamHandler {
|
|||
writer.close();
|
||||
}
|
||||
|
||||
public void handleGetByPathParam(InputStream inputStream, OutputStream outputStream, Context context)
|
||||
throws IOException {
|
||||
public void handleGetByParam(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
@ -81,61 +78,20 @@ public class APIDemoHandler implements RequestStreamHandler {
|
|||
if (pps.get("id") != null) {
|
||||
|
||||
int id = Integer.parseInt((String) pps.get("id"));
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||
.getItem("id", id);
|
||||
}
|
||||
|
||||
}
|
||||
if (result != null) {
|
||||
|
||||
Person person = new Person(result.toJSON());
|
||||
responseBody.put("Person", person);
|
||||
responseJson.put("statusCode", 200);
|
||||
} else {
|
||||
|
||||
responseBody.put("message", "No item found");
|
||||
responseJson.put("statusCode", 404);
|
||||
}
|
||||
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public void handleGetByQueryParam(InputStream inputStream, OutputStream outputStream, Context context)
|
||||
throws IOException {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
|
||||
Item result = null;
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
JSONObject responseBody = new JSONObject();
|
||||
|
||||
if (event.get("queryStringParameters") != null) {
|
||||
} else if (event.get("queryStringParameters") != null) {
|
||||
|
||||
JSONObject qps = (JSONObject) event.get("queryStringParameters");
|
||||
if (qps.get("id") != null) {
|
||||
|
||||
int id = Integer.parseInt((String) qps.get("id"));
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||
.getItem("id", id);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
|
||||
Person person = new Person(result.toJSON());
|
||||
|
@ -162,5 +118,4 @@ public class APIDemoHandler implements RequestStreamHandler {
|
|||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,19 +6,13 @@ import com.google.gson.GsonBuilder;
|
|||
public class Person {
|
||||
|
||||
private int id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private int age;
|
||||
private String address;
|
||||
private String name;
|
||||
|
||||
public Person(String json) {
|
||||
Gson gson = new Gson();
|
||||
Person request = gson.fromJson(json, Person.class);
|
||||
this.id = request.getId();
|
||||
this.firstName = request.getFirstName();
|
||||
this.lastName = request.getLastName();
|
||||
this.age = request.getAge();
|
||||
this.address = request.getAddress();
|
||||
this.name = request.getName();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -34,35 +28,11 @@ public class Person {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
### Relevant Articles:
|
||||
- [CDI Interceptor vs Spring AspectJ](http://www.baeldung.com/cdi-interceptor-vs-spring-aspectj)
|
||||
- [An Introduction to CDI (Contexts and Dependency Injection) in Java](http://www.baeldung.com/java-ee-cdi)
|
||||
|
|
|
@ -54,3 +54,5 @@
|
|||
- [An Introduction to Java.util.Hashtable Class](http://www.baeldung.com/java-hash-table)
|
||||
- [Method Parameter Reflection in Java](http://www.baeldung.com/java-parameter-reflection)
|
||||
- [Java 8 Unsigned Arithmetic Support](http://www.baeldung.com/java-unsigned-arithmetic)
|
||||
- [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end)
|
||||
- [Generalized Target-Type Inference in Java](http://www.baeldung.com/java-generalized-target-type-inference)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.fileToBase64StringConversion;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
public class FileToBase64StringConversionUnitTest {
|
||||
|
||||
private String inputFilePath = "test_image.jpg";
|
||||
private String outputFilePath = "test_image_copy.jpg";
|
||||
|
||||
@Test
|
||||
public void fileToBase64StringConversion() throws IOException {
|
||||
//load file from /src/test/resources
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
File inputFile = new File(classLoader
|
||||
.getResource(inputFilePath)
|
||||
.getFile());
|
||||
|
||||
byte[] fileContent = FileUtils.readFileToByteArray(inputFile);
|
||||
String encodedString = Base64
|
||||
.getEncoder()
|
||||
.encodeToString(fileContent);
|
||||
|
||||
//create output file
|
||||
File outputFile = new File(inputFile
|
||||
.getParentFile()
|
||||
.getAbsolutePath() + File.pathSeparator + outputFilePath);
|
||||
|
||||
// decode the string and write to file
|
||||
byte[] decodedBytes = Base64
|
||||
.getDecoder()
|
||||
.decode(encodedString);
|
||||
FileUtils.writeByteArrayToFile(outputFile, decodedBytes);
|
||||
|
||||
assertTrue(FileUtils.contentEquals(inputFile, outputFile));
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,80 @@
|
|||
package com.baeldung.java.list;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.apache.commons.collections4.iterators.ReverseListIterator;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Provides methods for iterating backward over a list.
|
||||
*/
|
||||
public class ReverseIterator {
|
||||
|
||||
/**
|
||||
* Iterate using the for loop.
|
||||
*
|
||||
* @param list the list
|
||||
*/
|
||||
public void iterateUsingForLoop(final List<String> list) {
|
||||
|
||||
for (int i = list.size(); i-- > 0; ) {
|
||||
System.out.println(list.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate using the Java {@link ListIterator}.
|
||||
*
|
||||
* @param list the list
|
||||
*/
|
||||
public void iterateUsingListIterator(final List<String> list) {
|
||||
|
||||
final ListIterator listIterator = list.listIterator(list.size());
|
||||
while (listIterator.hasPrevious()) {
|
||||
System.out.println(listIterator.previous());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate using Java {@link Collections} API.
|
||||
*
|
||||
* @param list the list
|
||||
*/
|
||||
public void iterateUsingCollections(final List<String> list) {
|
||||
|
||||
Collections.reverse(list);
|
||||
for (final String item : list) {
|
||||
System.out.println(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate using Apache Commons {@link ReverseListIterator}.
|
||||
*
|
||||
* @param list the list
|
||||
*/
|
||||
public void iterateUsingApacheReverseListIterator(final List<String> list) {
|
||||
|
||||
final ReverseListIterator listIterator = new ReverseListIterator(list);
|
||||
while (listIterator.hasNext()) {
|
||||
System.out.println(listIterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate using Guava {@link Lists} API.
|
||||
*
|
||||
* @param list the list
|
||||
*/
|
||||
public void iterateUsingGuava(final List<String> list) {
|
||||
|
||||
final List<String> reversedList = Lists.reverse(list);
|
||||
for (final String item : reversedList) {
|
||||
System.out.println(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package com.baeldung.java.list;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.apache.commons.collections4.iterators.ReverseListIterator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class ReverseIteratorUnitTest {
|
||||
|
||||
private final ReverseIterator reverseIterator = new ReverseIterator();
|
||||
|
||||
private List<String> list;
|
||||
|
||||
private final String originalString = "ABCDE";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
list = Lists.newArrayList("A", "B", "C", "D", "E");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingUsingForLoop_thenCorrect() {
|
||||
|
||||
String reverseString = "";
|
||||
for (int i = list.size(); i-- > 0; ) {
|
||||
reverseString += list.get(i);
|
||||
}
|
||||
assertEquals(reverseString, StringUtils.reverse(originalString));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingUsingListIterator_thenCorrect() {
|
||||
|
||||
String reverseString = "";
|
||||
final ListIterator listIterator = list.listIterator(list.size());
|
||||
while (listIterator.hasPrevious()) {
|
||||
reverseString += listIterator.previous();
|
||||
}
|
||||
assertEquals(reverseString, StringUtils.reverse(originalString));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingUsingCollections_thenCorrect() {
|
||||
|
||||
String reverseString = "";
|
||||
Collections.reverse(list);
|
||||
for (final String item : list) {
|
||||
reverseString += item;
|
||||
}
|
||||
assertEquals(reverseString, StringUtils.reverse(originalString));
|
||||
|
||||
assertEquals("E", list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingUsingApacheReverseListIterator_thenCorrect() {
|
||||
|
||||
String reverseString = "";
|
||||
final ReverseListIterator listIterator = new ReverseListIterator(list);
|
||||
while (listIterator.hasNext()) {
|
||||
reverseString += listIterator.next();
|
||||
}
|
||||
assertEquals(reverseString, StringUtils.reverse(originalString));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingUsingGuava_thenCorrect() {
|
||||
|
||||
String reverseString = "";
|
||||
final List<String> reversedList = Lists.reverse(list);
|
||||
for (final String item : reversedList) {
|
||||
reverseString += item;
|
||||
}
|
||||
assertEquals(reverseString, StringUtils.reverse(originalString));
|
||||
|
||||
assertEquals("A", list.get(0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.symlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import static java.nio.file.StandardOpenOption.*;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class SymLinkExample {
|
||||
|
||||
public void createSymbolicLink(Path link, Path target) throws IOException {
|
||||
if (Files.exists(link)) {
|
||||
Files.delete(link);
|
||||
}
|
||||
Files.createSymbolicLink(link, target);
|
||||
}
|
||||
|
||||
public void createHardLink(Path link, Path target) throws IOException {
|
||||
if (Files.exists(link)) {
|
||||
Files.delete(link);
|
||||
}
|
||||
Files.createLink(link, target);
|
||||
}
|
||||
|
||||
public Path createTextFile() throws IOException {
|
||||
byte[] content = IntStream.range(0, 10000)
|
||||
.mapToObj(i -> i + System.lineSeparator())
|
||||
.reduce("", String::concat)
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
Path filePath = Paths.get(".", "target_link.txt");
|
||||
Files.write(filePath, content, CREATE, TRUNCATE_EXISTING);
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void printLinkFiles(Path path) throws IOException {
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
|
||||
for (Path file : stream) {
|
||||
if (Files.isDirectory(file)) {
|
||||
printLinkFiles(file);
|
||||
} else if (Files.isSymbolicLink(file)) {
|
||||
System.out.format("File link '%s' with target '%s'%n", file, Files.readSymbolicLink(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new SymLinkExample().printLinkFiles(Paths.get("."));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.symlink;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class SymLinkExampleUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenUsingFiles_thenCreateSymbolicLink() throws IOException {
|
||||
SymLinkExample example = new SymLinkExample();
|
||||
Path filePath = example.createTextFile();
|
||||
Path linkPath = Paths.get(".", "symbolic_link.txt");
|
||||
example.createSymbolicLink(linkPath, filePath);
|
||||
assertTrue(Files.isSymbolicLink(linkPath));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingFiles_thenCreateHardLink() throws IOException {
|
||||
SymLinkExample example = new SymLinkExample();
|
||||
Path filePath = example.createTextFile();
|
||||
Path linkPath = Paths.get(".", "hard_link.txt");
|
||||
example.createHardLink(linkPath, filePath);
|
||||
assertFalse(Files.isSymbolicLink(linkPath));
|
||||
assertEquals(filePath.toFile()
|
||||
.length(),
|
||||
linkPath.toFile()
|
||||
.length());
|
||||
}
|
||||
|
||||
}
|
|
@ -160,3 +160,9 @@
|
|||
- [Guide to the super Java Keyword](http://www.baeldung.com/java-super)
|
||||
- [Guide to the this Java Keyword](http://www.baeldung.com/java-this)
|
||||
- [Jagged Arrays In Java](http://www.baeldung.com/java-jagged-arrays)
|
||||
- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class)
|
||||
- [Extracting Year, Month and Day from Date in Java](http://www.baeldung.com/java-year-month-day)
|
||||
- [Get Date Without Time in Java](http://www.baeldung.com/java-date-without-time)
|
||||
- [Convert a String to Title Case](http://www.baeldung.com/java-string-title-case)
|
||||
- [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension)
|
||||
- [Immutable Objects in Java](http://www.baeldung.com/java-immutable-object)
|
||||
|
|
|
@ -198,11 +198,6 @@
|
|||
<artifactId>mail</artifactId>
|
||||
<version>${javax.mail.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.5.0-b01</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
<artifactId>icu4j</artifactId>
|
||||
|
@ -255,6 +250,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>${maven-jar-plugin.version}</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
|
@ -293,6 +289,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>${maven-shade-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
@ -314,6 +311,7 @@
|
|||
<plugin>
|
||||
<groupId>com.jolira</groupId>
|
||||
<artifactId>onejar-maven-plugin</artifactId>
|
||||
<version>${onejar-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<configuration>
|
||||
|
@ -331,6 +329,7 @@
|
|||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
@ -478,6 +477,10 @@
|
|||
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
|
||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
||||
<javax.mail.version>1.5.0-b01</javax.mail.version>
|
||||
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
||||
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
|
||||
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
|
||||
<spring-boot-maven-plugin.version>2.0.3.RELEASE</spring-boot-maven-plugin.version>
|
||||
<icu4j.version>61.1</icu4j.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.console;
|
||||
|
||||
import java.io.Console;
|
||||
|
||||
public class ConsoleConsoleClass {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Console console = System.console();
|
||||
|
||||
if (console == null) {
|
||||
System.out.print("No console available");
|
||||
return;
|
||||
}
|
||||
|
||||
String progLanguauge = console.readLine("Enter your favourite programming language: ");
|
||||
console.printf(progLanguauge + " is very interesting!");
|
||||
|
||||
char[] pass = console.readPassword("To finish, enter password: ");
|
||||
|
||||
if ("BAELDUNG".equals(pass.toString().toUpperCase()))
|
||||
console.printf("Good! Regards!");
|
||||
else
|
||||
console.printf("Nice try. Regards.");
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.console;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ConsoleScannerClass {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Please enter your name and surname: ");
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
String nameSurname = scanner.nextLine();
|
||||
|
||||
System.out.println("Please enter your gender: ");
|
||||
|
||||
char gender = scanner.next().charAt(0);
|
||||
|
||||
System.out.println("Please enter your age: ");
|
||||
|
||||
int age = scanner.nextInt();
|
||||
|
||||
System.out.println("Please enter your height in meters: ");
|
||||
|
||||
double height = scanner.nextDouble();
|
||||
|
||||
System.out.println(nameSurname + ", " + age + ", is a great " + (gender == 'm' ? "guy" : "girl") + " with " + height + " meters height" + " and " + (gender == 'm' ? "he" : "she") + " reads Baeldung.");
|
||||
|
||||
System.out.print("Have a good");
|
||||
System.out.print(" one!");
|
||||
|
||||
System.out.println("\nPlease enter number of years of experience as a developer: ");
|
||||
|
||||
BufferedReader buffReader = new BufferedReader(new InputStreamReader(System.in));
|
||||
|
||||
int i = 0;
|
||||
|
||||
try {
|
||||
i = Integer.parseInt(buffReader.readLine());
|
||||
} catch (NumberFormatException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("You are a " + (i > 5 ? "great" : "good") + " developer!");
|
||||
|
||||
int sum = 0, count = 0;
|
||||
|
||||
System.out.println("Please enter your college degrees. To finish, enter baeldung website url");
|
||||
|
||||
while (scanner.hasNextInt()) {
|
||||
int nmbr = scanner.nextInt();
|
||||
sum += nmbr;
|
||||
count++;
|
||||
}
|
||||
int mean = sum / count;
|
||||
|
||||
System.out.println("Your average degree is " + mean);
|
||||
|
||||
if (scanner.hasNext(Pattern.compile("www.baeldung.com")))
|
||||
System.out.println("Correct!");
|
||||
else
|
||||
System.out.println("Baeldung website url is www.baeldung.com");
|
||||
|
||||
if (scanner != null)
|
||||
scanner.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.customexception;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class FileManager {
|
||||
|
||||
public static String getFirstLine(String fileName) throws IncorrectFileNameException {
|
||||
try (Scanner file = new Scanner(new File(fileName))) {
|
||||
if (file.hasNextLine()) {
|
||||
return file.nextLine();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Non readable file");
|
||||
}
|
||||
} catch (FileNotFoundException err) {
|
||||
if (!isCorrectFileName(fileName)) {
|
||||
throw new IncorrectFileNameException("Incorrect filename : " + fileName, err);
|
||||
}
|
||||
// Logging etc
|
||||
} catch (IllegalArgumentException err) {
|
||||
if (!containsExtension(fileName)) {
|
||||
throw new IncorrectFileExtensionException("Filename does not contain extension : " + fileName, err);
|
||||
}
|
||||
// Other error cases and logging
|
||||
}
|
||||
return "Default First Line";
|
||||
}
|
||||
|
||||
private static boolean containsExtension(String fileName) {
|
||||
if (fileName.contains(".txt") || fileName.contains(".doc"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isCorrectFileName(String fileName) {
|
||||
if (fileName.equals("wrongFileName.txt"))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.customexception;
|
||||
|
||||
public class IncorrectFileExtensionException extends RuntimeException{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public IncorrectFileExtensionException(String errorMessage, Throwable err) {
|
||||
super(errorMessage, err);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.customexception;
|
||||
|
||||
public class IncorrectFileNameException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public IncorrectFileNameException(String errorMessage, Throwable err) {
|
||||
super(errorMessage, err);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.encrypt;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.io.*;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
class FileEncrypterDecrypter {
|
||||
|
||||
private SecretKey secretKey;
|
||||
private Cipher cipher;
|
||||
|
||||
FileEncrypterDecrypter(SecretKey secretKey, String cipher) throws NoSuchPaddingException, NoSuchAlgorithmException {
|
||||
this.secretKey = secretKey;
|
||||
this.cipher = Cipher.getInstance(cipher);
|
||||
}
|
||||
|
||||
void encrypt(String content, String fileName) throws InvalidKeyException, IOException {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] iv = cipher.getIV();
|
||||
|
||||
try (
|
||||
FileOutputStream fileOut = new FileOutputStream(fileName);
|
||||
CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher)
|
||||
) {
|
||||
fileOut.write(iv);
|
||||
cipherOut.write(content.getBytes());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String decrypt(String fileName) throws InvalidAlgorithmParameterException, InvalidKeyException, IOException {
|
||||
|
||||
String content;
|
||||
|
||||
try (FileInputStream fileIn = new FileInputStream(fileName)) {
|
||||
byte[] fileIv = new byte[16];
|
||||
fileIn.read(fileIv);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(fileIv));
|
||||
|
||||
try (
|
||||
CipherInputStream cipherIn = new CipherInputStream(fileIn, cipher);
|
||||
InputStreamReader inputReader = new InputStreamReader(cipherIn);
|
||||
BufferedReader reader = new BufferedReader(inputReader)
|
||||
) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
content = sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.customexception;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class IncorrectFileExtensionExceptionUnitTest {
|
||||
|
||||
@Test
|
||||
public void testWhenCorrectFileExtensionGiven_ReceivesNoException() throws IncorrectFileNameException {
|
||||
assertThat(FileManager.getFirstLine("correctFileNameWithProperExtension.txt")).isEqualTo("Default First Line");
|
||||
}
|
||||
|
||||
@Test(expected = IncorrectFileExtensionException.class)
|
||||
public void testWhenCorrectFileNameExceptionThrown_ReceivesNoException() throws IncorrectFileNameException {
|
||||
StringBuffer sBuffer = new StringBuffer();
|
||||
sBuffer.append("src");
|
||||
sBuffer.append(File.separator);
|
||||
sBuffer.append("test");
|
||||
sBuffer.append(File.separator);
|
||||
sBuffer.append("resources");
|
||||
sBuffer.append(File.separator);
|
||||
sBuffer.append("correctFileNameWithoutProperExtension");
|
||||
FileManager.getFirstLine(sBuffer.toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.customexception;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class IncorrectFileNameExceptionUnitTest {
|
||||
|
||||
@Test(expected = IncorrectFileNameException.class)
|
||||
public void testWhenIncorrectFileNameExceptionThrown_ReceivesIncorrectFileNameException() throws IncorrectFileNameException {
|
||||
FileManager.getFirstLine("wrongFileName.txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWhenCorrectFileNameExceptionThrown_ReceivesNoException() throws IncorrectFileNameException {
|
||||
assertThat(FileManager.getFirstLine("correctFileName.txt")).isEqualTo("Default First Line");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.encrypt;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class FileEncrypterDecrypterIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenStringAndFilename_whenEncryptingIntoFile_andDecryptingFileAgain_thenOriginalStringIsReturned() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
|
||||
String originalContent = "foobar";
|
||||
SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
|
||||
|
||||
FileEncrypterDecrypter fileEncrypterDecrypter = new FileEncrypterDecrypter(secretKey, "AES/CBC/PKCS5Padding");
|
||||
fileEncrypterDecrypter.encrypt(originalContent, "baz.enc");
|
||||
|
||||
String decryptedContent = fileEncrypterDecrypter.decrypt("baz.enc");
|
||||
assertThat(decryptedContent, is(originalContent));
|
||||
|
||||
new File("baz.enc").delete(); // cleanup
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package com.baeldung.thread.join;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Demonstrates Thread.join behavior.
|
||||
*
|
||||
*/
|
||||
public class ThreadJoinUnitTest {
|
||||
|
||||
final static Logger LOGGER = Logger.getLogger(ThreadJoinUnitTest.class.getName());
|
||||
|
||||
class SampleThread extends Thread {
|
||||
public int processingCount = 0;
|
||||
|
||||
SampleThread(int processingCount) {
|
||||
this.processingCount = processingCount;
|
||||
LOGGER.info("Thread " + this.getName() + " created");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LOGGER.info("Thread " + this.getName() + " started");
|
||||
while (processingCount > 0) {
|
||||
try {
|
||||
Thread.sleep(1000); // Simulate some work being done by thread
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.info("Thread " + this.getName() + " interrupted.");
|
||||
}
|
||||
processingCount--;
|
||||
LOGGER.info("Inside Thread " + this.getName() + ", processingCount = " + processingCount);
|
||||
}
|
||||
LOGGER.info("Thread " + this.getName() + " exiting");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNewThread_whenJoinCalled_returnsImmediately() throws InterruptedException {
|
||||
Thread t1 = new SampleThread(0);
|
||||
LOGGER.info("Invoking join.");
|
||||
t1.join();
|
||||
LOGGER.info("Returned from join");
|
||||
LOGGER.info("Thread state is" + t1.getState());
|
||||
assertFalse(t1.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStartedThread_whenJoinCalled_waitsTillCompletion()
|
||||
throws InterruptedException {
|
||||
Thread t2 = new SampleThread(1);
|
||||
t2.start();
|
||||
LOGGER.info("Invoking join.");
|
||||
t2.join();
|
||||
LOGGER.info("Returned from join");
|
||||
assertFalse(t2.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout()
|
||||
throws InterruptedException {
|
||||
Thread t3 = new SampleThread(10);
|
||||
t3.start();
|
||||
t3.join(1000);
|
||||
assertTrue(t3.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void givenThreadTerminated_checkForEffect_notGuaranteed()
|
||||
throws InterruptedException {
|
||||
SampleThread t4 = new SampleThread(10);
|
||||
t4.start();
|
||||
//not guaranteed to stop even if t4 finishes.
|
||||
do {
|
||||
|
||||
} while (t4.processingCount > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJoinWithTerminatedThread_checkForEffect_guaranteed()
|
||||
throws InterruptedException {
|
||||
SampleThread t4 = new SampleThread(10);
|
||||
t4.start();
|
||||
do {
|
||||
t4.join(100);
|
||||
} while (t4.processingCount > 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +1,14 @@
|
|||
/bin/
|
||||
|
||||
#ignore gradle
|
||||
.gradle/
|
||||
|
||||
|
||||
#ignore build and generated files
|
||||
build/
|
||||
node/
|
||||
out/
|
||||
|
||||
#ignore installed node modules and package lock file
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
|
|
@ -30,3 +30,5 @@
|
|||
- [Lambda Expressions in Kotlin](http://www.baeldung.com/kotlin-lambda-expressions)
|
||||
- [Writing Specifications with Kotlin and Spek](http://www.baeldung.com/kotlin-spek)
|
||||
- [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson)
|
||||
- [Kotlin String Templates](http://www.baeldung.com/kotlin-string-template)
|
||||
- [Java EE 8 Security API](http://www.baeldung.com/java-ee-8-security)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
|
||||
group 'com.baeldung.ktor'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.2.41'
|
||||
ext.ktor_version = '0.9.2'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'application'
|
||||
|
||||
mainClassName = 'APIServer.kt'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
|
||||
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
|
||||
|
||||
kotlin { experimental { coroutines "enable" } }
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url "https://dl.bintray.com/kotlin/ktor" }
|
||||
}
|
||||
sourceSets {
|
||||
main{
|
||||
kotlin{
|
||||
srcDirs 'com/baeldung/ktor'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "io.ktor:ktor-server-netty:$ktor_version"
|
||||
compile "ch.qos.logback:logback-classic:1.2.1"
|
||||
compile "io.ktor:ktor-gson:$ktor_version"
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
implementation 'com.beust:klaxon:3.0.1'
|
||||
|
||||
}
|
||||
task runServer(type: JavaExec) {
|
||||
main = 'APIServer'
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
|
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
|
@ -0,0 +1,84 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
|
@ -33,7 +33,7 @@ fun main(args: Array<String>) {
|
|||
header("X-Developer", "Baeldung")
|
||||
}
|
||||
install(CallLogging) {
|
||||
level = Level.INFO
|
||||
level = Level.DEBUG
|
||||
filter { call -> call.request.path().startsWith("/todo") }
|
||||
filter { call -> call.request.path().startsWith("/author") }
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,2 @@
|
|||
rootProject.name = 'KtorWithKotlin'
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
@file:JvmName("APIServer")
|
||||
|
||||
|
||||
import io.ktor.application.call
|
||||
import io.ktor.application.install
|
||||
import io.ktor.features.CallLogging
|
||||
import io.ktor.features.ContentNegotiation
|
||||
import io.ktor.features.DefaultHeaders
|
||||
import io.ktor.gson.gson
|
||||
import io.ktor.request.path
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.*
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.netty.Netty
|
||||
import org.slf4j.event.Level
|
||||
|
||||
data class Author(val name: String, val website: String)
|
||||
data class ToDo(var id: Int, val name: String, val description: String, val completed: Boolean)
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
val toDoList = ArrayList<ToDo>();
|
||||
val jsonResponse = """{
|
||||
"id": 1,
|
||||
"task": "Pay waterbill",
|
||||
"description": "Pay water bill today",
|
||||
}"""
|
||||
|
||||
|
||||
embeddedServer(Netty, 8080) {
|
||||
install(DefaultHeaders) {
|
||||
header("X-Developer", "Baeldung")
|
||||
}
|
||||
install(CallLogging) {
|
||||
level = Level.DEBUG
|
||||
filter { call -> call.request.path().startsWith("/todo") }
|
||||
filter { call -> call.request.path().startsWith("/author") }
|
||||
}
|
||||
install(ContentNegotiation) {
|
||||
gson {
|
||||
setPrettyPrinting()
|
||||
}
|
||||
}
|
||||
routing() {
|
||||
route("/todo") {
|
||||
post {
|
||||
var toDo = call.receive<ToDo>();
|
||||
toDo.id = toDoList.size;
|
||||
toDoList.add(toDo);
|
||||
call.respond("Added")
|
||||
|
||||
}
|
||||
delete("/{id}") {
|
||||
call.respond(toDoList.removeAt(call.parameters["id"]!!.toInt()));
|
||||
}
|
||||
get("/{id}") {
|
||||
|
||||
call.respond(toDoList[call.parameters["id"]!!.toInt()]);
|
||||
}
|
||||
get {
|
||||
call.respond(toDoList);
|
||||
}
|
||||
}
|
||||
get("/author"){
|
||||
call.respond(Author("Baeldung","baeldung.com"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}.start(wait = true)
|
||||
}
|
|
@ -1 +1,3 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [A Guide to DeltaSpike Data Module](http://www.baeldung.com/deltaspike-data-module)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## EthereumJ
|
||||
## Ethereum
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to EthereumJ](http://www.baeldung.com/ethereumj)
|
|
@ -0,0 +1,242 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.ethereum</groupId>
|
||||
<artifactId>ethereum</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>ethereum</name>
|
||||
|
||||
<!-- Don't Use This - Use the BOM or direct dependency rather than parent -->
|
||||
<!--<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.6.RELEASE</version>
|
||||
</parent>-->
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<tomcat.version>8.5.4</tomcat.version>
|
||||
<ethereumj-core.version>1.5.0-RELEASE</ethereumj-core.version>
|
||||
<web3j.core.version>3.3.1</web3j.core.version>
|
||||
<springframework.version>5.0.5.RELEASE</springframework.version>
|
||||
<spring.boot.version>1.5.6.RELEASE</spring.boot.version>
|
||||
<maven-surefire.version>2.18.1</maven-surefire.version>
|
||||
<mockito.version>1.10.19</mockito.version>
|
||||
<jackson-databind.version>2.5.0</jackson-databind.version>
|
||||
<hamcrest.version>1.3</hamcrest.version>
|
||||
<jackson.version>2.9.3</jackson.version>
|
||||
<javax-jsp.version>2.3.1</javax-jsp.version>
|
||||
<javax-servlet.version>3.1.0</javax-servlet.version>
|
||||
<jsonpath.version>2.4.0</jsonpath.version>
|
||||
<jstl.version>1.2</jstl.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
<slf4j.version>1.7.25</slf4j.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>Ethereum</id>
|
||||
<name>Ethereum</name>
|
||||
<url>https://dl.bintray.com/ethereum/maven/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Boot Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${springframework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Ethereum -->
|
||||
<dependency>
|
||||
<groupId>org.ethereum</groupId>
|
||||
<artifactId>ethereumj-core</artifactId>
|
||||
<version>${ethereumj-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.web3j</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${web3j.core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson Dependencies -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax-servlet.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp.jstl</groupId>
|
||||
<artifactId>jstl-api</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>javax.servlet.jsp-api</artifactId>
|
||||
<version>${javax-jsp.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Testing -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${springframework.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>${hamcrest.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<version>${jsonpath.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>src/main/webapp</warSourceDirectory>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>ethereum</finalName>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.web3j.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.resource.PathResourceResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
@EnableAsync
|
||||
@ComponentScan("com.baeldung.web3j")
|
||||
public class AppConfig implements WebMvcConfigurer {
|
||||
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/").setViewName("index");
|
||||
}
|
||||
|
||||
/**
|
||||
* Static resource locations including themes
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**/*")
|
||||
.addResourceLocations("/", "/resources/")
|
||||
.setCachePeriod(3600)
|
||||
.resourceChain(true)
|
||||
.addResolver(new PathResourceResolver());
|
||||
}
|
||||
|
||||
/**
|
||||
* View resolver for JSP
|
||||
*/
|
||||
@Bean
|
||||
public UrlBasedViewResolver viewResolver() {
|
||||
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
|
||||
resolver.setPrefix("/WEB-INF/jsp/");
|
||||
resolver.setSuffix(".jsp");
|
||||
resolver.setViewClass(JstlView.class);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for async thread bean
|
||||
*
|
||||
* More: https://docs.spring.io/autorepo/docs/spring-framework/5.0.3.RELEASE/javadoc-api/org/springframework/scheduling/SchedulingTaskExecutor.html
|
||||
*/
|
||||
@Bean
|
||||
public Executor asyncExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(2);
|
||||
executor.setMaxPoolSize(2);
|
||||
executor.setQueueCapacity(500);
|
||||
executor.setThreadNamePrefix("CsvThread");
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.web3j.config;
|
||||
|
||||
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
|
||||
|
||||
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
|
||||
|
||||
//AbstractDispatcherServletInitializer override DEFAULT_SERVLET_NAME
|
||||
@Override
|
||||
protected String getServletName() {
|
||||
return "dispatcher";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getRootConfigClasses() {
|
||||
return new Class[]{};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getServletConfigClasses() {
|
||||
return new Class[]{AppConfig.class};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getServletMappings() {
|
||||
return new String[]{"/"};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.web3j.constants;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public static final String API_BLOCK = "/api/block";
|
||||
public static final String API_ACCOUNTS = "/api/accounts";
|
||||
public static final String API_TRANSACTIONS = "/api/transactions";
|
||||
public static final String API_BALANCE = "/api/balance";
|
||||
|
||||
public static final String GENERIC_EXCEPTION = "Exception encountered!";
|
||||
public static final String PLEASE_SUPPLY_REAL_DATA = "Please Supply Real Data!";
|
||||
|
||||
public static final String DEFAULT_ADDRESS = "0x281055afc982d96fab65b3a49cac8b878184cb16";
|
||||
public static final String DEFAULT_CONTRACT_ADDRESS = "00000000000000000000";
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.baeldung.web3j.contracts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import org.web3j.abi.TypeReference;
|
||||
import org.web3j.abi.datatypes.Function;
|
||||
import org.web3j.abi.datatypes.Type;
|
||||
import org.web3j.crypto.Credentials;
|
||||
import org.web3j.protocol.Web3j;
|
||||
import org.web3j.protocol.core.RemoteCall;
|
||||
import org.web3j.protocol.core.methods.response.TransactionReceipt;
|
||||
import org.web3j.tx.Contract;
|
||||
import org.web3j.tx.TransactionManager;
|
||||
|
||||
/**
|
||||
* <p>Auto generated code.
|
||||
* <p><strong>Do not modify!</strong>
|
||||
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
|
||||
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the
|
||||
* <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
|
||||
*
|
||||
* <p>Generated with web3j version 3.3.1.
|
||||
*/
|
||||
public class Example extends Contract {
|
||||
private static final String BINARY = "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029";
|
||||
|
||||
protected static final HashMap<String, String> _addresses;
|
||||
|
||||
static {
|
||||
_addresses = new HashMap<>();
|
||||
}
|
||||
|
||||
protected Example(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
protected Example(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public static RemoteCall<Example> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return deployRemoteCall(Example.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
|
||||
}
|
||||
|
||||
public static RemoteCall<Example> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return deployRemoteCall(Example.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
|
||||
}
|
||||
|
||||
public RemoteCall<TransactionReceipt> ExampleFunction() {
|
||||
final Function function = new Function(
|
||||
"ExampleFunction",
|
||||
Arrays.<Type>asList(),
|
||||
Collections.<TypeReference<?>>emptyList());
|
||||
return executeRemoteCallTransaction(function);
|
||||
}
|
||||
|
||||
public static Example load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return new Example(contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public static Example load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return new Example(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
protected String getStaticDeployedAddress(String networkId) {
|
||||
return _addresses.get(networkId);
|
||||
}
|
||||
|
||||
public static String getPreviouslyDeployedAddress(String networkId) {
|
||||
return _addresses.get(networkId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package com.baeldung.web3j.controllers;
|
||||
|
||||
import com.baeldung.web3j.constants.Constants;
|
||||
import com.baeldung.web3j.helpers.TimeHelper;
|
||||
import com.baeldung.web3j.services.Web3Service;
|
||||
import com.baeldung.web3j.transfers.ResponseTransfer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.web3j.protocol.core.methods.response.EthAccounts;
|
||||
import org.web3j.protocol.core.methods.response.EthBlockNumber;
|
||||
import org.web3j.protocol.core.methods.response.EthGetBalance;
|
||||
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION;
|
||||
|
||||
@RestController
|
||||
public class EthereumRestController {
|
||||
|
||||
@Autowired
|
||||
Web3Service web3Service;
|
||||
|
||||
@RequestMapping(value = Constants.API_BLOCK, method = RequestMethod.GET)
|
||||
public Future<ResponseTransfer> getBlock() {
|
||||
ResponseTransfer responseTransfer = new ResponseTransfer();
|
||||
Instant start = TimeHelper.start();
|
||||
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
CompletableFuture<EthBlockNumber> result = web3Service.getBlockNumber();
|
||||
responseTransfer.setMessage(result.get().toString());
|
||||
} catch (Exception e) {
|
||||
responseTransfer.setMessage(GENERIC_EXCEPTION);
|
||||
}
|
||||
return responseTransfer;
|
||||
}).thenApplyAsync(result -> {
|
||||
result.setPerformance(TimeHelper.stop(start));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@RequestMapping(value = Constants.API_ACCOUNTS, method = RequestMethod.GET)
|
||||
public Future<ResponseTransfer> getAccounts() {
|
||||
ResponseTransfer responseTransfer = new ResponseTransfer();
|
||||
Instant start = TimeHelper.start();
|
||||
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
CompletableFuture<EthAccounts> result = web3Service.getEthAccounts();
|
||||
responseTransfer.setMessage(result.get().toString());
|
||||
} catch (Exception e) {
|
||||
responseTransfer.setMessage(GENERIC_EXCEPTION);
|
||||
}
|
||||
return responseTransfer;
|
||||
|
||||
}).thenApplyAsync(result -> {
|
||||
result.setPerformance(TimeHelper.stop(start));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@RequestMapping(value = Constants.API_TRANSACTIONS, method = RequestMethod.GET)
|
||||
public Future<ResponseTransfer> getTransactions() {
|
||||
ResponseTransfer responseTransfer = new ResponseTransfer();
|
||||
Instant start = TimeHelper.start();
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
CompletableFuture<EthGetTransactionCount> result = web3Service.getTransactionCount();
|
||||
responseTransfer.setMessage(result.get().toString());
|
||||
} catch (Exception e) {
|
||||
responseTransfer.setMessage(GENERIC_EXCEPTION);
|
||||
}
|
||||
return responseTransfer;
|
||||
}).thenApplyAsync(result -> {
|
||||
result.setPerformance(TimeHelper.stop(start));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@RequestMapping(value = Constants.API_BALANCE, method = RequestMethod.GET)
|
||||
public Future<ResponseTransfer> getBalance() {
|
||||
ResponseTransfer responseTransfer = new ResponseTransfer();
|
||||
Instant start = TimeHelper.start();
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
CompletableFuture<EthGetBalance> result = web3Service.getEthBalance();
|
||||
responseTransfer.setMessage(result.get().toString());
|
||||
} catch (Exception e) {
|
||||
responseTransfer.setMessage(GENERIC_EXCEPTION);
|
||||
}
|
||||
return responseTransfer;
|
||||
}).thenApplyAsync(result -> {
|
||||
result.setPerformance(TimeHelper.stop(start));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.web3j.helpers;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
public class TimeHelper {
|
||||
|
||||
public static Instant start() {
|
||||
return Instant.now();
|
||||
}
|
||||
|
||||
public static Duration stop(Instant start) {
|
||||
Instant end = Instant.now();
|
||||
return Duration.between(start, end);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package com.baeldung.web3j.services;
|
||||
|
||||
import com.baeldung.web3j.contracts.Example;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.web3j.abi.FunctionEncoder;
|
||||
import org.web3j.abi.datatypes.Function;
|
||||
import org.web3j.crypto.Credentials;
|
||||
import org.web3j.crypto.WalletUtils;
|
||||
import org.web3j.protocol.Web3j;
|
||||
import org.web3j.protocol.core.DefaultBlockParameter;
|
||||
import org.web3j.protocol.core.methods.request.Transaction;
|
||||
import org.web3j.protocol.core.methods.response.EthAccounts;
|
||||
import org.web3j.protocol.core.methods.response.EthBlockNumber;
|
||||
import org.web3j.protocol.core.methods.response.EthGetBalance;
|
||||
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
|
||||
import org.web3j.protocol.http.HttpService;
|
||||
import org.web3j.tx.Contract;
|
||||
import org.web3j.tx.ManagedTransaction;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.baeldung.web3j.constants.Constants.DEFAULT_ADDRESS;
|
||||
import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION;
|
||||
import static com.baeldung.web3j.constants.Constants.PLEASE_SUPPLY_REAL_DATA;
|
||||
|
||||
@Service
|
||||
public class Web3Service {
|
||||
|
||||
private Web3j web3j = Web3j.build(new HttpService());
|
||||
|
||||
//Create and Init the default Web3J connection
|
||||
public void customInit(String provider) {
|
||||
this.web3j = Web3j.build(new HttpService(provider));
|
||||
}
|
||||
|
||||
//Convert to and from supplied contract ABI bytecode
|
||||
public static String toBinary(String bytecode) {
|
||||
return bytecode.replaceFirst("^0x", "");
|
||||
}
|
||||
|
||||
public static String toByteCode(String binary) {
|
||||
return "0x" + binary;
|
||||
}
|
||||
|
||||
public CompletableFuture<EthBlockNumber> getBlockNumber() {
|
||||
EthBlockNumber result = new EthBlockNumber();
|
||||
try {
|
||||
result = this.web3j.ethBlockNumber().sendAsync().get();
|
||||
} catch (Exception ex) {
|
||||
System.out.println(GENERIC_EXCEPTION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
|
||||
public CompletableFuture<EthAccounts> getEthAccounts() {
|
||||
EthAccounts result = new EthAccounts();
|
||||
try {
|
||||
result = this.web3j.ethAccounts().sendAsync().get();
|
||||
} catch (Exception ex) {
|
||||
System.out.println(GENERIC_EXCEPTION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
|
||||
public CompletableFuture<EthGetTransactionCount> getTransactionCount() {
|
||||
EthGetTransactionCount result = new EthGetTransactionCount();
|
||||
try {
|
||||
result = this.web3j.ethGetTransactionCount(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().get();
|
||||
} catch (Exception ex) {
|
||||
System.out.println(GENERIC_EXCEPTION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
|
||||
public CompletableFuture<EthGetBalance> getEthBalance() {
|
||||
EthGetBalance result = new EthGetBalance();
|
||||
try {
|
||||
result = this.web3j.ethGetBalance(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().get();
|
||||
} catch (Exception ex) {
|
||||
System.out.println(GENERIC_EXCEPTION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
|
||||
public CompletableFuture<String> fromScratchContractExample() {
|
||||
|
||||
String contractAddress = "";
|
||||
|
||||
try {
|
||||
//Create a wallet
|
||||
WalletUtils.generateNewWalletFile("PASSWORD", new File("/path/to/destination"), true);
|
||||
//Load the credentials from it
|
||||
Credentials credentials = WalletUtils.loadCredentials("PASSWORD", "/path/to/walletfile");
|
||||
|
||||
//Deploy contract to address specified by wallet
|
||||
Example contract = Example.deploy(this.web3j,
|
||||
credentials,
|
||||
ManagedTransaction.GAS_PRICE,
|
||||
Contract.GAS_LIMIT).send();
|
||||
|
||||
//Het the address
|
||||
contractAddress = contract.getContractAddress();
|
||||
|
||||
} catch (Exception ex) {
|
||||
System.out.println(PLEASE_SUPPLY_REAL_DATA);
|
||||
return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA);
|
||||
}
|
||||
return CompletableFuture.completedFuture(contractAddress);
|
||||
}
|
||||
|
||||
@Async
|
||||
public CompletableFuture<String> sendTx() {
|
||||
String transactionHash = "";
|
||||
|
||||
try {
|
||||
List inputParams = new ArrayList();
|
||||
List outputParams = new ArrayList();
|
||||
Function function = new Function("fuctionName", inputParams, outputParams);
|
||||
|
||||
String encodedFunction = FunctionEncoder.encode(function);
|
||||
|
||||
BigInteger nonce = BigInteger.valueOf(100);
|
||||
BigInteger gasprice = BigInteger.valueOf(100);
|
||||
BigInteger gaslimit = BigInteger.valueOf(100);
|
||||
|
||||
Transaction transaction = Transaction.createFunctionCallTransaction("FROM_ADDRESS", nonce, gasprice, gaslimit, "TO_ADDRESS", encodedFunction);
|
||||
|
||||
org.web3j.protocol.core.methods.response.EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction).sendAsync().get();
|
||||
transactionHash = transactionResponse.getTransactionHash();
|
||||
|
||||
} catch (Exception ex) {
|
||||
System.out.println(PLEASE_SUPPLY_REAL_DATA);
|
||||
return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA);
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(transactionHash);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.web3j.transfers;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class ResponseTransfer {
|
||||
|
||||
public ResponseTransfer() {}
|
||||
|
||||
private Duration performance;
|
||||
private String message;
|
||||
|
||||
public Duration getPerformance() {
|
||||
return performance;
|
||||
}
|
||||
|
||||
public void setPerformance(Duration performance) {
|
||||
this.performance = performance;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
# Ganache Readme
|
||||
|
||||
TL:DR - To set up Ganache visit: http://truffleframework.com/ganache/
|
||||
|
||||
# Three Ways to Install Ganache
|
||||
|
||||
Ganache is provided in three libraries or distributions:
|
||||
|
||||
(1) Ganache - https://github.com/trufflesuite/ganache
|
||||
|
||||
This is a pre-built and out-of-the-box solution. Easiest to set up. It provides an interface and server shell for Ganache CLI.
|
||||
|
||||
(2) Ganache CLI - https://www.npmjs.com/package/ganache-cli
|
||||
|
||||
Ganache CLI abstracts Ganache Core and supplies the default options and arguments used.
|
||||
|
||||
(3) Ganache Core - https://www.npmjs.com/package/ganache-core
|
||||
|
||||
Basically, only use Ganache Core if you need to build a totally customized option.
|
||||
|
||||
# Use
|
||||
|
||||
The default port is *8545* on *localhost*
|
|
@ -0,0 +1,43 @@
|
|||
# Using Truffle
|
||||
|
||||
Basic Truffle walkthrough readme.
|
||||
|
||||
See also: http://truffleframework.com/docs/
|
||||
|
||||
# Bash
|
||||
|
||||
Truffle install
|
||||
|
||||
```bash
|
||||
$ npm install truffle -g
|
||||
$ truffle version
|
||||
```
|
||||
|
||||
Truffle commands:
|
||||
|
||||
```bash
|
||||
$ truffle init
|
||||
$ truffle compile
|
||||
$ truffle migrate
|
||||
$ truffle test
|
||||
```
|
||||
|
||||
# Directory Structure
|
||||
|
||||
The command `$ truffle init` will create a directory structure in the specified root according to the following:
|
||||
|
||||
```
|
||||
root -|
|
||||
|-build (Compiled Solc JSON Output Dir)
|
||||
|-contracts (Solc Contracts to be Compiled and Migrated)
|
||||
|-migrations (Specify the Order and Dependencies of Contracts to Be Deployed)
|
||||
|-test (Truffle Tests)
|
||||
```
|
||||
|
||||
# Compile
|
||||
|
||||
Truffle will compile the smart contracts and expose their **JSON ABI's for use with Web3.js** or **Binary ABI's for use with Web3J**.
|
||||
|
||||
# Migration
|
||||
|
||||
Truffle will let you deploy your Solc contracts directly to a blockchin of your choice.
|
|
@ -0,0 +1,455 @@
|
|||
{
|
||||
"contractName": "ConvertLib",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "conversionRate",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "convert",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "convertedAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x60d161002f600b82828239805160001a6073146000811461001f57610021565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029",
|
||||
"deployedBytecode": "0x73000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029",
|
||||
"sourceMap": "28:148:0:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24",
|
||||
"deployedSourceMap": "28:148:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;50:123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109:20;154:14;145:6;:23;138:30;;50:123;;;;:::o",
|
||||
"source": "pragma solidity ^0.4.17;\r\n\r\nlibrary ConvertLib{\r\n\tfunction convert(uint amount,uint conversionRate) returns (uint convertedAmount)\r\n\t{\r\n\t\treturn amount * conversionRate;\r\n\t}\r\n}\r\n",
|
||||
"sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\ConvertLib.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol",
|
||||
"exportedSymbols": {
|
||||
"ConvertLib": [
|
||||
16
|
||||
]
|
||||
},
|
||||
"id": 17,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"^",
|
||||
"0.4",
|
||||
".17"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:24:0"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "library",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 16,
|
||||
"linearizedBaseContracts": [
|
||||
16
|
||||
],
|
||||
"name": "ConvertLib",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 14,
|
||||
"nodeType": "Block",
|
||||
"src": "133:40:0",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"commonType": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"id": 12,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 10,
|
||||
"name": "amount",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3,
|
||||
"src": "145:6:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"nodeType": "BinaryOperation",
|
||||
"operator": "*",
|
||||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 11,
|
||||
"name": "conversionRate",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 5,
|
||||
"src": "154:14:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"src": "145:23:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"functionReturnParameters": 9,
|
||||
"id": 13,
|
||||
"nodeType": "Return",
|
||||
"src": "138:30:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 15,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "convert",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 6,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3,
|
||||
"name": "amount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "67:11:0",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 2,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "67:4:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 5,
|
||||
"name": "conversionRate",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "79:19:0",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 4,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "79:4:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "66:33:0"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 9,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 8,
|
||||
"name": "convertedAmount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "109:20:0",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 7,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "109:4:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "108:22:0"
|
||||
},
|
||||
"scope": 16,
|
||||
"src": "50:123:0",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 17,
|
||||
"src": "28:148:0"
|
||||
}
|
||||
],
|
||||
"src": "0:178:0"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol",
|
||||
"exportedSymbols": {
|
||||
"ConvertLib": [
|
||||
16
|
||||
]
|
||||
},
|
||||
"id": 17,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"^",
|
||||
"0.4",
|
||||
".17"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:24:0"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "library",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 16,
|
||||
"linearizedBaseContracts": [
|
||||
16
|
||||
],
|
||||
"name": "ConvertLib",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 14,
|
||||
"nodeType": "Block",
|
||||
"src": "133:40:0",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"commonType": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"id": 12,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 10,
|
||||
"name": "amount",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3,
|
||||
"src": "145:6:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"nodeType": "BinaryOperation",
|
||||
"operator": "*",
|
||||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 11,
|
||||
"name": "conversionRate",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 5,
|
||||
"src": "154:14:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"src": "145:23:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"functionReturnParameters": 9,
|
||||
"id": 13,
|
||||
"nodeType": "Return",
|
||||
"src": "138:30:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 15,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "convert",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 6,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3,
|
||||
"name": "amount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "67:11:0",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 2,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "67:4:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 5,
|
||||
"name": "conversionRate",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "79:19:0",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 4,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "79:4:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "66:33:0"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 9,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 8,
|
||||
"name": "convertedAmount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "109:20:0",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 7,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "109:4:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "108:22:0"
|
||||
},
|
||||
"scope": 16,
|
||||
"src": "50:123:0",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 17,
|
||||
"src": "28:148:0"
|
||||
}
|
||||
],
|
||||
"src": "0:178:0"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "0.4.21+commit.dfe3193c.Emscripten.clang"
|
||||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-04-14T03:37:39.678Z"
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
{
|
||||
"contractName": "Example",
|
||||
"abi": [
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "ExampleFunction",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029",
|
||||
"deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029",
|
||||
"sourceMap": "28:134:1:-;;;50:45;;;;;;;;28:134;;;;;;",
|
||||
"deployedSourceMap": "28:134:1:-;;;;;;;;;;;;;;;;;;;;;;;;101:58;;;;;;;;;;;;;;;:::o",
|
||||
"source": "pragma solidity ^0.4.17;\r\n\r\ncontract Example {\r\n function Example() {\r\n // constructor\r\n }\r\n\r\n function ExampleFunction() {\r\n // example function\r\n }\r\n}",
|
||||
"sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\Example.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol",
|
||||
"exportedSymbols": {
|
||||
"Example": [
|
||||
27
|
||||
]
|
||||
},
|
||||
"id": 28,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 18,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"^",
|
||||
"0.4",
|
||||
".17"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:24:1"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 27,
|
||||
"linearizedBaseContracts": [
|
||||
27
|
||||
],
|
||||
"name": "Example",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 21,
|
||||
"nodeType": "Block",
|
||||
"src": "69:26:1",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 22,
|
||||
"implemented": true,
|
||||
"isConstructor": true,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "Example",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 19,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "66:2:1"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 20,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "69:0:1"
|
||||
},
|
||||
"scope": 27,
|
||||
"src": "50:45:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
},
|
||||
{
|
||||
"body": {
|
||||
"id": 25,
|
||||
"nodeType": "Block",
|
||||
"src": "128:31:1",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 26,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "ExampleFunction",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 23,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "125:2:1"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 24,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "128:0:1"
|
||||
},
|
||||
"scope": 27,
|
||||
"src": "101:58:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 28,
|
||||
"src": "28:134:1"
|
||||
}
|
||||
],
|
||||
"src": "0:162:1"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol",
|
||||
"exportedSymbols": {
|
||||
"Example": [
|
||||
27
|
||||
]
|
||||
},
|
||||
"id": 28,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 18,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"^",
|
||||
"0.4",
|
||||
".17"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:24:1"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 27,
|
||||
"linearizedBaseContracts": [
|
||||
27
|
||||
],
|
||||
"name": "Example",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 21,
|
||||
"nodeType": "Block",
|
||||
"src": "69:26:1",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 22,
|
||||
"implemented": true,
|
||||
"isConstructor": true,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "Example",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 19,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "66:2:1"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 20,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "69:0:1"
|
||||
},
|
||||
"scope": 27,
|
||||
"src": "50:45:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
},
|
||||
{
|
||||
"body": {
|
||||
"id": 25,
|
||||
"nodeType": "Block",
|
||||
"src": "128:31:1",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 26,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "ExampleFunction",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 23,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "125:2:1"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 24,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "128:0:1"
|
||||
},
|
||||
"scope": 27,
|
||||
"src": "101:58:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 28,
|
||||
"src": "28:134:1"
|
||||
}
|
||||
],
|
||||
"src": "0:162:1"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "0.4.21+commit.dfe3193c.Emscripten.clang"
|
||||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-04-14T03:37:39.710Z"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
pragma solidity ^0.4.17;
|
||||
|
||||
library ConvertLib{
|
||||
function convert(uint amount,uint conversionRate) returns (uint convertedAmount)
|
||||
{
|
||||
return amount * conversionRate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
pragma solidity ^0.4.17;
|
||||
|
||||
contract Example {
|
||||
function Example() {
|
||||
// constructor
|
||||
}
|
||||
|
||||
function ExampleFunction() {
|
||||
// example function
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
pragma solidity ^0.4.17;
|
||||
|
||||
contract Migrations {
|
||||
address public owner;
|
||||
uint public last_completed_migration;
|
||||
|
||||
modifier restricted() {
|
||||
if (msg.sender == owner) _;
|
||||
}
|
||||
|
||||
function Migrations() public {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
function setCompleted(uint completed) public restricted {
|
||||
last_completed_migration = completed;
|
||||
}
|
||||
|
||||
function upgrade(address new_address) public restricted {
|
||||
Migrations upgraded = Migrations(new_address);
|
||||
upgraded.setCompleted(last_completed_migration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = deployer => {
|
||||
deployer.deploy(artifacts.require("./Migrations.sol"));
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
const Example = artifacts.require("./Example.sol"),
|
||||
ConvertLib = artifacts.require("./ConvertLib.sol");
|
||||
|
||||
module.exports = deployer => {
|
||||
deployer.deploy(ConvertLib);
|
||||
deployer.link(ConvertLib, Example);
|
||||
deployer.deploy(Example);
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
module.exports = {
|
||||
contracts_build_directory: "./build/contracts",
|
||||
networks: {
|
||||
live: {
|
||||
network_id: 1, // Ethereum public network
|
||||
host: 'localhost',
|
||||
port: 8545
|
||||
},
|
||||
testnet: {
|
||||
network_id: 3, // Official Ethereum test network (Ropsten)
|
||||
host: 'localhost',
|
||||
port: 8545
|
||||
},
|
||||
development: {
|
||||
host: 'localhost',
|
||||
port: 8545,
|
||||
network_id: '*'
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.baeldung.web3j.controllers;
|
||||
|
||||
|
||||
import com.baeldung.web3j.config.AppConfig;
|
||||
import com.baeldung.web3j.constants.Constants;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {AppConfig.class})
|
||||
@WebAppConfiguration
|
||||
public class EthereumRestControllerIntegrationTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private void constructAsyncTest(String endpoint) {
|
||||
try {
|
||||
MvcResult asyncResult = mockMvc
|
||||
.perform(get(endpoint))
|
||||
.andReturn();
|
||||
|
||||
mockMvc.perform(asyncDispatch(asyncResult))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
@Before
|
||||
public void preTest() throws Exception {
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accounts() {
|
||||
constructAsyncTest(Constants.API_ACCOUNTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transactions() {
|
||||
constructAsyncTest(Constants.API_TRANSACTIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void block() {
|
||||
constructAsyncTest(Constants.API_BLOCK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void balance() {
|
||||
constructAsyncTest(Constants.API_BALANCE);
|
||||
}
|
||||
|
||||
@After
|
||||
public void postTest() {
|
||||
mockMvc = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.web3j.controllers;
|
||||
|
||||
import com.baeldung.web3j.constants.Constants;
|
||||
import com.baeldung.web3j.services.Web3Service;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class EthereumRestControllerUnitTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private void constructAsyncTest(String endpoint) {
|
||||
try {
|
||||
MvcResult asyncResult = mockMvc
|
||||
.perform(get(endpoint))
|
||||
.andReturn();
|
||||
|
||||
mockMvc.perform(asyncDispatch(asyncResult))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Mock
|
||||
private Web3Service web3Service;
|
||||
|
||||
@InjectMocks
|
||||
private EthereumRestController ethereumRestController;
|
||||
|
||||
@Before
|
||||
public void preTest() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(ethereumRestController).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accounts() {
|
||||
constructAsyncTest(Constants.API_ACCOUNTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transactions() {
|
||||
constructAsyncTest(Constants.API_TRANSACTIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void block() {
|
||||
constructAsyncTest(Constants.API_BLOCK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void balance() {
|
||||
constructAsyncTest(Constants.API_BALANCE);
|
||||
}
|
||||
|
||||
@After
|
||||
public void postTest() {
|
||||
mockMvc = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.web3j.services;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class EthereumContractUnitTest {
|
||||
|
||||
private Web3Service web3Service;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
web3Service = new Web3Service();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContract() {
|
||||
CompletableFuture<String> result = web3Service.fromScratchContractExample();
|
||||
assert (result instanceof CompletableFuture);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendTx() {
|
||||
CompletableFuture<String> result = web3Service.sendTx();
|
||||
assert (result instanceof CompletableFuture);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.ethereumj</groupId>
|
||||
<artifactId>ethereumj</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>1.0.0</version>
|
||||
<name>ethereumj</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-1</relativePath>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>Ethereum</id>
|
||||
<name>Ethereum</name>
|
||||
<url>https://dl.bintray.com/ethereum/maven/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
<!-- Unit Testing -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Ethereum -->
|
||||
<dependency>
|
||||
<groupId>org.ethereum</groupId>
|
||||
<artifactId>ethereumj-core</artifactId>
|
||||
<version>${ethereumj-core.version}</version>
|
||||
</dependency>
|
||||
<!-- Web3j -->
|
||||
<dependency>
|
||||
<groupId>org.web3j</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${web3j.core.version}</version>
|
||||
</dependency>
|
||||
<!-- JSTL/JSP -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-databind.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>ethereumj</finalName>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<tomcat.version>8.5.4</tomcat.version>
|
||||
<ethereumj-core.version>1.5.0-RELEASE</ethereumj-core.version>
|
||||
<web3j.core.version>3.3.1</web3j.core.version>
|
||||
<jackson-databind.version>2.5.0</jackson-databind.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<!-- POM file generated with GWT webAppCreator -->
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>google_web_toolkit</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>com.baeldung.Google_web_toolkit</name>
|
||||
|
||||
<properties>
|
||||
|
||||
<!-- Setting maven.compiler.source to something different to 1.8
|
||||
needs that you configure the sourceLevel in gwt-maven-plugin since
|
||||
GWT compiler 2.8 requires 1.8 (see gwt-maven-plugin block below) -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
|
||||
<!-- Don't let your Mac use a crazy non-standard encoding -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- ensure all GWT deps use the same version (unless overridden) -->
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-servlet</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-user</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-dev</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- Output classes directly into the webapp, so that IDEs and "mvn process-classes" update them in DevMode -->
|
||||
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
|
||||
|
||||
<plugins>
|
||||
|
||||
<!-- GWT Maven Plugin-->
|
||||
<plugin>
|
||||
<groupId>net.ltgt.gwt.maven</groupId>
|
||||
<artifactId>gwt-maven-plugin</artifactId>
|
||||
<version>1.0-rc-8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<moduleName>com.baeldung.Google_web_toolkit</moduleName>
|
||||
<moduleShortName>Google_web_toolkit</moduleShortName>
|
||||
<failOnError>true</failOnError>
|
||||
<!-- GWT compiler 2.8 requires 1.8, hence define sourceLevel here if you use
|
||||
a different source language for java compilation -->
|
||||
<sourceLevel>1.8</sourceLevel>
|
||||
<!-- Compiler configuration -->
|
||||
<compilerArgs>
|
||||
<!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
|
||||
<arg>-compileReport</arg>
|
||||
<arg>-XcompilerMetrics</arg>
|
||||
</compilerArgs>
|
||||
<!-- DevMode configuration -->
|
||||
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
|
||||
<classpathScope>compile+runtime</classpathScope>
|
||||
<!-- URL(s) that should be opened by DevMode (gwt:devmode). -->
|
||||
<startupUrls>
|
||||
<startupUrl>Google_web_toolkit.html</startupUrl>
|
||||
</startupUrls>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Skip normal test execution, we use gwt:test instead -->
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
When updating your version of GWT, you should also update this DTD reference,
|
||||
so that your app can take advantage of the latest GWT module capabilities.
|
||||
-->
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.8.2//EN"
|
||||
"http://gwtproject.org/doctype/2.8.2/gwt-module.dtd">
|
||||
<module rename-to='google_web_toolkit'>
|
||||
<!-- Inherit the core Web Toolkit stuff. -->
|
||||
<inherits name='com.google.gwt.user.User'/>
|
||||
|
||||
<!-- Inherit the default GWT style sheet. You can change -->
|
||||
<!-- the theme of your GWT application by uncommenting -->
|
||||
<!-- any one of the following lines. -->
|
||||
<inherits name='com.google.gwt.user.theme.clean.Clean'/>
|
||||
<!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/> -->
|
||||
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
|
||||
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
|
||||
|
||||
<!-- Other module inherits -->
|
||||
|
||||
<!-- Specify the app entry point class. -->
|
||||
<entry-point class='com.baeldung.client.Google_web_toolkit'/>
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<source path='client'/>
|
||||
<source path='shared'/>
|
||||
|
||||
<!-- allow Super Dev Mode -->
|
||||
<add-linker name="xsiframe"/>
|
||||
</module>
|
|
@ -0,0 +1,108 @@
|
|||
package com.baeldung.client;
|
||||
|
||||
import com.baeldung.shared.MessageService;
|
||||
import com.baeldung.shared.MessageServiceAsync;
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.dom.client.KeyCodes;
|
||||
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.DialogBox;
|
||||
import com.google.gwt.user.client.ui.HTML;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
|
||||
/**
|
||||
* Entry point classes define <code>onModuleLoad()</code>.
|
||||
*/
|
||||
public class Google_web_toolkit implements EntryPoint {
|
||||
private final MessageServiceAsync messageServiceAsync = GWT.create(MessageService.class);
|
||||
|
||||
public void onModuleLoad() {
|
||||
Button sendButton = new Button("Submit");
|
||||
TextBox nameField = new TextBox();
|
||||
nameField.setText("Hi there");
|
||||
|
||||
Label warningLabel = new Label();
|
||||
|
||||
sendButton.addStyleName("sendButton");
|
||||
|
||||
RootPanel.get("nameFieldContainer").add(nameField);
|
||||
RootPanel.get("sendButtonContainer").add(sendButton);
|
||||
RootPanel.get("errorLabelContainer").add(warningLabel);
|
||||
|
||||
Button closeButton = new Button("Thanks");
|
||||
closeButton.getElement().setId("closeButton");
|
||||
|
||||
Label textToServerLabel = new Label();
|
||||
HTML serverResponseLabel = new HTML();
|
||||
VerticalPanel vPanel = new VerticalPanel();
|
||||
vPanel.addStyleName("vPanel");
|
||||
vPanel.add(new HTML("Sending message to the server:"));
|
||||
vPanel.add(textToServerLabel);
|
||||
vPanel.add(new HTML("<br><b>Server replies:</b>"));
|
||||
vPanel.add(serverResponseLabel);
|
||||
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
|
||||
vPanel.add(closeButton);
|
||||
vPanel.setVisible(false);
|
||||
RootPanel.get("serverResponseContainer").add(vPanel);
|
||||
|
||||
closeButton.addClickHandler(event -> {
|
||||
sendButton.setEnabled(true);
|
||||
sendButton.setFocus(true);
|
||||
vPanel.setVisible(false);
|
||||
});
|
||||
|
||||
class MyHandler implements ClickHandler, KeyUpHandler {
|
||||
|
||||
public void onClick(ClickEvent event) {
|
||||
sendMessageToServer();
|
||||
}
|
||||
|
||||
public void onKeyUp(KeyUpEvent event) {
|
||||
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
|
||||
sendMessageToServer();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessageToServer() {
|
||||
|
||||
warningLabel.setText("");
|
||||
String textToServer = nameField.getText();
|
||||
if (textToServer == null || textToServer.isEmpty()) {
|
||||
warningLabel.setText("Please enter the message");
|
||||
return;
|
||||
}
|
||||
|
||||
sendButton.setEnabled(false);
|
||||
textToServerLabel.setText(textToServer);
|
||||
serverResponseLabel.setText("");
|
||||
messageServiceAsync.sendMessage(textToServer, new AsyncCallback<String>() {
|
||||
public void onFailure(Throwable caught) {
|
||||
serverResponseLabel.addStyleName("serverResponseLabelError");
|
||||
serverResponseLabel.setHTML("server error occurred");
|
||||
closeButton.setFocus(true);
|
||||
}
|
||||
|
||||
public void onSuccess(String result) {
|
||||
serverResponseLabel.removeStyleName("serverResponseLabelError");
|
||||
serverResponseLabel.setHTML(result);
|
||||
closeButton.setFocus(true);
|
||||
vPanel.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add a handler to send the name to the server
|
||||
MyHandler handler = new MyHandler();
|
||||
sendButton.addClickHandler(handler);
|
||||
nameField.addKeyUpHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.server;
|
||||
|
||||
import com.baeldung.shared.MessageService;
|
||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* The server-side implementation of the RPC service.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class MessageServiceImpl extends RemoteServiceServlet implements MessageService {
|
||||
|
||||
public String sendMessage(String message) throws IllegalArgumentException {
|
||||
if (message == null) {
|
||||
throw new IllegalArgumentException("message is null");
|
||||
}
|
||||
|
||||
return "Hello, " + message + "!<br><br> Time received: " + LocalDateTime.now();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.shared;
|
||||
|
||||
import com.google.gwt.user.client.rpc.RemoteService;
|
||||
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||
|
||||
/**
|
||||
* The client-side stub for the RPC service.
|
||||
*/
|
||||
@RemoteServiceRelativePath("greet")
|
||||
public interface MessageService extends RemoteService {
|
||||
String sendMessage(String message) throws IllegalArgumentException;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.baeldung.shared;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
|
||||
/**
|
||||
* The async counterpart of <code>MessageService</code>.
|
||||
*/
|
||||
public interface MessageServiceAsync {
|
||||
void sendMessage(String input, AsyncCallback<String> callback) throws IllegalArgumentException;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/** Add css rules here for your application. */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #777777;
|
||||
margin: 40px 0px 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sendButton {
|
||||
display: block;
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
/** Most GWT widgets already have a style name defined */
|
||||
.gwt-DialogBox {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.vPanel {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.serverResponseLabelError {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/** Set ids using widget.getElement().setId("idOfElement") */
|
||||
#closeButton {
|
||||
margin: 15px 6px 6px;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<!doctype html>
|
||||
<!-- The DOCTYPE declaration above will set the -->
|
||||
<!-- browser's rendering engine into -->
|
||||
<!-- "Standards Mode". Replacing this declaration -->
|
||||
<!-- with a "Quirks Mode" doctype is not supported. -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="Google_web_toolkit.css">
|
||||
|
||||
<title>Sample GWT Application</title>
|
||||
|
||||
<script type="text/javascript" language="javascript" src="google_web_toolkit/google_web_toolkit.nocache.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Sample GWT Application</h1>
|
||||
<table align="center">
|
||||
<tr>
|
||||
<td colspan="2" style="font-weight:bold;">Please enter your message:</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nameFieldContainer"></td>
|
||||
<td id="sendButtonContainer"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="color:red;" id="errorLabelContainer"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="color:red;" id="serverResponseContainer"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue