Skip to content

Commit

Permalink
Merge branch 'devs' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
chenchen42 committed Feb 7, 2018
2 parents b30ef99 + c9ea54c commit 346a329
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 68 deletions.
43 changes: 22 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
<p align="center">Based on <code>Java8</code> + <code>Netty4</code> to create lightweight, high-performance, simple and elegant Web framework 😋</p>
<p align="center">Spend <b>1 hour</b> to learn it to do something interesting, a Spring in addition to the framework of the best choice.</p>
<p align="center">
🐾 <a href="#quick-start" target="_blank">Quick Start</a> |
📘 <a href="https://dev-cheats.com/topics/blade-in-action.html" target="_blank">Blade In Action</a> |
🎬 <a href="https://www.youtube.com/playlist?list=PLK2w-tGRdrj5TV2lxHFj8hcg4mbmRmnWX" target="_blank">Video Tutorial</a> |
🌚 <a href="" target="_blank">Contribution</a> |
🐾 <a href="#quick-start" target="_blank">Quick Start</a> |
📘 <a href="https://dev-cheats.com/topics/blade-in-action.html" target="_blank">Blade In Action</a> |
🎬 <a href="https://www.youtube.com/playlist?list=PLK2w-tGRdrj5TV2lxHFj8hcg4mbmRmnWX" target="_blank">Video Tutorial</a> |
🌚 <a href="" target="_blank">Contribution</a> |
💰 <a href="https://lets-blade.com/donate" target="_blank">Donate</a> |
🇨🇳 <a href="README_CN.md">简体中文</a>
</p>
Expand All @@ -18,6 +18,7 @@
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square"></a>
<a class="badge-align" href="https://www.codacy.com/app/lets-blade/blade"><img src="https://api.codacy.com/project/badge/Grade/5f5fb55f38614f04823372db3a3c1d1b"/></a>
<a href="https://gitter.im/biezhi/blade"><img src="https://badges.gitter.im/biezhi/blade.svg?style=flat-square"></a>
<a href="https://www.codetriage.com/biezhi/blade"><img src="https://www.codetriage.com/biezhi/blade/badges/users.svg"></a>
</p>

***
Expand Down Expand Up @@ -137,19 +138,19 @@ public static void main(String[] args) {
```java
@Path
public class IndexController {

@GetRoute("signin")
public String signin(){
return "signin.html";
}

@PostRoute("signin")
@JSON
public RestResponse doSignin(Request request){
// do something
return RestResponse.ok();
}

}
```

Expand All @@ -175,7 +176,7 @@ public static void main(String[] args) {
```java
@PostRoute("/save")
public void savePerson(@Param String username, @Param Integer age){
System.out.println("username is:" + usernam + ", age is:" + age)
 System.out.println("username is:" + username + ", age is:" + age)
}
```

Expand All @@ -201,15 +202,15 @@ public static void main(String[] args) {
Integer uid = request.pathInt("uid");
response.text("uid : " + uid);
});

// Create two parameters route
blade.get("/users/:uid/post/:pid", (request, response) -> {
Integer uid = request.pathInt("uid");
Integer pid = request.pathInt("pid");
String msg = "uid = " + uid + ", pid = " + pid;
response.text(msg);
});

// Start blade
blade.start();
}
Expand Down Expand Up @@ -380,7 +381,7 @@ public void upload(Request request){
request.fileItem("img").ifPresent(fileItem -> {
byte[] data = fileItem.getData();
// Save the temporary file to the specified path
Files.write(Paths.get(filePath), data);
Files.write(Paths.get(filePath), data);
});
}
```
Expand Down Expand Up @@ -493,12 +494,12 @@ Create a `BeanProcessor` class
```java
@Bean
public class TemplateConfig implements BeanProcessor {

@Override
public void processor(Blade blade) {
blade.templateEngine(new JetbrickTemplateEngine());
}

}
```

Expand Down Expand Up @@ -527,13 +528,13 @@ The `hello.html` template
<body>

<h1>Hello, ${user.username}</h1>

#if(user.age > 18)
<p>Good Boy!</p>
#else
<p>Gooood Baby!</p>
#end

</body>
</html>
```
Expand All @@ -545,9 +546,9 @@ The `hello.html` template
```java
@GetRoute("redirect")
public void redirectToGithub(Response response){

response.redirect("https://github.com/biezhi");

}
```

Expand All @@ -558,10 +559,10 @@ public void redirectToGithub(Response response){
```java
@GetRoute("write-cookie")
public void writeCookie(Response response){

response.cookie("hello", "world");
response.cookie("UID", "22", 3600);

}
```

Expand Down Expand Up @@ -652,7 +653,7 @@ Blade has already implemented an exception handler by default, and sometimes you
```java
@Bean
public class GolbalExceptionHandler extends DefaultExceptionHandler {
@Override
public void handle(Exception e) {
if (e instanceof ValidateException) {
Expand All @@ -663,7 +664,7 @@ public class GolbalExceptionHandler extends DefaultExceptionHandler {
super.handle(e);
}
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public static void main(String[] args) {
```java
@PostRoute("/save")
public void savePerson(@Param String username, @Param Integer age){
System.out.println("username is:" + usernam + ", age is:" + age)
System.out.println("username is:" + username + ", age is:" + age)
}
```

Expand Down
85 changes: 82 additions & 3 deletions src/main/java/com/blade/Blade.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.blade.kit.Assert;
import com.blade.kit.BladeKit;
import com.blade.kit.StringKit;
import com.blade.kit.reload.FileChangeDetector;
import com.blade.mvc.Const;
import com.blade.mvc.SessionManager;
import com.blade.mvc.handler.DefaultExceptionHandler;
import com.blade.mvc.handler.ExceptionHandler;
Expand All @@ -45,12 +47,13 @@
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.blade.mvc.Const.*;

Expand Down Expand Up @@ -414,6 +417,14 @@ public Blade devMode(boolean devMode) {
return this;
}

public boolean isAutoRefreshDir(){
return environment.get(ENV_KEY_AUTO_REFRESH_DIR).isPresent();
}

public void setAutoRefreshDir(String dir){
environment.set(ENV_KEY_AUTO_REFRESH_DIR, dir);
}

public Class<?> bootClass() {
return this.bootClass;
}
Expand Down Expand Up @@ -674,6 +685,7 @@ public Blade start(Class<?> mainCls, String... args) {
*/
public Blade start(Class<?> bootClass, @NonNull String address, int port, String... args) {
try {
loadConfig(args);
environment.set(ENV_KEY_SERVER_ADDRESS, address);
Assert.greaterThan(port, 0, "server port not is negative number.");
this.bootClass = bootClass;
Expand All @@ -683,6 +695,7 @@ public Blade start(Class<?> bootClass, @NonNull String address, int port, String
server.start(Blade.this, args);
latch.countDown();
server.join();

} catch (Exception e) {
startupExceptionHandler.accept(e);
}
Expand All @@ -694,6 +707,33 @@ public Blade start(Class<?> bootClass, @NonNull String address, int port, String
thread.setName(threadName);
thread.start();
started = true;

Thread resourceFilesRefreshThread = new Thread(()-> {

try {
FileChangeDetector fileChangeDetector = new FileChangeDetector(environment.get(ENV_KEY_AUTO_REFRESH_DIR).get());
fileChangeDetector.processEvent( (event , filePath) ->{
try {
//TODO: add support for Create and Delete
if(event.equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
Path destPath = FileChangeDetector.getDestPath(filePath, environment);
Files.copy(filePath, destPath, StandardCopyOption.REPLACE_EXISTING);
}
}catch (IOException e){
log.error("Exception when trying to copy updated file");
startupExceptionHandler.accept(e);
}
});
}catch (IOException e){
startupExceptionHandler.accept(e);
}

});

if (devMode() && isAutoRefreshDir()){
log.info("auto refresh is enabled");
resourceFilesRefreshThread.start();
}
} catch (Exception e) {
startupExceptionHandler.accept(e);
}
Expand Down Expand Up @@ -807,4 +847,43 @@ public WebSocketHandler webSocketHandler() {
return webSocketHandler;
}

}
private void loadConfig(String[] args) {

String bootConf = environment().get(ENV_KEY_BOOT_CONF, "classpath:app.properties");

Environment bootEnv = Environment.of(bootConf);

if (bootEnv != null) {
bootEnv.props().forEach((key, value) -> environment.set(key.toString(), value));
}

if (null != args) {
Optional<String> envArg = Stream.of(args).filter(s -> s.startsWith(Const.TERMINAL_BLADE_ENV)).findFirst();
envArg.ifPresent(arg -> {
String envName = "app-" + arg.split("=")[1] + ".properties";
log.info("current environment file is: {}", envName);
Environment customEnv = Environment.of(envName);
if (customEnv != null) {
customEnv.props().forEach((key, value) -> environment.set(key.toString(), value));
}
});
}

register(environment);

// load terminal param
if (!BladeKit.isEmpty(args)) {
for (String arg : args) {
if (arg.startsWith(TERMINAL_SERVER_ADDRESS)) {
int pos = arg.indexOf(TERMINAL_SERVER_ADDRESS) + TERMINAL_SERVER_ADDRESS.length();
String address = arg.substring(pos);
environment.set(ENV_KEY_SERVER_ADDRESS, address);
} else if (arg.startsWith(TERMINAL_SERVER_PORT)) {
int pos = arg.indexOf(TERMINAL_SERVER_PORT) + TERMINAL_SERVER_PORT.length();
String port = arg.substring(pos);
environment.set(ENV_KEY_SERVER_PORT, port);
}
}
}
}
}
85 changes: 85 additions & 0 deletions src/main/java/com/blade/kit/reload/FileChangeDetector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.blade.kit.reload;

import com.blade.Environment;
import com.blade.mvc.Const;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

/**
* Created by Eddie Wang on 12/25/17.
*/
@Slf4j
public class FileChangeDetector {
private WatchService watcher;
private Map<WatchKey, Path> pathMap = new HashMap<>();

public FileChangeDetector(String dirPath) throws IOException{
watcher = FileSystems.getDefault().newWatchService();
registerAll(Paths.get(dirPath));
}

private void register(Path dir) throws IOException{
WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
pathMap.put(key,dir);
}

private void registerAll(Path dir) throws IOException{
Files.walkFileTree(dir, new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
register(dir);
return FileVisitResult.CONTINUE;
}
});
}

public void processEvent(BiConsumer<WatchEvent.Kind<Path>, Path> processor){
for(;;){
WatchKey key;
try{
key = watcher.take();
}catch (InterruptedException e) {
return;
}

Path dir = pathMap.get(key);
for (WatchEvent<?> event: key.pollEvents()){
WatchEvent.Kind kind = event.kind();
Path filePath = dir.resolve(((WatchEvent<Path>)event).context());

if(Files.isDirectory(filePath)) continue;
log.info("File {} changes detected!",filePath.toString());
//copy updated files to target
processor.accept(kind, filePath);
}
key.reset();
}
}

public static Path getDestPath(Path src, Environment env){
String templateDir = env.get(Const.ENV_KEY_TEMPLATE_PATH,"/templates");
Optional<String> staticDir = env.get(Const.ENV_KEY_STATIC_DIRS);
List<String> templateOrStaticDirKeyword = new ArrayList<>();
templateOrStaticDirKeyword.add(templateDir);
if(staticDir.isPresent()){
templateOrStaticDirKeyword.addAll(Arrays.asList(staticDir.get().split(",")));
}else{
templateOrStaticDirKeyword.addAll(Const.DEFAULT_STATICS);
}

List result = templateOrStaticDirKeyword.stream().filter(dir -> src.toString().indexOf(dir)!=-1).collect(Collectors.toList());
if(result.size()!=1){
log.info("Cannot get dest dir");
return null;
}
String key = (String)result.get(0);
log.info(Const.CLASSPATH + src.toString().substring(src.toString().indexOf(key)));
return Paths.get(Const.CLASSPATH + src.toString().substring(src.toString().indexOf(key)));
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/blade/mvc/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public interface Const {
String ENV_KEY_NETTY_SO_BACKLOG = "server.netty.so-backlog";

String ENV_KEY_BOOT_CONF = "boot_conf";

String ENV_KEY_AUTO_REFRESH_DIR = "app.auto.refresh.dir";
// terminal
String TERMINAL_SERVER_ADDRESS = "--server.address=";
String TERMINAL_SERVER_PORT = "--server.port=";
Expand Down
Loading

0 comments on commit 346a329

Please sign in to comment.