diff --git a/.gitignore b/.gitignore index 3fb6945..a17e3c6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ /local.properties .DS_Store /captures -.externalNativeBuild \ No newline at end of file +.externalNativeBuild +/maven-repo \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/Core.java b/andserver/src/main/java/com/yanzhenjie/andserver/Core.java deleted file mode 100644 index 9107c3d..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/Core.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver; - -import com.yanzhenjie.andserver.exception.resolver.ExceptionResolver; -import com.yanzhenjie.andserver.filter.Filter; -import com.yanzhenjie.andserver.interceptor.Interceptor; -import com.yanzhenjie.andserver.ssl.SSLSocketInitializer; -import com.yanzhenjie.andserver.util.Executors; -import com.yanzhenjie.andserver.website.WebSite; - -import org.apache.httpcore.ExceptionLogger; -import org.apache.httpcore.config.ConnectionConfig; -import org.apache.httpcore.config.SocketConfig; -import org.apache.httpcore.impl.bootstrap.HttpServer; -import org.apache.httpcore.impl.bootstrap.ServerBootstrap; - -import java.net.InetAddress; -import java.nio.charset.Charset; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.SSLContext; - -/** - * Created by Yan Zhenjie on 2017/3/13. - */ -final class Core implements Server { - - static Builder newBuilder() { - return new Builder(); - } - - private final InetAddress mInetAddress; - private final int mPort; - private final int mTimeout; - private final SSLContext mSSLContext; - private final SSLSocketInitializer mSSLSocketInitializer; - private final Interceptor mInterceptor; - private final WebSite mWebSite; - private final Map mRequestHandlerMap; - private final Filter mFilter; - private final ExceptionResolver mExceptionResolver; - private final ServerListener mListener; - - private HttpServer mHttpServer; - private boolean isRunning; - - private Core(Builder builder) { - this.mInetAddress = builder.mInetAddress; - this.mPort = builder.mPort; - this.mTimeout = builder.mTimeout; - this.mSSLContext = builder.mSSLContext; - this.mSSLSocketInitializer = builder.mSSLSocketInitializer; - this.mInterceptor = builder.mInterceptor; - this.mWebSite = builder.mWebSite; - this.mRequestHandlerMap = builder.mRequestHandlerMap; - this.mFilter = builder.mFilter; - this.mExceptionResolver = builder.mExceptionResolver; - this.mListener = builder.mListener; - } - - @Override - public boolean isRunning() { - return isRunning; - } - - @Override - public void startup() { - if (isRunning) return; - - Executors.getInstance().submit(new Runnable() { - @Override - public void run() { - DispatchRequestHandler handler = new DispatchRequestHandler(); - handler.setInterceptor(mInterceptor); - handler.setWebSite(mWebSite); - if (mRequestHandlerMap != null && mRequestHandlerMap.size() > 0) { - for (Map.Entry handlerEntry : mRequestHandlerMap.entrySet()) { - String path = handlerEntry.getKey(); - RequestHandler requestHandler = handlerEntry.getValue(); - handler.registerRequestHandler(path, requestHandler); - } - } - handler.setFilter(mFilter); - handler.setExceptionResolver(mExceptionResolver); - - mHttpServer = ServerBootstrap.bootstrap() - .setSocketConfig( - SocketConfig.custom() - .setSoKeepAlive(true) - .setSoReuseAddress(true) - .setSoTimeout(mTimeout) - .setTcpNoDelay(false) - .build() - ) - .setConnectionConfig( - ConnectionConfig.custom() - .setBufferSize(4 * 1024) - .setCharset(Charset.defaultCharset()) - .build() - ) - .setLocalAddress(mInetAddress) - .setListenerPort(mPort) - .setSslContext(mSSLContext) - .setSslSetupHandler(new SSLSocketInitializer.SSLSocketInitializerWrapper(mSSLSocketInitializer)) - .setServerInfo("AndServer") - .registerHandler("*", handler) - .setExceptionLogger(ExceptionLogger.STD_ERR) - .create(); - try { - isRunning = true; - mHttpServer.start(); - - Executors.getInstance().post(new Runnable() { - @Override - public void run() { - if (mListener != null) - mListener.onStarted(); - } - }); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - mHttpServer.shutdown(3, TimeUnit.SECONDS); - } - }); - } catch (final Exception e) { - Executors.getInstance().post(new Runnable() { - @Override - public void run() { - if (mListener != null) - mListener.onError(e); - } - }); - } - } - }); - } - - /** - * The current server InetAddress. - */ - @Override - public InetAddress getInetAddress() { - if (isRunning) - return mHttpServer.getInetAddress(); - return null; - } - - /** - * Stop core server. - */ - @Override - public void shutdown() { - if (!isRunning) return; - - Executors.getInstance().execute(new Runnable() { - @Override - public void run() { - if (mHttpServer != null) - mHttpServer.shutdown(3, TimeUnit.MINUTES); - - Executors.getInstance().post(new Runnable() { - @Override - public void run() { - if (mListener != null) - mListener.onStopped(); - } - }); - } - }); - } - - private static final class Builder implements Server.Builder { - - private InetAddress mInetAddress; - private int mPort; - private int mTimeout; - private SSLContext mSSLContext; - private SSLSocketInitializer mSSLSocketInitializer; - private Interceptor mInterceptor; - private WebSite mWebSite; - private Map mRequestHandlerMap; - private Filter mFilter; - private ExceptionResolver mExceptionResolver; - private ServerListener mListener; - - private Builder() { - this.mRequestHandlerMap = new LinkedHashMap<>(); - } - - @Override - public Server.Builder inetAddress(InetAddress inetAddress) { - this.mInetAddress = inetAddress; - return this; - } - - @Override - public Server.Builder port(int port) { - this.mPort = port; - return this; - } - - @Override - public Server.Builder timeout(int timeout, TimeUnit timeUnit) { - long timeoutMs = timeUnit.toMillis(timeout); - this.mTimeout = (int) Math.min(timeoutMs, Integer.MAX_VALUE); - return this; - } - - @Override - public Server.Builder sslContext(SSLContext sslContext) { - this.mSSLContext = sslContext; - return this; - } - - @Override - public Server.Builder sslSocketInitializer(SSLSocketInitializer initializer) { - this.mSSLSocketInitializer = initializer; - return this; - } - - @Override - public Server.Builder interceptor(Interceptor interceptor) { - this.mInterceptor = interceptor; - return this; - } - - @Override - public Server.Builder exceptionResolver(ExceptionResolver resolver) { - this.mExceptionResolver = resolver; - return this; - } - - @Override - public Server.Builder registerHandler(String path, RequestHandler handler) { - this.mRequestHandlerMap.put(path, handler); - return this; - } - - @Override - public Server.Builder filter(Filter filter) { - this.mFilter = filter; - return this; - } - - @Override - public Server.Builder website(WebSite webSite) { - this.mWebSite = webSite; - return this; - } - - @Override - public Server.Builder listener(ServerListener listener) { - this.mListener = listener; - return this; - } - - @Override - public Server build() { - return new Core(this); - } - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/DispatchRequestHandler.java b/andserver/src/main/java/com/yanzhenjie/andserver/DispatchRequestHandler.java deleted file mode 100644 index b442e8d..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/DispatchRequestHandler.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver; - -import com.yanzhenjie.andserver.annotation.RequestMapping; -import com.yanzhenjie.andserver.exception.BaseException; -import com.yanzhenjie.andserver.exception.MethodNotSupported; -import com.yanzhenjie.andserver.exception.NotFoundException; -import com.yanzhenjie.andserver.exception.resolver.ExceptionResolver; -import com.yanzhenjie.andserver.exception.resolver.SimpleExceptionResolver; -import com.yanzhenjie.andserver.filter.Filter; -import com.yanzhenjie.andserver.interceptor.Interceptor; -import com.yanzhenjie.andserver.website.WebSite; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; -import org.apache.httpcore.protocol.HttpRequestHandler; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static com.yanzhenjie.andserver.util.HttpRequestParser.getRequestPath; - -/** - * Created by Yan Zhenjie on 2017/3/15. - */ -class DispatchRequestHandler implements HttpRequestHandler { - - private static ExceptionResolver sDefaultExceptionResolver = new SimpleExceptionResolver(); - - private Interceptor mInterceptor; - private WebSite mWebSite; - private Map mRequestHandlerMapper = new LinkedHashMap<>(); - private Filter mFilter; - private ExceptionResolver mExceptionResolver = sDefaultExceptionResolver; - - DispatchRequestHandler() { - } - - void setInterceptor(Interceptor interceptor) { - mInterceptor = interceptor; - } - - void setWebSite(WebSite webSite) { - this.mWebSite = webSite; - } - - void registerRequestHandler(String path, RequestHandler handler) { - mRequestHandlerMapper.put(path, handler); - } - - void setFilter(Filter filter) { - this.mFilter = filter; - } - - void setExceptionResolver(ExceptionResolver exceptionResolver) { - mExceptionResolver = exceptionResolver; - } - - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - try { - if (mInterceptor != null && mInterceptor.onBeforeExecute(request, response, context)) - return; - - RequestHandler handler = getRequestHandler(request, context); - if (handler == null) { - String path = getRequestPath(request); - throw new NotFoundException(path); - } else { - handleRequest(handler, request, response, context); - } - - if (mInterceptor != null) - mInterceptor.onAfterExecute(request, response, context); - } catch (Exception e) { - try { - mExceptionResolver.resolveException(e, request, response, context); - } catch (Exception ee) { - sDefaultExceptionResolver.resolveException(e, request, response, context); - } - } - } - - /** - * Handle Request with handler. - */ - private void handleRequest(RequestHandler handler, HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - verifyHandler(request, handler); - if (mFilter != null) { - mFilter.doFilter(handler, request, response, context); - } else { - handler.handle(request, response, context); - } - } - - /** - * The processor that gets the current request. - */ - private RequestHandler getRequestHandler(HttpRequest request, HttpContext context) throws HttpException, IOException { - String path = getRequestPath(request); - if (mWebSite != null && mWebSite.intercept(request, context)) { - return mWebSite; - } - return mRequestHandlerMapper.get(path); - } - - private void verifyHandler(HttpRequest request, RequestHandler handler) throws BaseException { - RequestMethod requestMethod = RequestMethod.reverse(request.getRequestLine().getMethod()); - Class clazz = handler.getClass(); - try { - Method handlerMethod = clazz.getMethod("handle", HttpRequest.class, HttpResponse.class, HttpContext.class); - RequestMapping requestMapping = handlerMethod.getAnnotation(RequestMapping.class); - if (requestMapping != null) { - RequestMethod[] requestMethods = requestMapping.method(); - List requestMethodList = Arrays.asList(requestMethods); - if (!requestMethodList.contains(requestMethod)) { - throw new MethodNotSupported(requestMethod); - } - } - } catch (NoSuchMethodException ignored) { - } - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/RequestHandler.java b/andserver/src/main/java/com/yanzhenjie/andserver/RequestHandler.java deleted file mode 100644 index 8dd4ea5..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/RequestHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; - -/** - *

Dealing with the client's request.

- * Created by Yan Zhenjie on 2016/6/13. - */ -public interface RequestHandler { - - /** - * When is the client request is triggered. - * - * @param request {@link HttpRequest}. - * @param response {@link HttpResponse}. - * @param context {@link HttpContext}. - * @throws HttpException may be. - * @throws IOException read data. - */ - void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException; -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/Server.java b/andserver/src/main/java/com/yanzhenjie/andserver/Server.java deleted file mode 100644 index ede23bc..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/Server.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver; - -import com.yanzhenjie.andserver.exception.resolver.ExceptionResolver; -import com.yanzhenjie.andserver.filter.Filter; -import com.yanzhenjie.andserver.interceptor.Interceptor; -import com.yanzhenjie.andserver.ssl.SSLSocketInitializer; -import com.yanzhenjie.andserver.website.WebSite; - -import java.net.InetAddress; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.SSLContext; - -/** - *

The control of the server.

- * Created by Yan Zhenjie on 2016/6/13. - */ -public interface Server { - - /** - * Server running status. - * - * @return return true, not return false. - */ - boolean isRunning(); - - /** - * Start the server. - */ - void startup(); - - /** - * Get the network address. - */ - InetAddress getInetAddress(); - - /** - * Quit the server. - */ - void shutdown(); - - interface Builder { - - /** - * Specified server need to monitor the ip address. - */ - Builder inetAddress(InetAddress inetAddress); - - /** - * Specify the port on which the server listens. - */ - Builder port(int port); - - /** - * Connection and response timeout. - */ - Builder timeout(int timeout, TimeUnit timeUnit); - - /** - * Setting up the server is based on the SSL protocol. - */ - Builder sslContext(SSLContext sslContext); - - /** - * Set SSLServerSocket's initializer. - */ - Builder sslSocketInitializer(SSLSocketInitializer initializer); - - /** - * Set request/response pair interceptor. - */ - Builder interceptor(Interceptor interceptor); - - /** - * Set up a website. - */ - Builder website(WebSite webSite); - - /** - * Register a {@link RequestHandler} for a path. - */ - Builder registerHandler(String path, RequestHandler handler); - - /** - * Set Handler's filter. - */ - Builder filter(Filter filter); - - /** - * Set the exception resolver in the request/response process. - */ - Builder exceptionResolver(ExceptionResolver resolver); - - /** - * Set the server listener. - */ - Builder listener(ServerListener listener); - - /** - * Create a server. - */ - Server build(); - } - - interface ServerListener { - /** - * When the server is started. - */ - void onStarted(); - - /** - * When the server stops running. - */ - void onStopped(); - - /** - * An error occurred while starting the server. - */ - void onError(Exception e); - } -} diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/SimpleRequestHandler.java b/andserver/src/main/java/com/yanzhenjie/andserver/SimpleRequestHandler.java deleted file mode 100644 index f1cc914..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/SimpleRequestHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver; - -import com.yanzhenjie.andserver.view.View; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; - -/** - * Created by YanZhenjie on 2017/12/20. - */ -public class SimpleRequestHandler implements RequestHandler { - - @Override - public final void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - View view = handle(request, response); - response.setStatusCode(view.getHttpCode()); - response.setEntity(view.getHttpEntity()); - response.setHeaders(view.getHeaders()); - } - - protected View handle(HttpRequest request, HttpResponse response) throws HttpException, IOException { - return handle(request); - } - - protected View handle(HttpRequest request) throws HttpException, IOException { - return new View(200); - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/exception/BaseException.java b/andserver/src/main/java/com/yanzhenjie/andserver/exception/BaseException.java deleted file mode 100644 index b71b6e3..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/exception/BaseException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.exception; - -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.StringEntity; - -/** - * Created by YanZhenjie on 2017/12/19. - */ -public class BaseException extends HttpException { - - private int mHttpCode; - private HttpEntity mHttpBody; - - public BaseException() { - this(500, "Unknown exception occurred on server."); - } - - public BaseException(int httpCode, String httpBody) { - super(httpBody); - this.mHttpCode = httpCode; - this.mHttpBody = new StringEntity(httpBody, ContentType.TEXT_PLAIN); - } - - public int getHttpCode() { - return mHttpCode; - } - - public HttpEntity getHttpBody() { - return mHttpBody; - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/exception/resolver/ExceptionResolver.java b/andserver/src/main/java/com/yanzhenjie/andserver/exception/resolver/ExceptionResolver.java deleted file mode 100644 index 93824b3..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/exception/resolver/ExceptionResolver.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.exception.resolver; - -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -/** - * Created by YanZhenjie on 2017/12/18. - */ -public interface ExceptionResolver { - - /** - * The exception here is thrown by {@code AndServer} or {@code RequestHandler}. - * Equivalent to the interception of anomalies, unified treatment of anomalies here. - */ - void resolveException(Exception e, HttpRequest request, HttpResponse response, HttpContext context); -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/exception/resolver/SimpleExceptionResolver.java b/andserver/src/main/java/com/yanzhenjie/andserver/exception/resolver/SimpleExceptionResolver.java deleted file mode 100644 index 1025027..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/exception/resolver/SimpleExceptionResolver.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.exception.resolver; - -import com.yanzhenjie.andserver.view.View; -import com.yanzhenjie.andserver.exception.BaseException; - -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.StringEntity; -import org.apache.httpcore.protocol.HttpContext; - -/** - * Created by YanZhenjie on 2017/12/20. - */ -public class SimpleExceptionResolver implements ExceptionResolver { - - @Override - public final void resolveException(Exception e, HttpRequest request, HttpResponse response, HttpContext context) { - View view = resolveException(e, request, response); - response.setStatusCode(view.getHttpCode()); - response.setEntity(view.getHttpEntity()); - response.setHeaders(view.getHeaders()); - } - - public View resolveException(Exception e, HttpRequest request, HttpResponse response) { - return resolveException(e); - } - - protected View resolveException(Exception e) { - if (e instanceof BaseException) { - BaseException exception = (BaseException) e; - return new View(exception.getHttpCode(), exception.getHttpBody()); - } - String message = String.format("Server error occurred:\n%1$s", e.getMessage()); - HttpEntity httpEntity = new StringEntity(message, ContentType.TEXT_PLAIN); - return new View(500, httpEntity); - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/filter/Filter.java b/andserver/src/main/java/com/yanzhenjie/andserver/filter/Filter.java deleted file mode 100644 index c899ba8..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/filter/Filter.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.filter; - -import com.yanzhenjie.andserver.RequestHandler; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; - -/** - * Created by YanZhenjie on 2017/12/22. - */ -public interface Filter { - - /** - * Each request/response pair will be called. - */ - void doFilter(RequestHandler handler, HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException; - -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/filter/HttpCacheFilter.java b/andserver/src/main/java/com/yanzhenjie/andserver/filter/HttpCacheFilter.java deleted file mode 100644 index 8ab135a..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/filter/HttpCacheFilter.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.filter; - -import com.yanzhenjie.andserver.RequestHandler; -import com.yanzhenjie.andserver.protocol.ETag; -import com.yanzhenjie.andserver.protocol.LastModified; -import com.yanzhenjie.andserver.util.DateUtils; -import com.yanzhenjie.andserver.util.DigestUtils; - -import org.apache.httpcore.Header; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; - -import static com.yanzhenjie.andserver.util.HttpRequestParser.parseDateHeader; - -/** - * Created by YanZhenjie on 2017/12/22. - */ -public class HttpCacheFilter implements Filter { - - private static final String CACHE_CONTROL = "Cache-Control"; - private static final String LAST_MODIFIED = "Last-Modified"; - private static final String IF_MODIFIED_SINCE = "If-Modified-Since"; - private static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; - private static final String E_TAG = "ETag"; - private static final String IF_NONE_MATCH = "If-None-Match"; - - @Override - public void doFilter(RequestHandler handler, HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - boolean isLastModified; - long sourceLastModified = -1; - if (isLastModified = handler instanceof LastModified) { - sourceLastModified = ((LastModified) handler).getLastModified(request); - } - - boolean isETag; - String sourceETag = null; - if (isETag = handler instanceof ETag) { - sourceETag = ((ETag) handler).getETag(request); - } - - Header ifUnmodifiedSinceHeader = request.getFirstHeader(IF_UNMODIFIED_SINCE); - if (isLastModified && ifUnmodifiedSinceHeader != null) { - if (!validateIfUnmodifiedSince(request, sourceLastModified)) { - response.setStatusCode(412); - return; - } - } - - Header ifModifiedSinceHeader = request.getFirstHeader(IF_MODIFIED_SINCE); - Header ifNoneMatchHeader = request.getFirstHeader(IF_NONE_MATCH); - if (isLastModified && isETag) { - if (ifModifiedSinceHeader != null && ifNoneMatchHeader != null) { - if (validateIfModifiedSince(request, sourceLastModified) && validateIfNoneMatch(request, sourceETag)) { - response.setStatusCode(304); - response.addHeader(CACHE_CONTROL, "public"); - response.addHeader(LAST_MODIFIED, generateLastModified(sourceLastModified)); - response.addHeader(E_TAG, generateETag(sourceETag)); - return; - } - } - } - - if (isLastModified && ifModifiedSinceHeader != null) { - if (validateIfModifiedSince(request, sourceLastModified)) { - response.setStatusCode(304); - response.addHeader(CACHE_CONTROL, "public"); - response.addHeader(LAST_MODIFIED, generateLastModified(sourceLastModified)); - return; - } - } - - handler.handle(request, response, context); - - if (isLastModified && sourceLastModified >= 0) { - response.addHeader(LAST_MODIFIED, generateLastModified(sourceLastModified)); - } - if (isETag && sourceETag != null) { - response.addHeader(E_TAG, generateETag(sourceETag)); - } - if (isLastModified) { - response.addHeader(CACHE_CONTROL, "public"); - } - } - - /** - * Generate the {@code ETag} header value from the given response body byte array. - *

The default implementation generates an MD5 hash.

- * - * @param tag tag of the source. - * @return the {@code ETag} header value. - */ - protected String generateETag(String tag) throws IOException { - return "\"0" + DigestUtils.md5DigestAsHex(tag) + '"'; - } - - /** - * Verify if the requested {@code If-None-Match} header is still valid. - * - * @param request current request. - * @param sourceETag tag of the source. - * @return true, otherwise is false. - */ - protected boolean validateIfNoneMatch(HttpRequest request, String sourceETag) { - Header eTagHeader = request.getFirstHeader(IF_NONE_MATCH); - if (sourceETag == null && eTagHeader == null) return true; - - if (sourceETag != null && eTagHeader != null) { - String ifNoneMatch = eTagHeader.getValue(); - return sourceETag.equalsIgnoreCase(ifNoneMatch); - } - return false; - } - - /** - * Generate the {@code Last-Modified} header value from the given response body byte array. - * - * @param lastModified last modified timestamp of the source. - * @return the {@code Last-Modified} header value. - */ - protected String generateLastModified(long lastModified) throws IOException { - return DateUtils.formatMillisToGMT(lastModified); - } - - /** - * Verify if the requested {@code If-Modified-Since} property is still valid. - * - * @param request current request. - * @param sourceLastModify last modified timestamp of the source. - * @return true, otherwise is false. - */ - protected boolean validateIfModifiedSince(HttpRequest request, long sourceLastModify) { - if (sourceLastModify < 0) { - return false; - } - long ifModifiedSince = parseDateHeader(request, IF_MODIFIED_SINCE); - if (ifModifiedSince < 0) { - return false; - } - return ifModifiedSince >= (sourceLastModify / 1000 * 1000); - } - - /** - * Verify if the requested {@code If-Unmodified-Since} property is still valid. - * - * @param request current request. - * @param sourceLastModify last modified timestamp of the source. - * @return true, otherwise is false. - */ - protected boolean validateIfUnmodifiedSince(HttpRequest request, long sourceLastModify) { - if (sourceLastModify < 0) { - return false; - } - long ifUnmodifiedSince = parseDateHeader(request, IF_UNMODIFIED_SINCE); - if (ifUnmodifiedSince < 0) { - return false; - } - return ifUnmodifiedSince < (sourceLastModify / 1000 * 1000); - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/interceptor/Interceptor.java b/andserver/src/main/java/com/yanzhenjie/andserver/interceptor/Interceptor.java deleted file mode 100644 index 778195e..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/interceptor/Interceptor.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.interceptor; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; - -/** - * Created by YanZhenjie on 2017/12/19. - */ -public interface Interceptor { - - /** - * When receiving a request, first ask if you intercept, - * if intercepted it will not be distributed to any {@code RequestHandler}. - */ - boolean onBeforeExecute(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException; - - /** - * Called after any {@code RequestHandler} response. - */ - void onAfterExecute(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException; - -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/protocol/LastModified.java b/andserver/src/main/java/com/yanzhenjie/andserver/protocol/LastModified.java deleted file mode 100644 index 4f8069b..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/protocol/LastModified.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.protocol; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; - -import java.io.IOException; - -/** - * Created by YanZhenjie on 2017/12/22. - */ -public interface LastModified { - - /** - * The return value will be sent to the HTTP client as {@code Last-Modified }header, - * and compared with {@code If-Modified-Since} headers that the client sends back. - * The content will only get regenerated if there has been a modification. - * - * @param request current HTTP request. - * @return the time the underlying resource was last modified, - * {@code <0} meaning that the content must always be regenerated. - */ - long getLastModified(HttpRequest request) throws HttpException, IOException; - -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/ssl/SSLSocketInitializer.java b/andserver/src/main/java/com/yanzhenjie/andserver/ssl/SSLSocketInitializer.java deleted file mode 100644 index 22a4364..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/ssl/SSLSocketInitializer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.ssl; - -import org.apache.httpcore.impl.bootstrap.SSLServerSetupHandler; - -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLServerSocket; - -/** - * Created by YanZhenjie on 2017/12/19. - */ -public interface SSLSocketInitializer { - - void onCreated(SSLServerSocket socket) throws SSLException; - - final class SSLSocketInitializerWrapper implements SSLServerSetupHandler { - - private SSLSocketInitializer mSSLSocketInitializer; - - public SSLSocketInitializerWrapper(SSLSocketInitializer initializer) { - this.mSSLSocketInitializer = initializer; - } - - public void initialize(SSLServerSocket socket) throws SSLException { - if (mSSLSocketInitializer != null) { - mSSLSocketInitializer.onCreated(socket); - } - } - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/upload/HttpFileUpload.java b/andserver/src/main/java/com/yanzhenjie/andserver/upload/HttpFileUpload.java deleted file mode 100644 index ea0e26c..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/upload/HttpFileUpload.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.upload; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.FileItemIterator; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.httpcore.HttpEntityEnclosingRequest; -import org.apache.httpcore.HttpRequest; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * Created by Yan Zhenjie on 2017/3/16. - */ -public class HttpFileUpload extends FileUpload { - - public HttpFileUpload() { - } - - public HttpFileUpload(FileItemFactory fileItemFactory) { - super(fileItemFactory); - } - - public List parseRequest(HttpRequest request) throws FileUploadException { - return parseRequest(new HttpUploadContext((HttpEntityEnclosingRequest) request)); - } - - public Map> parseParameterMap(HttpRequest request) throws FileUploadException { - return parseParameterMap(new HttpUploadContext((HttpEntityEnclosingRequest) request)); - } - - public FileItemIterator getItemIterator(HttpRequest request) throws FileUploadException, IOException { - return getItemIterator(new HttpUploadContext((HttpEntityEnclosingRequest) request)); - } -} diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/upload/HttpUploadContext.java b/andserver/src/main/java/com/yanzhenjie/andserver/upload/HttpUploadContext.java deleted file mode 100644 index 96dfb7e..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/upload/HttpUploadContext.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.upload; - -import org.apache.commons.fileupload.UploadContext; -import org.apache.httpcore.Header; -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpEntityEnclosingRequest; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Created by Yan Zhenjie on 2017/3/16. - */ -public class HttpUploadContext implements UploadContext { - - private final HttpEntity mEntity; - - public HttpUploadContext(HttpEntityEnclosingRequest request) { - this.mEntity = request.getEntity(); - } - - @Override - public String getCharacterEncoding() { - Header header = mEntity.getContentEncoding(); - return header == null ? null : header.getValue(); - } - - @Override - public String getContentType() { - Header header = mEntity.getContentType(); - return header == null ? null : header.getValue(); - } - - @Override - public int getContentLength() { - long contentLength = contentLength(); - return contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) contentLength; - } - - @Override - public long contentLength() { - return mEntity.getContentLength(); - } - - @Override - public InputStream getInputStream() throws IOException { - return this.mEntity.getContent(); - } -} diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/AssetsReader.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/AssetsReader.java deleted file mode 100644 index 3c0b2df..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/AssetsReader.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import android.content.res.AssetManager; -import android.text.TextUtils; - -import java.io.File; -import java.io.InputStream; -import java.util.LinkedList; -import java.util.List; - -/** - *

- * AssetManager wrapper. - *

- * Created by Yan Zhenjie on 2017/3/15. - */ -public class AssetsReader { - - /** - * {@link AssetManager}. - */ - private AssetManager mAssetManager; - - /** - * Create {@link AssetsReader}. - * - * @param assetManager {@link AssetManager}, such as: context.getAssets(); - */ - public AssetsReader(AssetManager assetManager) { - this.mAssetManager = assetManager; - } - - /** - * Get stream file. - * - * @param fileName assets in the absolute path. - * @return {@link InputStream} or null. - */ - public InputStream getInputStream(String fileName) { - try { - return mAssetManager.open(fileName); - } catch (Throwable ignored) { - return null; - } - } - - /** - * Specify whether the destination is a file. - * - * @param fileName assets in the absolute path. - * @return true, other wise is false. - */ - public boolean isFile(String fileName) { - return getInputStream(fileName) != null; - } - - /** - * Scanning subFolders and files under the specified path. - * - * @param path the specified path. - * @return String[] Array of strings, one for each asset. May be null. - */ - public String[] fileList(String path) { - try { - return mAssetManager.list(path); - } catch (Throwable ignored) { - return null; - } - } - - /** - * Scan all files in the inPath. - * - * @param inPath path in the path. - * @return under inPath absolute path. - */ - public List scanFile(String inPath) { - List pathList = new LinkedList<>(); - if (isFile(inPath)) { - pathList.add(inPath); - } else { - String[] files = fileList(inPath); - if (files != null && files.length > 0) { - for (String file : files) { - String realPath = (TextUtils.isEmpty(inPath) ? "" : (inPath + File.separator)) + file; - if (isFile(realPath)) pathList.add(realPath); - else { - List childList = scanFile(realPath); - if (childList.size() > 0) pathList.addAll(childList); - } - } - } - } - return pathList; - } - -} diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/DateUtils.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/DateUtils.java deleted file mode 100644 index 7669aad..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/DateUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -/** - * Created by YanZhenjie on 2017/12/22. - */ -public class DateUtils { - - /** - * Format of http head. - */ - public static final String FORMAT_HTTP_DATA = "EEE, dd MMM y HH:mm:ss 'GMT'"; - - /** - * Commmon TimeZone for GMT. - */ - public static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT"); - - /** - * Parsing the TimeZone of time in milliseconds. - * - * @param gmtTime GRM Time, Format such as: {@value #FORMAT_HTTP_DATA}. - * @return The number of milliseconds from 1970.1.1. - * @throws ParseException if an error occurs during parsing. - */ - public static long parseGMTToMillis(String gmtTime) throws ParseException { - SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_HTTP_DATA, Locale.US); - formatter.setTimeZone(GMT_TIME_ZONE); - Date date = formatter.parse(gmtTime); - return date.getTime(); - } - - /** - * Parsing the TimeZone of time from milliseconds. - * - * @param milliseconds the number of milliseconds from 1970.1.1. - * @return GRM Time, Format such as: {@value #FORMAT_HTTP_DATA}. - */ - public static String formatMillisToGMT(long milliseconds) { - Date date = new Date(milliseconds); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT_HTTP_DATA, Locale.US); - simpleDateFormat.setTimeZone(GMT_TIME_ZONE); - return simpleDateFormat.format(date); - } - -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/DigestUtils.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/DigestUtils.java deleted file mode 100644 index bb3ca39..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/DigestUtils.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import java.io.IOException; -import java.io.InputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Created by YanZhenjie on 2017/12/22. - */ -public abstract class DigestUtils { - - private static final String MD5_ALGORITHM_NAME = "MD5"; - - private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - /** - * Calculate the MD5 digest of string. - * - * @param string string to calculate the digest over. - * @return the digest. - */ - public static byte[] md5Digest(String string) { - return md5Digest(string.getBytes()); - } - - /** - * Calculate the MD5 digest of the given bytes. - * - * @param bytes the bytes to calculate the digest over. - * @return the digest. - */ - public static byte[] md5Digest(byte[] bytes) { - return digest(MD5_ALGORITHM_NAME, bytes); - } - - /** - * Calculate the MD5 digest of the given stream. - * - * @param inputStream the InputStream to calculate the digest over. - * @return the digest. - */ - public static byte[] md5Digest(InputStream inputStream) throws IOException { - return digest(MD5_ALGORITHM_NAME, inputStream); - } - - /** - * Return a hexadecimal string representation of the MD5 digest of string. - * - * @param string string to calculate the digest over. - * @return a hexadecimal digest string. - */ - public static String md5DigestAsHex(String string) { - return md5DigestAsHex(string.getBytes()); - } - - /** - * Return a hexadecimal string representation of the MD5 digest of the given bytes. - * - * @param bytes the bytes to calculate the digest over. - * @return a hexadecimal digest string. - */ - public static String md5DigestAsHex(byte[] bytes) { - return digestAsHexString(MD5_ALGORITHM_NAME, bytes); - } - - /** - * Return a hexadecimal string representation of the MD5 digest of the given stream. - * - * @param inputStream the InputStream to calculate the digest over. - * @return a hexadecimal digest string. - */ - public static String md5DigestAsHex(InputStream inputStream) throws IOException { - return digestAsHexString(MD5_ALGORITHM_NAME, inputStream); - } - - /** - * Append a hexadecimal string representation of the MD5 digest of the given - * bytes to the given {@link StringBuilder}. - * - * @param bytes the bytes to calculate the digest over. - * @param builder the string builder to append the digest to. - * @return the given string builder. - */ - public static StringBuilder appendMd5DigestAsHex(byte[] bytes, StringBuilder builder) { - return appendDigestAsHex(MD5_ALGORITHM_NAME, bytes, builder); - } - - /** - * Append a hexadecimal string representation of the MD5 digest of the given - * inputStream to the given {@link StringBuilder}. - * - * @param inputStream the inputStream to calculate the digest over. - * @param builder the string builder to append the digest to. - * @return the given string builder. - */ - public static StringBuilder appendMd5DigestAsHex(InputStream inputStream, StringBuilder builder) throws IOException { - return appendDigestAsHex(MD5_ALGORITHM_NAME, inputStream, builder); - } - - - /** - * Create a new {@link MessageDigest} with the given algorithm. - * Necessary because {@code MessageDigest} is not thread-safe. - */ - private static MessageDigest getDigest(String algorithm) { - try { - return MessageDigest.getInstance(algorithm); - } catch (NoSuchAlgorithmException ex) { - throw new IllegalStateException("Could not find MessageDigest with algorithm \"" + algorithm + "\"", ex); - } - } - - private static byte[] digest(String algorithm, byte[] bytes) { - return getDigest(algorithm).digest(bytes); - } - - private static byte[] digest(String algorithm, InputStream inputStream) throws IOException { - MessageDigest messageDigest = getDigest(algorithm); - final byte[] buffer = new byte[2048]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) != -1) { - messageDigest.update(buffer, 0, bytesRead); - } - return messageDigest.digest(); - } - - private static String digestAsHexString(String algorithm, byte[] bytes) { - char[] hexDigest = digestAsHexChars(algorithm, bytes); - return new String(hexDigest); - } - - private static String digestAsHexString(String algorithm, InputStream inputStream) throws IOException { - char[] hexDigest = digestAsHexChars(algorithm, inputStream); - return new String(hexDigest); - } - - private static StringBuilder appendDigestAsHex(String algorithm, byte[] bytes, StringBuilder builder) { - char[] hexDigest = digestAsHexChars(algorithm, bytes); - return builder.append(hexDigest); - } - - private static StringBuilder appendDigestAsHex(String algorithm, InputStream inputStream, StringBuilder builder) - throws IOException { - - char[] hexDigest = digestAsHexChars(algorithm, inputStream); - return builder.append(hexDigest); - } - - private static char[] digestAsHexChars(String algorithm, byte[] bytes) { - byte[] digest = digest(algorithm, bytes); - return encodeHex(digest); - } - - private static char[] digestAsHexChars(String algorithm, InputStream inputStream) throws IOException { - byte[] digest = digest(algorithm, inputStream); - return encodeHex(digest); - } - - private static char[] encodeHex(byte[] bytes) { - char chars[] = new char[32]; - for (int i = 0; i < chars.length; i = i + 2) { - byte b = bytes[i / 2]; - chars[i] = HEX_CHARS[(b >>> 0x4) & 0xf]; - chars[i + 1] = HEX_CHARS[b & 0xf]; - } - return chars; - } - -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/Executors.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/Executors.java deleted file mode 100644 index 78abe48..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/Executors.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import android.os.Handler; -import android.os.Looper; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - -/** - *

- * Thread executor. - *

- * Created by Yan Zhenjie on 2016/6/13. - */ -public final class Executors { - - private static Executors instance; - - /** - * Get instance. - * - * @return {@link Executors}. - */ - public static Executors getInstance() { - if (instance == null) - synchronized (Executors.class) { - if (instance == null) - instance = new Executors(); - } - return instance; - } - - /** - * Executor Service. - */ - private final ExecutorService mService; - - /** - * Handler. - */ - private static Handler mHandler; - - private Executors() { - mService = java.util.concurrent.Executors.newCachedThreadPool(); - mHandler = new Handler(Looper.getMainLooper()); - } - - /** - * Execute a runnable. - */ - public void execute(Runnable runnable) { - mService.execute(runnable); - } - - /** - * Submit a runnable. - */ - public Future submit(Runnable runnable) { - return mService.submit(runnable); - } - - /** - * Submit a runnable. - */ - public Future submit(Runnable runnable, T result) { - return mService.submit(runnable, result); - } - - /** - * Submit a callable. - */ - public Future submit(Callable callable) { - return mService.submit(callable); - } - - /** - * Post a runnable. - */ - public void post(Runnable command) { - mHandler.post(command); - } -} diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/FileUtils.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/FileUtils.java deleted file mode 100644 index 6c16d69..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/FileUtils.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import android.text.TextUtils; -import android.webkit.MimeTypeMap; - -/** - * Created by YanZhenjie on 2017/12/19. - */ -public class FileUtils { - - /** - * Get MimeType of file path. - * - * @param path file path. - * @return get contentType based on file name, if not {@code application/octet-stream}. - */ - public static String getMimeType(String path) { - String mimeType = "application/octet-stream"; - if (!TextUtils.isEmpty(path)) { - String extension = MimeTypeMap.getFileExtensionFromUrl(path); - if (MimeTypeMap.getSingleton().hasExtension(extension)) - mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - } - return mimeType; - } - -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/HttpRequestParser.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/HttpRequestParser.java deleted file mode 100644 index 8f8d066..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/HttpRequestParser.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import android.text.TextUtils; - -import com.yanzhenjie.andserver.RequestMethod; -import com.yanzhenjie.andserver.upload.HttpUploadContext; - -import org.apache.commons.fileupload.FileUploadBase; -import org.apache.httpcore.Header; -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpEntityEnclosingRequest; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.util.EntityUtils; - -import java.io.IOException; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.StringTokenizer; - -/** - *

- * Parsing {@link HttpRequest}. - *

- * Created by Yan Zhenjie on 2016/6/13. - */ -public class HttpRequestParser { - - public static final String CHARSET_UTF8 = "utf-8"; - - /** - * Parse params from {@link HttpRequest}. - * - * @param request {@link HttpRequest}. - * @return parameter key-value pairs. - * @throws IOException if it is a POST request IO exception might occur when get the data. - */ - public static Map parseParams(HttpRequest request) throws IOException { - return parseParams(request, false); - } - - /** - * Parse params from {@link HttpRequest}. - * - * @param request {@link HttpRequest}. - * @param lowerCaseNames key to lowercase. - * @return parameter key-value pairs. - * @throws IOException if it is a POST request IO exception might occur when get the data. - */ - public static Map parseParams(HttpRequest request, boolean lowerCaseNames) throws IOException { - String content = getContent(request); - return splitHttpParams(content, lowerCaseNames); - } - - /** - * Split http params. - * - * @param content target content. - * @param lowerCaseNames key to lowercase. - * @return parameter key-value pairs. - */ - public static Map splitHttpParams(String content, boolean lowerCaseNames) { - Map paramMap = new HashMap<>(); - StringTokenizer tokenizer = new StringTokenizer(content, "&"); - while (tokenizer.hasMoreElements()) { - String keyValue = tokenizer.nextToken(); - int index = keyValue.indexOf("="); - if (index > 0) { - String key = keyValue.substring(0, index); - if (lowerCaseNames) - key = key.toLowerCase(Locale.ENGLISH); - paramMap.put(key, UrlCoder.urlDecode(keyValue.substring(index + 1), CHARSET_UTF8)); - } - } - return paramMap; - } - - /** - * Obtain the contents of the Request. - */ - public static String getContent(HttpRequest request) throws IOException { - if (isAllowRequestBody(request)) { - return getContentFromBody(request); - } else { - return getContentFromUri(request); - } - } - - /** - * Obtain the contents of the RequestBody. - */ - public static String getContentFromBody(HttpRequest request) throws IOException { - HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); - String charset = parseHeadValue(entity.getContentType().getValue(), "charset", CHARSET_UTF8); - return EntityUtils.toString(entity, charset); - } - - /** - * Obtain the parameters from the URI path. - */ - public static String getContentFromUri(HttpRequest request) { - String uri = request.getRequestLine().getUri(); - int index = uri.indexOf('?'); - return (index == -1) || (index + 1 >= uri.length()) ? "" : uri.substring(index + 1); - } - - /** - * Obtain the path of the current request. - */ - public static String getRequestPath(HttpRequest request) { - String uriPath = request.getRequestLine().getUri(); - int index = uriPath.indexOf("?"); - if (index != -1) { - uriPath = uriPath.substring(0, index); - } else { - index = uriPath.indexOf("#"); - if (index != -1) { - uriPath = uriPath.substring(0, index); - } - } - String[] pathArray = uriPath.split("/"); - if (pathArray.length > 1) { - List pathList = new ArrayList<>(); - for (String path : pathArray) { - path = UrlCoder.urlDecode(path, "utf-8"); - pathList.add(path); - } - uriPath = TextUtils.join("/", pathList); - } - return uriPath; - } - - /** - * Is this a request that allows a body? - */ - public static boolean isAllowRequestBody(HttpRequest request) { - return getRequestMethod(request).allowRequestBody(); - } - - /** - * Get the RequestMethod of Request. - */ - public static RequestMethod getRequestMethod(HttpRequest request) { - String method = request.getRequestLine().getMethod(); - return RequestMethod.reverse(method); - } - - /** - * Whether to allow the RequestBody with the request. - */ - public static boolean isMultipartContentRequest(HttpRequest request) { - if (!(request instanceof HttpEntityEnclosingRequest)) return false; - HttpEntityEnclosingRequest enclosingRequest = (HttpEntityEnclosingRequest) request; - return isAllowRequestBody(request) && FileUploadBase.isMultipartContent(new HttpUploadContext(enclosingRequest)); - } - - /** - * Parse the request for the specified time header. - */ - public static long parseDateHeader(HttpRequest request, String headerName) { - Header header = request.getFirstHeader(headerName); - if (header != null) { - String dateValue = header.getValue(); - try { - return DateUtils.parseGMTToMillis(dateValue); - } catch (ParseException ex) { - int separatorIndex = dateValue.indexOf(';'); - if (separatorIndex != -1) { - String datePart = dateValue.substring(0, separatorIndex); - try { - return DateUtils.parseGMTToMillis(datePart); - } catch (ParseException ignored) { - } - } - } - } - return -1; - } - - /** - * A value of the header information. - * - * @param content like {@code text/html;charset=utf-8}. - * @param key like {@code charset}. - * @param defaultValue list {@code utf-8}. - * @return If you have a value key, you will return the parsed value if you don't return the default value. - */ - public static String parseHeadValue(String content, String key, String defaultValue) { - if (!TextUtils.isEmpty(content) && !TextUtils.isEmpty(key)) { - StringTokenizer stringTokenizer = new StringTokenizer(content, ";"); - while (stringTokenizer.hasMoreElements()) { - String valuePair = stringTokenizer.nextToken(); - int index = valuePair.indexOf('='); - if (index > 0) { - String name = valuePair.substring(0, index).trim(); - if (key.equalsIgnoreCase(name)) { - defaultValue = valuePair.substring(index + 1).trim(); - break; - } - } - } - } - return defaultValue; - } - -} diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java b/andserver/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java deleted file mode 100644 index 23ac3cf..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright © 2018 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.util; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.nio.charset.Charset; - -/** - * Created by YanZhenjie on 2018/2/20. - */ -public class UrlCoder { - - public static String urlEncode(String target, String charset) { - try { - return URLEncoder.encode(target, charset); - } catch (UnsupportedEncodingException e) { - return target; - } - } - - public static String urlEncode(String target, Charset charset) { - return urlEncode(target, charset.name()); - } - - public static String urlDecode(String target, String charset) { - try { - return URLDecoder.decode(target, charset); - } catch (UnsupportedEncodingException e) { - return target; - } - } - - public static String urlDecode(String target, Charset charset) { - return urlDecode(target, charset.name()); - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/view/View.java b/andserver/src/main/java/com/yanzhenjie/andserver/view/View.java deleted file mode 100644 index 5dabbf0..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/view/View.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.view; - -import org.apache.httpcore.Header; -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.StringEntity; -import org.apache.httpcore.message.BasicHeader; -import org.apache.httpcore.message.HeaderGroup; - -/** - * Created by YanZhenjie on 2017/12/19. - */ -public class View { - - private int mHttpCode; - private HttpEntity mHttpEntity; - private HeaderGroup mHeaderGroup; - - public View(int httpCode) { - this(httpCode, (HttpEntity) null); - } - - public View(int httpCode, String httpBody) { - this(httpCode, new StringEntity(httpBody, ContentType.TEXT_PLAIN)); - } - - public View(int httpCode, HttpEntity httpEntity) { - this.mHttpCode = httpCode; - this.mHttpEntity = httpEntity; - this.mHeaderGroup = new HeaderGroup(); - } - - public int getHttpCode() { - return mHttpCode; - } - - public void setHeader(String key, String value) { - mHeaderGroup.updateHeader(new BasicHeader(key, value)); - } - - public void addHeader(String key, String value) { - mHeaderGroup.addHeader(new BasicHeader(key, value)); - } - - public Header[] getHeaders() { - return mHeaderGroup.getAllHeaders(); - } - - public HttpEntity getHttpEntity() { - return mHttpEntity; - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/website/AssetsWebsite.java b/andserver/src/main/java/com/yanzhenjie/andserver/website/AssetsWebsite.java deleted file mode 100644 index 540956e..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/website/AssetsWebsite.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.website; - -import android.content.res.AssetManager; -import android.os.SystemClock; - -import com.yanzhenjie.andserver.exception.NotFoundException; -import com.yanzhenjie.andserver.protocol.ETag; -import com.yanzhenjie.andserver.protocol.LastModified; -import com.yanzhenjie.andserver.util.AssetsReader; -import com.yanzhenjie.andserver.view.View; - -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.InputStreamEntity; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static com.yanzhenjie.andserver.util.FileUtils.getMimeType; -import static com.yanzhenjie.andserver.util.HttpRequestParser.getRequestPath; - -/** - *

- * The web site in assets. - *

- * Created by Yan Zhenjie on 2017/3/15. - */ -public class AssetsWebsite extends SimpleWebsite implements LastModified, ETag { - - private final AssetsReader mAssetsReader; - private final String mRootPath; - private final Map mPatternMap; - - private boolean isScanned; - - - /** - * Assets Website. - * - * @param assetManager {@link AssetsReader}. - * @param rootPath site root directory in assets, such as: {@code ""}, {@code "website"}. - */ - public AssetsWebsite(AssetManager assetManager, String rootPath) { - this.mAssetsReader = new AssetsReader(assetManager); - this.mRootPath = rootPath; - this.mPatternMap = new LinkedHashMap<>(); - } - - @Override - public boolean intercept(HttpRequest request, HttpContext context) { - tryScanFile(); - - String httpPath = getRequestPath(request); - return mPatternMap.containsKey(httpPath); - } - - /** - * Try to scan the file, no longer scan if it has already been scanned. - */ - private void tryScanFile() { - if (!isScanned) { - synchronized (AssetsWebsite.class) { - if (!isScanned) { - onScanFile(mRootPath, mAssetsReader, mPatternMap); - isScanned = true; - } - } - } - } - - /** - * Scan Assets under the file. - * - * @param rootPath The location to scan. - * @param assetsReader Asset content reader. - * @param patternMap The file corresponds to the http path as the key, the file path as the value. - */ - protected void onScanFile(String rootPath, AssetsReader assetsReader, Map patternMap) { - List fileList = assetsReader.scanFile(rootPath); - if (fileList.size() > 0) { - for (String filePath : fileList) { - String httpPath = trimStartSlash(filePath); - httpPath = httpPath.substring(rootPath.length(), httpPath.length()); - httpPath = addStartSlash(httpPath); - patternMap.put(httpPath, filePath); - - if (filePath.endsWith(INDEX_FILE_PATH)) { - httpPath = httpPath.substring(0, httpPath.indexOf(INDEX_FILE_PATH)); - patternMap.put(httpPath, filePath); - patternMap.put(addEndSlash(httpPath), filePath); - } - } - } - } - - @Override - public View handle(HttpRequest request) throws HttpException, IOException { - String httpPath = getRequestPath(request); - String filePath = mPatternMap.get(httpPath); - InputStream source = mAssetsReader.getInputStream(filePath); - if (source == null) - throw new NotFoundException(httpPath); - - int length = source.available(); - String mimeType = getMimeType(filePath); - - HttpEntity httpEntity = new InputStreamEntity(source, length, ContentType.create(mimeType, Charset.defaultCharset())); - return new View(200, httpEntity); - } - - @Override - public long getLastModified(HttpRequest request) throws IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - String filePath = mPatternMap.get(httpPath); - InputStream source = mAssetsReader.getInputStream(filePath); - if (source != null) - return System.currentTimeMillis() - SystemClock.currentThreadTimeMillis(); - return -1; - } - - @Override - public String getETag(HttpRequest request) throws IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - String filePath = mPatternMap.get(httpPath); - InputStream source = mAssetsReader.getInputStream(filePath); - if (source != null) { - long sourceSize = source.available(); - return sourceSize + filePath; - } - return null; - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/website/FileBrowser.java b/andserver/src/main/java/com/yanzhenjie/andserver/website/FileBrowser.java deleted file mode 100644 index 9a35b83..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/website/FileBrowser.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.website; - -import com.yanzhenjie.andserver.exception.NotFoundException; -import com.yanzhenjie.andserver.protocol.ETag; -import com.yanzhenjie.andserver.protocol.LastModified; -import com.yanzhenjie.andserver.view.View; - -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.FileEntity; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; - -import static com.yanzhenjie.andserver.util.FileUtils.getMimeType; -import static com.yanzhenjie.andserver.util.HttpRequestParser.getRequestPath; - -/** - * Created by YanZhenjie on 2017/12/23. - */ -public class FileBrowser extends SimpleWebsite implements LastModified, ETag { - - private final String mRootPath; - - public FileBrowser(String rootPath) { - this.mRootPath = rootPath; - } - - @Override - public boolean intercept(HttpRequest request, HttpContext context) throws HttpException, IOException { - String httpPath = getRequestPath(request); - httpPath = "/".equals(httpPath) ? "/" : trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - return source != null; - } - - /** - * Find the path specified resource. - * - * @param httpPath path. - * @return return if the file is found. - */ - private File findPathSource(String httpPath) { - if ("/".equals(httpPath)) { - return new File(mRootPath); - } else { - File sourceFile = new File(mRootPath, httpPath); - if (sourceFile.exists()) { - return sourceFile; - } - } - return null; - } - - @Override - public View handle(HttpRequest request) throws HttpException, IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - if (source == null) - throw new NotFoundException(httpPath); - return generatePageView(source); - } - - /** - * Generate {@code View} for page of folder. - * - * @param source folder. - * @return view of folder. - */ - private View generatePageView(File source) throws IOException { - if (source.isDirectory()) { - File[] files = source.listFiles(); - File tempFile = File.createTempFile("file_browser", ".html"); - OutputStream outputStream = new FileOutputStream(tempFile); - - String folderName = source.getName(); - String prefix = String.format(FOLDER_HTML_PREFIX, folderName, folderName); - outputStream.write(prefix.getBytes("utf-8")); - - if (files != null && files.length > 0) { - for (File file : files) { - String filePath = file.getAbsolutePath(); - int rootIndex = filePath.indexOf(mRootPath); - String httpPath = filePath.substring(rootIndex + mRootPath.length()); - httpPath = addStartSlash(httpPath); - String fileItem = String.format(FOLDER_ITEM, httpPath, file.getName()); - outputStream.write(fileItem.getBytes("utf-8")); - } - } - - outputStream.write(FOLDER_HTML_SUFFIX.getBytes("utf-8")); - return generateSourceView(tempFile); - } else { - return generateSourceView(source); - } - } - - /** - * Generate {@code View} for source. - * - * @param source file. - * @return view of source. - */ - private View generateSourceView(File source) throws IOException { - String mimeType = getMimeType(source.getAbsolutePath()); - HttpEntity httpEntity = new FileEntity(source, ContentType.create(mimeType, Charset.defaultCharset())); - return new View(200, httpEntity); - } - - @Override - public long getLastModified(HttpRequest request) throws IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - if (source != null && source.isFile()) - return source.lastModified(); - return -1; - } - - @Override - public String getETag(HttpRequest request) throws IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - if (source != null && source.isFile()) { - long sourceSize = source.length(); - String sourcePath = source.getAbsolutePath(); - long lastModified = source.lastModified(); - return sourceSize + sourcePath + lastModified; - } - return null; - } - - private static final String FOLDER_HTML_PREFIX - = "" - + "" - + "" - + "" - + "" - + "" - + "%1$s" - + "" - + "" - + "" - + "

%2$s

" - + "
    "; - private static final String FOLDER_ITEM = "
  • %2$s
  • "; - private static final String FOLDER_HTML_SUFFIX - = "
" - + "" - + ""; -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/website/SimpleWebsite.java b/andserver/src/main/java/com/yanzhenjie/andserver/website/SimpleWebsite.java deleted file mode 100644 index 5897c7f..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/website/SimpleWebsite.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.website; - -import com.yanzhenjie.andserver.view.View; -import com.yanzhenjie.andserver.exception.NotFoundException; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.File; -import java.io.IOException; - -import static com.yanzhenjie.andserver.util.HttpRequestParser.getRequestPath; - -/** - *

Basic website.

- * Created by Yan Zhenjie on 2017/3/16. - */ -public abstract class SimpleWebsite implements WebSite { - - protected static final String INDEX_FILE_PATH = "/index.html"; - - /** - * Remove the '/' at the beginning. - * - * @param target target string. - * @return rule result. - */ - protected String addStartSlash(String target) { - if (!target.startsWith(File.separator)) target = File.separator + target; - return target; - } - - /** - * Remove the '/' at the beginning. - * - * @param target target string. - * @return rule result. - */ - protected String addEndSlash(String target) { - if (!target.endsWith(File.separator)) target = target + File.separator; - return target; - } - - /** - * Remove the '/' at the beginning. - * - * @param target target string. - * @return rule result. - */ - protected String trimStartSlash(String target) { - while (target.startsWith(File.separator)) target = target.substring(1); - return target; - } - - /** - * Remove the '/' at the end of the string. - * - * @param target target string. - * @return rule result. - */ - protected String trimEndSlash(String target) { - while (target.endsWith(File.separator)) target = target.substring(0, target.length() - 1); - return target; - } - - /** - * Remove the '/' at the beginning and end of the string. - * - * @param target target string. - * @return rule result. - */ - protected String trimSlash(String target) { - target = trimStartSlash(target); - target = trimEndSlash(target); - return target; - } - - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - View view = handle(request, response); - response.setStatusCode(view.getHttpCode()); - response.setEntity(view.getHttpEntity()); - response.setHeaders(view.getHeaders()); - } - - protected View handle(HttpRequest request, HttpResponse response) throws HttpException, IOException { - return handle(request); - } - - protected View handle(HttpRequest request) throws HttpException, IOException { - throw new NotFoundException(getRequestPath(request)); - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/website/StorageWebsite.java b/andserver/src/main/java/com/yanzhenjie/andserver/website/StorageWebsite.java deleted file mode 100644 index 76f2bee..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/website/StorageWebsite.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.website; - -import com.yanzhenjie.andserver.exception.NotFoundException; -import com.yanzhenjie.andserver.protocol.ETag; -import com.yanzhenjie.andserver.protocol.LastModified; -import com.yanzhenjie.andserver.view.View; - -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.FileEntity; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; - -import static com.yanzhenjie.andserver.util.FileUtils.getMimeType; -import static com.yanzhenjie.andserver.util.HttpRequestParser.getRequestPath; - -/** - *

- * The web site in storage. - *

- * Created by Yan Zhenjie on 2017/3/15. - */ -public class StorageWebsite extends SimpleWebsite implements LastModified, ETag { - - private final String mRootPath; - - public StorageWebsite(String rootPath) { - this.mRootPath = rootPath; - } - - @Override - public boolean intercept(HttpRequest request, HttpContext context) throws HttpException, IOException { - String httpPath = getRequestPath(request); - httpPath = "/".equals(httpPath) ? "/" : trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - return source != null; - } - - /** - * Find the path specified resource. - * - * @param httpPath path. - * @return return if the file is found. - */ - private File findPathSource(String httpPath) { - if ("/".equals(httpPath)) { - File indexFile = new File(mRootPath, INDEX_FILE_PATH); - if (indexFile.exists() && indexFile.isFile()) { - return indexFile; - } - } else { - File sourceFile = new File(mRootPath, httpPath); - if (sourceFile.exists()) { - if (sourceFile.isFile()) { - return sourceFile; - } else { - File childIndexFile = new File(sourceFile, INDEX_FILE_PATH); - if (childIndexFile.exists() && childIndexFile.isFile()) { - return childIndexFile; - } - } - } - } - return null; - } - - @Override - public View handle(HttpRequest request) throws HttpException, IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - if (source == null) - throw new NotFoundException(httpPath); - return generateSourceView(source); - } - - /** - * Generate {@code View} for source. - * - * @param source file. - * @return view of source. - */ - private View generateSourceView(File source) throws IOException { - String mimeType = getMimeType(source.getAbsolutePath()); - HttpEntity httpEntity = new FileEntity(source, ContentType.create(mimeType, Charset.defaultCharset())); - return new View(200, httpEntity); - } - - @Override - public long getLastModified(HttpRequest request) throws IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - if (source != null) - return source.lastModified(); - return -1; - } - - @Override - public String getETag(HttpRequest request) throws IOException { - String httpPath = trimEndSlash(getRequestPath(request)); - File source = findPathSource(httpPath); - if (source != null) { - long sourceSize = source.length(); - String sourcePath = source.getAbsolutePath(); - long lastModified = source.lastModified(); - return sourceSize + sourcePath + lastModified; - } - return null; - } -} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/website/WebSite.java b/andserver/src/main/java/com/yanzhenjie/andserver/website/WebSite.java deleted file mode 100644 index 87a7731..0000000 --- a/andserver/src/main/java/com/yanzhenjie/andserver/website/WebSite.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.website; - -import com.yanzhenjie.andserver.RequestHandler; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; - -/** - *

- * Registration website interface. - *

- * Created by Yan Zhenjie on 2017/3/15. - */ -public interface WebSite extends RequestHandler { - - boolean intercept(HttpRequest request, HttpContext context) throws HttpException, IOException; -} \ No newline at end of file diff --git a/andserver/.gitignore b/annotation/.gitignore similarity index 100% rename from andserver/.gitignore rename to annotation/.gitignore diff --git a/annotation/build.gradle b/annotation/build.gradle new file mode 100644 index 0000000..1fb914a --- /dev/null +++ b/annotation/build.gradle @@ -0,0 +1,6 @@ +apply plugin: rootProject.ext.plugins.javaLibrary + +compileJava { + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 +} \ No newline at end of file diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/api/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/andserver/build.gradle b/api/build.gradle similarity index 75% rename from andserver/build.gradle rename to api/build.gradle index d27d8e4..42084a2 100644 --- a/andserver/build.gradle +++ b/api/build.gradle @@ -1,4 +1,4 @@ -apply plugin: rootProject.ext.plugins.library +apply plugin: rootProject.ext.plugins.androidLibrary android { compileSdkVersion rootProject.ext.android.compileSdkVersion @@ -11,8 +11,9 @@ android { } dependencies { + // api rootProject.ext.dependencies.andserverAnnotation + api project(':annotation') + implementation rootProject.ext.dependencies.httpcore implementation rootProject.ext.dependencies.fileupload -} - -apply from: 'https://raw.githubusercontent.com/yanzhenjie/bintray/master/maven.gradle' \ No newline at end of file +} \ No newline at end of file diff --git a/andserver/src/main/AndroidManifest.xml b/api/src/main/AndroidManifest.xml similarity index 91% rename from andserver/src/main/AndroidManifest.xml rename to api/src/main/AndroidManifest.xml index 02ea420..56bf3d0 100644 --- a/andserver/src/main/AndroidManifest.xml +++ b/api/src/main/AndroidManifest.xml @@ -14,6 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - \ No newline at end of file + \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/AndServer.java b/api/src/main/java/com/yanzhenjie/andserver/AndServer.java similarity index 70% rename from andserver/src/main/java/com/yanzhenjie/andserver/AndServer.java rename to api/src/main/java/com/yanzhenjie/andserver/AndServer.java index d9d3f3a..80bd12c 100644 --- a/andserver/src/main/java/com/yanzhenjie/andserver/AndServer.java +++ b/api/src/main/java/com/yanzhenjie/andserver/AndServer.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016 Yan Zhenjie. + * Copyright 2018 Yan Zhenjie. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,6 @@ package com.yanzhenjie.andserver; /** - *

- * Server entrance. - *

- * Created by Yan Zhenjie on 2016/6/13. + * Created by YanZhenjie on 2018/6/9. */ -public class AndServer { - - private AndServer() { - } - - public static Server.Builder serverBuilder() { - return Core.newBuilder(); - } -} \ No newline at end of file +public class AndServer {} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 4de4d6e..b66ab42 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.android.tools.build:gradle:3.1.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' } diff --git a/config.gradle b/config.gradle index d12400a..909f718 100644 --- a/config.gradle +++ b/config.gradle @@ -1,64 +1,61 @@ ext { - plugins = [ - java : 'java', - library : 'com.android.library', - application: 'com.android.application', - maven : 'com.github.dcendents.android-maven', - bintray : 'com.jfrog.bintray' - ] - - android = [ - applicationId : "com.yanzhenjie.andserver.sample", - compileSdkVersion : 27, - buildToolsVersion : "27.0.3", - - libraryMinSdkVersion : 9, - libraryTargetSdkVersion: 27, - sampleMinSdkVersion : 14, - sampleTargetSdkVersion : 22, - - versionCode : 16, - versionName : "1.1.4", - ] - - bintray = [ - // library - version : "1.1.4", - - siteUrl : 'https://github.com/yanzhenjie/AndServer', - gitUrl : 'git@github.com:yanzhenjie/AndServer.git', - - group : "com.yanzhenjie", - - // project - packaging : 'aar', - name : 'AndServer', - description : 'Android web server', - - // project.license - licenseName : 'The Apache Software License, Version 2.0', - licenseUrl : 'http://www.apache.org/licenses/LICENSE-2.0.txt', - - // project.developers - developerId : 'yanzhenjie', - developerName : 'yanzhenjie', - developerEmail: 'smallajax@foxmail.com', - - // bintray - binrayLibrary : "andserver", - bintrayRepo : "maven", - bintrayUser : 'yolanda', - bintrayLicense: "Apache-2.0" - ] - - dependencies = [ - httpcore : "com.yanzhenjie.apache:httpcore:4.4.9", - fileupload: "com.yanzhenjie.apache:fileupload:1.3.3", - - andserver : 'com.yanzhenjie:andserver:1.1.4', - appCompat : 'com.android.support:appcompat-v7:27.1.1', - design : 'com.android.support:design:27.1.1', - - loading : 'com.yanzhenjie:loading:1.0.0' - ] + plugins = [java : 'java', + javaLibrary : 'java-library', + javaPluginGradle: 'java-gradle-plugin', + android : 'com.android.application', + androidLibrary : 'com.android.library', + maven : 'com.github.dcendents.android-maven', + bintray : 'com.jfrog.bintray', + andserver : 'com.yanzhenjie.andserver'] + + android = [applicationId : "com.yanzhenjie.andserver.sample", + compileSdkVersion : 27, + buildToolsVersion : "27.0.3", + + libraryMinSdkVersion : 9, + libraryTargetSdkVersion: 27, + sampleMinSdkVersion : 14, + sampleTargetSdkVersion : 22, + + versionCode : 17, + versionName : "2.0.0",] + + bintray = [version : "2.0.0-alpha", + + siteUrl : 'https://github.com/yanzhenjie/AndServer', + gitUrl : 'git@github.com:yanzhenjie/AndServer.git', + + group : "com.yanzhenjie.andserver", + + packaging : 'aar', + name : 'AndServer', + description : 'Android web server', + + licenseName : 'The Apache Software License, Version 2.0', + licenseUrl : 'http://www.apache.org/licenses/LICENSE-2.0.txt', + + developerId : 'yanzhenjie', + developerName : 'yanzhenjie', + developerEmail: 'smallajax@foxmail.com', + + binrayLibrary : "", + bintrayRepo : "maven", + bintrayUser : 'yolanda', + bintrayLicense: "Apache-2.0"] + + dependencies = [autoService : 'com.google.auto.service:auto-service:1.0-rc4', + javaPoet : 'com.squareup:javapoet:1.11.1', + commonsLang : 'org.apache.commons:commons-lang3:3.7', + commonsCollections : 'org.apache.commons:commons-collections4:4.1', + httpcore : "com.yanzhenjie.apache:httpcore:4.4.9", + fileupload : "com.yanzhenjie.apache:fileupload:1.3.3", + + andserverApi : 'com.yanzhenjie.andserver:api:2.0.0-alpha', + andserverAnnotation: 'com.yanzhenjie.andserver:annotation:2.0.0-alpha', + andserverProcessor : 'com.yanzhenjie.andserver:processor:2.0.0-alpha', + + appCompat : 'com.android.support:appcompat-v7:27.1.1', + design : 'com.android.support:design:27.1.1', + loading : 'com.yanzhenjie:loading:1.0.0', + fastJson : 'com.alibaba:fastjson:1.1.68.android',] } \ No newline at end of file diff --git a/gradle-plugin/.gitignore b/gradle-plugin/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/gradle-plugin/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/gradle-plugin/build.gradle b/gradle-plugin/build.gradle new file mode 100644 index 0000000..c3f4ca7 --- /dev/null +++ b/gradle-plugin/build.gradle @@ -0,0 +1,21 @@ +apply plugin: rootProject.ext.plugins.javaPluginGradle + +compileJava { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + implementation rootProject.ext.dependencies.javaPoet +} + +gradlePlugin { + plugins { + andserver { + id = rootProject.ext.bintray.group + implementationClass = 'com.yanzhenjie.andserver.plugin.LauncherPlugin' + } + } +} + +apply from: 'maven.gradle' \ No newline at end of file diff --git a/gradle-plugin/maven.gradle b/gradle-plugin/maven.gradle new file mode 100644 index 0000000..7c6ea0e --- /dev/null +++ b/gradle-plugin/maven.gradle @@ -0,0 +1,12 @@ +apply plugin: 'maven-publish' + +group = rootProject.ext.bintray.group +version = rootProject.ext.bintray.version + +publishing { + repositories { + maven { + url "../maven-repo" + } + } +} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/exception/NotFoundException.java b/gradle-plugin/src/main/java/com/yanzhenjie/andserver/plugin/LauncherPlugin.java similarity index 66% rename from andserver/src/main/java/com/yanzhenjie/andserver/exception/NotFoundException.java rename to gradle-plugin/src/main/java/com/yanzhenjie/andserver/plugin/LauncherPlugin.java index 8060f1b..f559ee2 100644 --- a/andserver/src/main/java/com/yanzhenjie/andserver/exception/NotFoundException.java +++ b/gradle-plugin/src/main/java/com/yanzhenjie/andserver/plugin/LauncherPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Yan Zhenjie. + * Copyright 2018 Yan Zhenjie. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.yanzhenjie.andserver.exception; +package com.yanzhenjie.andserver.plugin; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; /** - * Created by YanZhenjie on 2017/12/18. + * Created by YanZhenjie on 2018/6/8. */ -public class NotFoundException extends BaseException { +public class LauncherPlugin implements Plugin { - public NotFoundException(String path) { - super(404, String.format("The resource [%1$s] does not exist.", path)); + @Override + public void apply(Project project) { } } \ No newline at end of file diff --git a/processor/.gitignore b/processor/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/processor/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/processor/build.gradle b/processor/build.gradle new file mode 100644 index 0000000..04b850d --- /dev/null +++ b/processor/build.gradle @@ -0,0 +1,20 @@ +apply plugin: rootProject.ext.plugins.javaLibrary + +compileJava { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + // api rootProject.ext.dependencies.andserverAnnotation + implementation project(':annotation') + + implementation rootProject.ext.dependencies.autoService + implementation rootProject.ext.dependencies.javaPoet + + implementation rootProject.ext.dependencies.commonsLang + implementation rootProject.ext.dependencies.commonsCollections + + implementation rootProject.ext.dependencies.httpcore + implementation rootProject.ext.dependencies.fileupload +} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/BaseProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/BaseProcessor.java new file mode 100644 index 0000000..6e88e59 --- /dev/null +++ b/processor/src/main/java/com/yanzhenjie/andserver/processor/BaseProcessor.java @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Yan Zhenjie. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.yanzhenjie.andserver.processor; + +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.lang.model.SourceVersion; + +/** + * Created by YanZhenjie on 2018/6/8. + */ +public abstract class BaseProcessor extends AbstractProcessor { + + @Override + public final SourceVersion getSupportedSourceVersion() { + return SourceVersion.latestSupported(); + } + + @Override + public final Set getSupportedAnnotationTypes() { + Set> classSet = new HashSet<>(); + addAnnotation(classSet); + + Set nameSet = new HashSet<>(); + for (Class clazz : classSet) { + nameSet.add(clazz.getCanonicalName()); + } + return nameSet; + } + + protected abstract void addAnnotation(Set> classSet); +} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/exception/MethodNotSupported.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Constant.java similarity index 60% rename from andserver/src/main/java/com/yanzhenjie/andserver/exception/MethodNotSupported.java rename to processor/src/main/java/com/yanzhenjie/andserver/processor/util/Constant.java index 4643941..dfe2112 100644 --- a/andserver/src/main/java/com/yanzhenjie/andserver/exception/MethodNotSupported.java +++ b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Constant.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Yan Zhenjie. + * Copyright 2018 Yan Zhenjie * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.yanzhenjie.andserver.exception; - -import com.yanzhenjie.andserver.RequestMethod; +package com.yanzhenjie.andserver.processor.util; /** - * Created by YanZhenjie on 2017/12/19. + * Created by YanZhenjie on 2018/2/6. */ -public class MethodNotSupported extends BaseException { +public final class Constant { - public MethodNotSupported(RequestMethod method) { - super(405, String.format("The %1$s method is not supported.", method.getValue())); - } + public static final String DOC_EDIT_WARN = + "This file was generated by AndServer automatically and you should NOT edit it."; + public static final String PACKAGE_NAME = "com.yanzhenjie.andserver"; } \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Logger.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Logger.java new file mode 100644 index 0000000..53922e6 --- /dev/null +++ b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Logger.java @@ -0,0 +1,69 @@ +/* + * Copyright © Yan Zhenjie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.yanzhenjie.andserver.processor.util; + +import org.apache.commons.lang3.StringUtils; + +import javax.annotation.processing.Messager; +import javax.tools.Diagnostic; + +/** + * Created by YanZhenjie on 2018/2/5. + */ +public class Logger { + + private Messager mMessager; + + public Logger(Messager messager) { + mMessager = messager; + } + + public void i(CharSequence info) { + if (StringUtils.isNotEmpty(info)) { + mMessager.printMessage(Diagnostic.Kind.NOTE, info); + } + } + + public void e(CharSequence error) { + if (StringUtils.isNotEmpty(error)) { + mMessager.printMessage(Diagnostic.Kind.ERROR, "An exception is encountered, " + error); + } + } + + public void e(Throwable error) { + if (null != error) { + mMessager.printMessage(Diagnostic.Kind.ERROR, + "An exception is encountered, " + error.getMessage() + "\n" + + formatStackTrace(error.getStackTrace())); + } + } + + public void w(CharSequence warning) { + if (StringUtils.isNotEmpty(warning)) { + mMessager.printMessage(Diagnostic.Kind.WARNING, warning); + } + } + + private String formatStackTrace(StackTraceElement[] stackTrace) { + StringBuilder sb = new StringBuilder(); + for (StackTraceElement element : stackTrace) { + sb.append(" at ").append(element.toString()); + sb.append("\n"); + } + return sb.toString(); + } + +} \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 2072895..ff1f61c 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,4 +1,5 @@ -apply plugin: rootProject.ext.plugins.application +apply plugin: rootProject.ext.plugins.android +apply plugin: rootProject.ext.plugins.andserver android { compileSdkVersion rootProject.ext.android.compileSdkVersion @@ -10,17 +11,29 @@ android { targetSdkVersion rootProject.ext.android.sampleTargetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionName - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_7 - targetCompatibility JavaVersion.VERSION_1_7 - } } } dependencies { - implementation rootProject.ext.dependencies.andserver + // implementation rootProject.ext.dependencies.andserverApi + // annotationProcessor rootProject.ext.dependencies.andserverProcessor + implementation project(':api') + annotationProcessor project(':processor') + implementation rootProject.ext.dependencies.design implementation rootProject.ext.dependencies.appCompat implementation rootProject.ext.dependencies.loading + implementation rootProject.ext.dependencies.fastJson } + +buildscript { + repositories { + maven { + url uri('../maven-repo') + } + } + + dependencies { + classpath 'com.yanzhenjie.andserver:gradle-plugin:2.0.0-alpha' + } +} \ No newline at end of file diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 60220fe..158dedd 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -15,34 +15,34 @@ limitations under the License. --> + xmlns:android="http://schemas.android.com/apk/res/android" + package="com.yanzhenjie.andserver.sample"> - - - + + + + android:name=".App" + android:allowBackup="false" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:supportsRtl="false" + android:theme="@style/AppTheme"> + android:name=".MainActivity" + android:label="@string/app_name" + android:theme="@style/AppTheme"> - + - + + android:name=".CoreService" + android:exported="false" /> \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/CoreService.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/CoreService.java index 519f5c0..b1bce7f 100644 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/CoreService.java +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/CoreService.java @@ -20,66 +20,13 @@ import android.os.IBinder; import android.support.annotation.Nullable; -import com.yanzhenjie.andserver.AndServer; -import com.yanzhenjie.andserver.Server; -import com.yanzhenjie.andserver.filter.HttpCacheFilter; -import com.yanzhenjie.andserver.sample.handler.FileHandler; -import com.yanzhenjie.andserver.sample.handler.ImageHandler; -import com.yanzhenjie.andserver.sample.handler.LoginHandler; -import com.yanzhenjie.andserver.sample.handler.UploadHandler; -import com.yanzhenjie.andserver.sample.util.NetUtils; -import com.yanzhenjie.andserver.website.AssetsWebsite; - -import java.util.concurrent.TimeUnit; - /** - *

Server service.

- * Created by Yan Zhenjie on 2017/3/16. + * Server service. Created by Yan Zhenjie on 2017/3/16. */ public class CoreService extends Service { - /** - * AndServer. - */ - private Server mServer; - @Override - public void onCreate() { - // More usage documentation: http://yanzhenjie.github.io/AndServer - mServer = AndServer.serverBuilder() - .inetAddress(NetUtils.getLocalIPAddress()) // Bind IP address. - .port(8080) - .timeout(10, TimeUnit.SECONDS) - .website(new AssetsWebsite(getAssets(), "web")) - .registerHandler("/download", new FileHandler()) - .registerHandler("/login", new LoginHandler()) - .registerHandler("/upload", new UploadHandler()) - .registerHandler("/image", new ImageHandler()) - .filter(new HttpCacheFilter()) - .listener(mListener) - .build(); - } - - /** - * Server listener. - */ - private Server.ServerListener mListener = new Server.ServerListener() { - @Override - public void onStarted() { - String hostAddress = mServer.getInetAddress().getHostAddress(); - ServerManager.serverStart(CoreService.this, hostAddress); - } - - @Override - public void onStopped() { - ServerManager.serverStop(CoreService.this); - } - - @Override - public void onError(Exception e) { - ServerManager.serverError(CoreService.this, e.getMessage()); - } - }; + public void onCreate() {} @Override public int onStartCommand(Intent intent, int flags, int startId) { @@ -90,35 +37,22 @@ public int onStartCommand(Intent intent, int flags, int startId) { @Override public void onDestroy() { super.onDestroy(); - stopServer(); // Stop server. + stopServer(); } /** * Start server. */ - private void startServer() { - if (mServer != null) { - if (mServer.isRunning()) { - String hostAddress = mServer.getInetAddress().getHostAddress(); - ServerManager.serverStart(CoreService.this, hostAddress); - } else { - mServer.startup(); - } - } - } + private void startServer() {} /** * Stop server. */ - private void stopServer() { - if (mServer != null && mServer.isRunning()) { - mServer.shutdown(); - } - } + private void stopServer() {} @Nullable @Override public IBinder onBind(Intent intent) { return null; } -} +} \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/MainActivity.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/MainActivity.java index 71b53bb..79d3fa0 100644 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/MainActivity.java +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/MainActivity.java @@ -49,13 +49,13 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - mBtnStart = (Button) findViewById(R.id.btn_start); - mBtnStop = (Button) findViewById(R.id.btn_stop); - mBtnBrowser = (Button) findViewById(R.id.btn_browse); - mTvMessage = (TextView) findViewById(R.id.tv_message); + mBtnStart = findViewById(R.id.btn_start); + mBtnStop = findViewById(R.id.btn_stop); + mBtnBrowser = findViewById(R.id.btn_browse); + mTvMessage = findViewById(R.id.tv_message); mBtnStart.setOnClickListener(this); mBtnStop.setOnClickListener(this); @@ -150,15 +150,11 @@ public void serverStop() { } private void showDialog() { - if (mDialog == null) - mDialog = new LoadingDialog(this); - if (!mDialog.isShowing()) - mDialog.show(); + if (mDialog == null) mDialog = new LoadingDialog(this); + if (!mDialog.isShowing()) mDialog.show(); } private void closeDialog() { - if (mDialog != null && mDialog.isShowing()) - mDialog.dismiss(); + if (mDialog != null && mDialog.isShowing()) mDialog.dismiss(); } - -} +} \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/ServerManager.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/ServerManager.java index 385456f..4afab3e 100644 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/ServerManager.java +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/ServerManager.java @@ -39,7 +39,7 @@ public class ServerManager extends BroadcastReceiver { * * @param context context. */ - public static void serverStart(Context context, String hostAddress) { + public static void onServerStart(Context context, String hostAddress) { sendBroadcast(context, CMD_VALUE_START, hostAddress); } @@ -48,7 +48,7 @@ public static void serverStart(Context context, String hostAddress) { * * @param context context. */ - public static void serverError(Context context, String error) { + public static void onServerError(Context context, String error) { sendBroadcast(context, CMD_VALUE_ERROR, error); } @@ -57,7 +57,7 @@ public static void serverError(Context context, String error) { * * @param context context. */ - public static void serverStop(Context context) { + public static void onServerStop(Context context) { sendBroadcast(context, CMD_VALUE_STOP); } @@ -88,6 +88,13 @@ public void register() { mActivity.registerReceiver(this, filter); } + /** + * UnRegister broadcast. + */ + public void unRegister() { + mActivity.unregisterReceiver(this); + } + public void startService() { mActivity.startService(mService); } @@ -96,13 +103,6 @@ public void stopService() { mActivity.stopService(mService); } - /** - * UnRegister broadcast. - */ - public void unRegister() { - mActivity.unregisterReceiver(this); - } - @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); @@ -126,5 +126,4 @@ public void onReceive(Context context, Intent intent) { } } } - -} +} \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/entity/ReturnData.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/entity/ReturnData.java new file mode 100644 index 0000000..8414c0d --- /dev/null +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/entity/ReturnData.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Yan Zhenjie. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.yanzhenjie.andserver.sample.entity; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * Created by YanZhenjie on 2018/6/9. + */ +public class ReturnData { + + @JSONField(name = "isSucceed") + private boolean isSucceed; + + @JSONField(name = "errorCode") + private int errorCode; + + @JSONField(name = "message") + private String message; + + @JSONField(name = "data") + private Object data; + + public ReturnData() { + } + + public boolean isSucceed() { + return isSucceed; + } + + public void setSucceed(boolean succeed) { + isSucceed = succeed; + } + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } +} \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/entity/UserInfo.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/entity/UserInfo.java new file mode 100644 index 0000000..cf926bd --- /dev/null +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/entity/UserInfo.java @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Yan Zhenjie. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.yanzhenjie.andserver.sample.entity; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * Created by YanZhenjie on 2018/6/9. + */ +public class UserInfo { + + @JSONField(name = "userId") + private String mUserId; + @JSONField(name = "userName") + private String mUserName; + + public UserInfo() { + } + + public String getUserId() { + return mUserId; + } + + public void setUserId(String userId) { + mUserId = userId; + } + + public String getUserName() { + return mUserName; + } + + public void setUserName(String userName) { + this.mUserName = userName; + } +} \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/FileHandler.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/FileHandler.java deleted file mode 100644 index 16ee8ef..0000000 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/FileHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.sample.handler; - -import com.yanzhenjie.andserver.RequestHandler; -import com.yanzhenjie.andserver.RequestMethod; -import com.yanzhenjie.andserver.annotation.RequestMapping; -import com.yanzhenjie.andserver.sample.App; - -import org.apache.commons.io.IOUtils; -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.FileEntity; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; - -import static com.yanzhenjie.andserver.util.FileUtils.getMimeType; - -/** - *

Returns a file.

- * Created by Yan Zhenjie on 2016/7/1. - */ -public class FileHandler implements RequestHandler { - - @RequestMapping(method = {RequestMethod.GET}) - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - File file = File.createTempFile("AndServer", ".txt", App.get().getCacheDir()); - OutputStream outputStream = new FileOutputStream(file); - IOUtils.write("LAN server of Android platform.", outputStream, Charset.defaultCharset()); - - HttpEntity httpEntity = new FileEntity(file, ContentType.create(getMimeType(file.getAbsolutePath()), Charset.defaultCharset())); - response.setHeader("Content-Disposition", "attachment;filename=AndServer.txt"); - response.setStatusCode(200); - response.setEntity(httpEntity); - } -} diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/ImageHandler.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/ImageHandler.java deleted file mode 100644 index 621d1ba..0000000 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/ImageHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright © 2017 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.sample.handler; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Environment; - -import com.yanzhenjie.andserver.SimpleRequestHandler; -import com.yanzhenjie.andserver.view.View; -import com.yanzhenjie.andserver.sample.App; -import com.yanzhenjie.andserver.sample.R; - -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.entity.ContentType; -import org.apache.httpcore.entity.FileEntity; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; - -import static com.yanzhenjie.andserver.util.FileUtils.getMimeType; - -/** - * Created by YanZhenjie on 2017/12/20. - */ -public class ImageHandler extends SimpleRequestHandler { - - private File mFile = new File(Environment.getExternalStorageDirectory(), "xxx.jpg"); - - @Override - protected View handle(HttpRequest request) throws HttpException, IOException { - writeToSdCard(); - - HttpEntity httpEntity = new FileEntity(mFile, ContentType.create(getMimeType(mFile.getAbsolutePath()), Charset.defaultCharset())); - return new View(200, httpEntity); - } - - private void writeToSdCard() throws IOException { - if (!mFile.exists()) { - synchronized (ImageHandler.class) { - if (!mFile.exists()) { - boolean b = mFile.createNewFile(); - if (!b) { - throw new IOException("What broken cell phone."); - } - - Bitmap bitmap = BitmapFactory.decodeResource(App.get().getResources(), R.drawable.sample_image); - OutputStream outputStream = null; - try { - outputStream = new FileOutputStream(mFile); - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } finally { - if (outputStream != null) { - outputStream.flush(); - outputStream.close(); - } - } - } - } - } - } - -} \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/LoginHandler.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/LoginHandler.java deleted file mode 100644 index db0cdcb..0000000 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/LoginHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.sample.handler; - -import com.yanzhenjie.andserver.RequestHandler; -import com.yanzhenjie.andserver.RequestMethod; -import com.yanzhenjie.andserver.annotation.RequestMapping; -import com.yanzhenjie.andserver.util.HttpRequestParser; - -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.entity.StringEntity; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.IOException; -import java.net.URLDecoder; -import java.util.Map; - -/** - *

Login Handler.

- * Created by Yan Zhenjie on 2016/6/13. - */ -public class LoginHandler implements RequestHandler { - - @RequestMapping(method = {RequestMethod.POST}) - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - Map params = HttpRequestParser.parseParams(request); - - if (!params.containsKey("username") || !params.containsKey("password")) { - StringEntity stringEntity = new StringEntity("Please enter your account number and password.", "utf-8"); - - response.setStatusCode(400); - response.setEntity(stringEntity); - return; - } - - String userName = URLDecoder.decode(params.get("username"), "utf-8"); - String password = URLDecoder.decode(params.get("password"), "utf-8"); - - if ("123".equals(userName) && "123".equals(password)) { - StringEntity stringEntity = new StringEntity("Login Succeed", "utf-8"); - - response.setStatusCode(200); - response.setEntity(stringEntity); - } else { - StringEntity stringEntity = new StringEntity("Login Failed", "utf-8"); - - response.setStatusCode(400); - response.setEntity(stringEntity); - } - } -} diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/UploadHandler.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/UploadHandler.java deleted file mode 100644 index 28540c3..0000000 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/handler/UploadHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright © 2016 Yan Zhenjie. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.yanzhenjie.andserver.sample.handler; - -import android.os.Environment; - -import com.yanzhenjie.andserver.RequestHandler; -import com.yanzhenjie.andserver.RequestMethod; -import com.yanzhenjie.andserver.annotation.RequestMapping; -import com.yanzhenjie.andserver.upload.HttpFileUpload; -import com.yanzhenjie.andserver.upload.HttpUploadContext; -import com.yanzhenjie.andserver.util.HttpRequestParser; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.httpcore.HttpEntityEnclosingRequest; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpRequest; -import org.apache.httpcore.HttpResponse; -import org.apache.httpcore.entity.StringEntity; -import org.apache.httpcore.protocol.HttpContext; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** - *

Upload file handler.

- * Created by Yan Zhenjie on 2016/6/13. - */ -public class UploadHandler implements RequestHandler { - - @RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT}) - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - if (!HttpRequestParser.isMultipartContentRequest(request)) { // Is POST and upload. - response(403, "You must upload file.", response); - } else { - final File saveDirectory = Environment.getExternalStorageDirectory(); - - if (saveDirectory.isDirectory()) { - try { - processFileUpload(request, saveDirectory); - response(200, "Ok.", response); - } catch (Exception e) { - response(500, "Save the file when the error occurs.", response); - } - } else { - response(500, "The server can not save the file.", response); - } - } - } - - private void response(int responseCode, String message, HttpResponse response) throws IOException { - response.setStatusCode(responseCode); - response.setEntity(new StringEntity(message, "utf-8")); - } - - /** - * Parse file and save. - * - * @param request request. - * @param saveDirectory save directory. - * @throws Exception may be. - */ - private void processFileUpload(HttpRequest request, File saveDirectory) throws Exception { - FileItemFactory factory = new DiskFileItemFactory(1024 * 1024, saveDirectory); - HttpFileUpload fileUpload = new HttpFileUpload(factory); - - // Set upload process listener. - // fileUpload.setProgressListener(new ProgressListener(){...}); - - List fileItems = fileUpload.parseRequest(new HttpUploadContext((HttpEntityEnclosingRequest) request)); - - for (FileItem fileItem : fileItems) { - if (!fileItem.isFormField()) { // File param. - // Attribute. - // fileItem.getContentType(); - // fileItem.getFieldName(); - // fileItem.getName(); - // fileItem.getSize(); - // fileItem.getString(); - - File uploadedFile = new File(saveDirectory, fileItem.getName()); - // 把流写到文件上。 - fileItem.write(uploadedFile); - } else { // General param. - String key = fileItem.getName(); - String value = fileItem.getString(); - } - } - } -} diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/util/AppUtils.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/util/AppUtils.java new file mode 100644 index 0000000..35bd5a6 --- /dev/null +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/util/AppUtils.java @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Yan Zhenjie. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.yanzhenjie.andserver.sample.util; + +import com.alibaba.fastjson.JSON; +import com.yanzhenjie.andserver.sample.entity.ReturnData; + +/** + * Created by YanZhenjie on 2018/6/9. + */ +public class AppUtils { + + /** + * Business is successful. + * + * @param data return data. + * + * @return json. + */ + public static String successfulJsonData(Object data) { + ReturnData returnData = new ReturnData(); + returnData.setSucceed(true); + returnData.setData(data); + return JSON.toJSONString(returnData); + } + + /** + * Business is failed. + * + * @param errorCode error code. + * @param message message. + * + * @return json. + */ + public static String failedJsonData(int errorCode, String message) { + ReturnData returnData = new ReturnData(); + returnData.setSucceed(false); + returnData.setErrorCode(errorCode); + returnData.setMessage(message); + return JSON.toJSONString(returnData); + } + +} \ No newline at end of file diff --git a/andserver/src/main/java/com/yanzhenjie/andserver/view/RedirectView.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/util/Constants.java similarity index 62% rename from andserver/src/main/java/com/yanzhenjie/andserver/view/RedirectView.java rename to sample/src/main/java/com/yanzhenjie/andserver/sample/util/Constants.java index 3274582..2b93404 100644 --- a/andserver/src/main/java/com/yanzhenjie/andserver/view/RedirectView.java +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/util/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Yan Zhenjie. + * Copyright 2018 Yan Zhenjie. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,17 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.yanzhenjie.andserver.view; +package com.yanzhenjie.andserver.sample.util; /** - * Created by YanZhenjie on 2017/12/22. + * Created by YanZhenjie on 2018/6/9. */ -public class RedirectView extends View { +public interface Constants { - private static final String LOCATION = "Location"; + /** + * Json content type. + */ + String CONTENT_JSON = "application/json;charset=utf-8"; + + /** + * Html content type. + */ + String CONTENT_HTML = "text/html;charset=utf-8"; - public RedirectView(String path) { - super(302); - setHeader(LOCATION, path); - } } \ No newline at end of file diff --git a/sample/src/main/java/com/yanzhenjie/andserver/sample/util/NetUtils.java b/sample/src/main/java/com/yanzhenjie/andserver/sample/util/NetUtils.java index abf554c..2d074eb 100644 --- a/sample/src/main/java/com/yanzhenjie/andserver/sample/util/NetUtils.java +++ b/sample/src/main/java/com/yanzhenjie/andserver/sample/util/NetUtils.java @@ -29,14 +29,15 @@ public class NetUtils { /** * Ipv4 address check. */ - private static final Pattern IPV4_PATTERN = Pattern.compile("^(" + - "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + - "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); + private static final Pattern IPV4_PATTERN = Pattern.compile( + "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); /** * Check if valid IPV4 address. * * @param input the address string to check for validity. + * * @return True if the input parameter is a valid IPv4 address. */ public static boolean isIPv4Address(String input) { @@ -57,16 +58,14 @@ public static InetAddress getLocalIPAddress() { while (enumeration.hasMoreElements()) { NetworkInterface nif = enumeration.nextElement(); Enumeration inetAddresses = nif.getInetAddresses(); - if (inetAddresses != null) - while (inetAddresses.hasMoreElements()) { - InetAddress inetAddress = inetAddresses.nextElement(); - if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) { - return inetAddress; - } + if (inetAddresses != null) while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) { + return inetAddress; } + } } } return null; } - -} \ No newline at end of file +} diff --git a/sample/src/main/res/drawable-xxhdpi/sample_image.jpg b/sample/src/main/res/drawable-xxhdpi/sample_image.jpg deleted file mode 100644 index 4f5c788..0000000 Binary files a/sample/src/main/res/drawable-xxhdpi/sample_image.jpg and /dev/null differ diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index c84d729..b169983 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -15,60 +15,60 @@ limitations under the License. --> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?actionBarSize" + android:background="?attr/colorPrimary" + app:layout_scrollFlags="scroll|enterAlways|snap" + app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> + android:id="@+id/content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_behavior="@string/appbar_scrolling_view_behavior">